akka-js / akka.js

Akka, for Scala.js
http://akka-js.org
475 stars 39 forks source link

Stash not available under Scala 3 (with CrossVersion) #130

Open devlaam opened 2 years ago

devlaam commented 2 years ago

Akka.js continues to be very useful! However, when taking my project to Scala 3 (and making use of CrossVersion.for3Use2_13) a problem with the use of Stash arises. It seems not possible to define mailbox configurations in application.conf for that file is not being read, and making use of then ConfigFactory does not work for it relies on Scala 2 macro's (not supported in Scala 3). Making an alternative Stash class is also difficult for the underlying queues in the mailboxes are not accessible (needed to get the order right).

Is there a way to somehow manually load the required mailbox class? Or do you know some other workaround?

andreaTP commented 2 years ago

Hi @devlaam ! I have to say that I'm actually surprised that this project still works with Scala 3 🙂

There is a section on how to configure the mailbox in the main Readme: https://github.com/akka-js/akka.js/blob/040fac83d610cca094f51913743f2dbae2077332/README.md?plain=1#L91-L110 I'm not sure how the macro incompatibility works in Scala 3, but if you insert a local variable in the String to parse you invalidate the Macro and everything should be resolved at runtime, but this might require more investigation. Alternatively, you can try to use parseMap, or directly invoking the underlying implementation.

devlaam commented 2 years ago

Hello andreaTP, thanks a lot for the quick reply!!

I already tried the way you suggested, but failed. But, since you suggested it, I thought, let's try a little harder. This is a solution i found to be working. Define your actor system with:

object SystemDef
{ import com.typesafe.config.{Config => TSConfig}
  import org.akkajs.shocon.{Config => SHConfig}
  val actSysName   = "mySystem"
  val stashMailbox = "stash-custom-mailbox"
  val stashConfig  = s""" $stashMailbox { mailbox-type = "akka.dispatch.UnboundedDequeBasedMailbox" } """
  val actorSystem  = ActorSystem(actSysName,TSConfig(SHConfig(stashConfig))) }

and make use of it like this:

object Worker 
{ case class Config(...) 
  def create(config: Config): Props = Props(new Worker(config)).withMailbox(SystemDef.stashMailbox) }

class Worker(val config: Worker.Config) extends Actor with Stash
{ ... }

Again, a big thank you (and for your wonderful work in general). Happy stashing!

andreaTP commented 2 years ago

Thanks a lot for sharing your solution @devlaam ! And sorry if it turns out to be so ugly ...