package scalaz
package concurrent
import Scalaz._
import java.util.concurrent.{ExecutorService, ThreadFactory, Executors}
trait Strategy {
def apply[A](a: => A): () => A
}
abstract class StrategyLow {
implicit val Sequential: Strategy = new Strategy {
def apply[A](a: => A) = {
val v = a
() => v
}
}
import java.util.concurrent.ExecutorService
implicit def Executor(implicit s: ExecutorService) = new Strategy {
import java.util.concurrent.Callable
def apply[A](a: => A) = {
val fut = s.submit(new Callable[A] {
def call = a
})
() => fut.get
}
}
implicit val Id: Strategy = new Strategy {
def apply[A](a: => A) = () => a
}
implicit val Naive: Strategy = new Strategy {
import scala.concurrent.ops.future
def apply[A](a: => A) = future {a}
}
implicit val SwingWorker: Strategy = new Strategy {
import javax.swing.SwingWorker
def apply[A](a: => A) = {
val worker = new SwingWorker[A, Unit] {
def doInBackground = a
}
worker.execute
() => worker.get
}
}
implicit val SwingInvokeLater: Strategy = new Strategy {
import javax.swing.SwingUtilities
import SwingUtilities.invokeLater
import java.util.concurrent.{Callable, FutureTask}
def apply[A](a: => A) = {
val task = new FutureTask[A](new Callable[A] {
def call = a
})
invokeLater(task)
() => task.get
}
}
}
object Strategy extends StrategyLow {
lazy val DefaultExecutorService: ExecutorService = {
import Executors._
newFixedThreadPool(Runtime.getRuntime.availableProcessors, new ThreadFactory {
def newThread(r: Runnable) = {
val t = defaultThreadFactory.newThread(r)
t.setDaemon(true)
t
}
})
}
implicit lazy val DefaultStrategy: Strategy = Executor(DefaultExecutorService)
}