Hello. I wolnder if monix 3.0.0-RC1 is compatiable with cats 1.4.0 and cats-effect 1.0.0?
I got two wierd exceptions:
java.lang.AbstractMethodError: Method monix/eval/instances/CatsConcurrentForTask$.bracketCase(Ljava/lang/Object;Lscala/Function1;Lscala/Function2;)Ljava/lang/Object; is abstract
at monix.eval.instances.CatsConcurrentForTask$.bracketCase(CatsAsyncForTask.scala)
at cats.effect.Bracket.bracket(Bracket.scala:64)
at cats.effect.concurrent.Semaphore$AbstractSemaphore.withPermit(Semaphore.scala:244)
and
java.lang.ClassCastException: monix.eval.Task$Eval cannot be cast to cats.effect.IO
at monix.eval.internal.TaskEffect$.$anonfun$cancelable$1(TaskEffect.scala:59)
at monix.eval.internal.TaskEffect$.$anonfun$cancelable$1$adapted(TaskEffect.scala:52)
at monix.eval.internal.TaskRunLoop$.executeAsyncTask(TaskRunLoop.scala:421)
at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:110)
at monix.eval.internal.TaskRunLoop$RestartCallback.onSuccess(TaskRunLoop.scala:537)
at monix.eval.internal.TaskRunLoop$.startFull(TaskRunLoop.scala:117)
at monix.eval.internal.TaskMemoize$Register.$anonfun$registerListener$1(TaskMemoize.scala:132)
at monix.eval.internal.TaskMemoize$Register.$anonfun$registerListener$1$adapted(TaskMemoize.scala:129)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Semaphore[Task, Unit]
usage in my code
IO
s are scheduled manually by the runloop (with round robin last time I checked, but that was a while ago)
join
) or interrupt it (cancel
)
TaskRunLoop
. It's not going to be easy to read though, due to all the speed improvements.
IO[Any]
, and a Stack[Any => IO[Any]]]
// Fiber does not need to be interrupted, but might need to yield:
if (opcount == maxopcount) {
// Cooperatively yield to other fibers currently suspended.
// FIXME: Replace with the new design.
opcount = 0
// Cannot capture `curIo` since it will be boxed into `ObjectRef`,
// which destroys performance, so we create a temp val here.
val tmpIo = curIo
rts.submit(evaluate(tmpIo))
curIo = null
Fiber
in scalaz is a concrete type that holds the runloop logic
I have some thoughts on improving the run loop, but I don't have time for experiments right now. I'm thinking of introducing the "visitor pattern" we now have in Iterant
too ... when you end up with an ADT with a lot of states, the JVM can do that pattern matching better than you via plain old method dispatches, however for tight flatMap loops pattern matching is faster (saw it in testing) so I have to juggle those modes somewhat ... to switch between method dispatches (visitor) and pattern matching in hot loops.
Not sure how well that will work out without experiments. Plain old method dispatches would be cool for adding more specialized states (ContextSwitch
is a recent example).