You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

77 lines
2.3 KiB

package outwatchapp.util.reactive
import io.circe.Decoder
import io.circe.Encoder
import io.circe.Printer
import io.circe.parser._
import io.circe.syntax._
import monix.execution.Ack
import monix.execution.Cancelable
import monix.execution.cancelables.SingleAssignCancelable
import monix.reactive.Observable
import monix.reactive.Observer
import monix.reactive.OverflowStrategy
import org.scalajs.dom.raw.MessageEvent
import org.scalajs.dom.webworkers.DedicatedWorkerGlobalScope
import scala.concurrent.Future
import outwatchapp.util.reactive.Exceptions.WrongTypeException
// @js.native
// @JSGlobalScope
// object WorkerGlobal extends DedicatedWorkerGlobalScope
// class DedicatedWorkerImpl[T: Encoder: Decoder](wg: DedicatedWorkerGlobalScope) {
// def run = Task.deferAction(implicit s =>
// for {
// _ <- Task.unit
// sub <- Task(ConcurrentSubject.publish[T])
// } yield ()
// )
// }
object DedicatedWorker {
def source[T: Decoder](wg: DedicatedWorkerGlobalScope) =
Observable.create[T](OverflowStrategy.DropOld(50)) { sub =>
val c = SingleAssignCancelable()
def onmessageFn(event: MessageEvent): Unit = {
event.data match {
case s: String =>
decode[T](s)
.map { res =>
if (sub.onNext(res) == Ack.Stop) c.cancel()
res
}
.left
.foreach(err =>
sub.onError(
new Exception(s"Failed to decode $s. Error was $err")
)
)
case other =>
sub.onError(WrongTypeException(s"Received wrong type: $other"))
}
}
wg.onmessage = onmessageFn _
c := Cancelable(() => wg.onmessage = _ => ())
}
def sink[T: Encoder](wg: DedicatedWorkerGlobalScope) =
new Observer[T] {
val printer = Printer.noSpaces
override def onNext(elem: T): Future[Ack] = {
// wg.onoffline
wg.postMessage(printer.print(elem.asJson))
Ack.Continue
}
override def onError(ex: Throwable): Unit = ex.printStackTrace()
override def onComplete(): Unit = println("Worker observer completed")
}
def apply[T: Encoder: Decoder](
wg: DedicatedWorkerGlobalScope
): DedicatedWorker[T] = MonixProSubject.from(sink(wg), source(wg))
}