Last active
March 3, 2016 06:41
-
-
Save m2ym/9b051ca3f0fd4adc8f56 to your computer and use it in GitHub Desktop.
Scala.js + Scalaz Concurrent Task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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