Skip to content

Instantly share code, notes, and snippets.

@m2ym
Last active March 3, 2016 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m2ym/9b051ca3f0fd4adc8f56 to your computer and use it in GitHub Desktop.
Save m2ym/9b051ca3f0fd4adc8f56 to your computer and use it in GitHub Desktop.
Scala.js + Scalaz Concurrent Task
import org.scalajs.dom
import dom.document
import scala.scalajs.js.JSApp
import scalaz.Nondeterminism
import scalaz.concurrent.Future
import scalaz.concurrent.Task
import scalaz.Free.Trampoline
import scalaz.\/._
import scala.collection.mutable.Queue
import scalaz._
object Main extends JSApp {
object Executor {
case class Waiter(wakeup: Unit => Unit)
var pending: Seq[Task[Unit]] = Seq()
val waiters: Queue[Waiter] = Queue()
def point[A](a: => A): Task[A] = Nondeterminism[Task].point(a)
def async(t: Task[Unit]): Unit =
pending = t +: pending
def schedule(): Unit = {
if (waiters.nonEmpty)
waiters.dequeue().wakeup()
}
def sleep(duration: Int): Task[Unit] = new Task(Future.Async { (cb: Throwable \/ Unit => Trampoline[Unit]) =>
dom.setTimeout(() => cb(\/-(())).run, duration)
schedule()
})
def `yield`(): Task[Unit] = new Task(Future.Async { (cb: Throwable \/ Unit => Trampoline[Unit]) =>
waiters.enqueue(Waiter(_ => cb(\/-(())).run))
schedule()
})
def choose[A](h: Task[A], t: Task[A]*): Task[A] = {
Nondeterminism[Task].chooseAny(h, t) flatMap { case (a, rest) =>
// TODO cancel
point(a)
}
}
def start(): Unit = {
val working = pending
pending = Seq()
Nondeterminism[Task].chooseAny(working) match {
case None =>
// TODO
()
case Some(t) =>
t.unsafePerformAsync {
case -\/(e) =>
// TODO
()
case \/-((_, rest)) =>
pending ++= rest
start()
}
}
}
}
def main(): Unit = {
import Executor._
def f(): Task[Unit] = sleep(2000) flatMap { _ => dom.console.log("Hello"); f() }
def g(): Task[Unit] = sleep(3000) flatMap { _ => dom.console.log("World"); g() }
async(f())
async(g())
start()
}
}
Hello
World
Hello
World
Hello
Hello
World
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment