Yang Bo,

thanks for experimenting with and sharing this: when macros started to 
materialize two years ago I had the same thought and proposed (internally) to 
investigate what I called messageflow at the time (inspired by our dataflow 
module which has been treated in the same fashion, going from CPS plugin to 
async/await macros). This model makes for a nice and direct way of formulating 
temporary intermediate states within actors, typically encountered while 
waiting for another actor to reply. Interestingly, the original work on the 
Actor model (in particular by Gul Agha) already contains this as a primitive of 
the actor language.

On the other hand I have learned a few more things over the past year that are 
related to this topic as well. Perhaps the most concise write-up is this issue 
on the Reactive Streams repository. What you are doing is that the actor is not 
technically blocked (in the sense of parking a thread), but it is still 
logically blocked, since it cannot handle any message other than the reply that 
is being awaited—everything else would violate the Actor model in that 
concurrent entry into the behavior is not allowed: handling a message must 
determine the behavior that applies to the next message, and this process is 
applied strictly in sequence. We discussed this topic also with Akara 
Sucharitakul and Justin du Coeur on this list a few months ago (search for the 
Aggregator Pattern), and what we concluded was that mixing a normal actor (with 
the current behavior as the message entry point) with an `await` scheme (that 
adds secondary message entry points) would lead to confusing behavior in that 
e.g. a Cancel message would not have the intended effect:

  def receive = {
    case DoWork =>
      val r = otherActor ? Query await 5.seconds // this uses become() under 
the hood
      sender() ! Reply(transform(r))
    case Cancel =>
      context.stop(self)
  }

Now what you are showing is a slight variation on this theme in that your actor 
does not actually have the normal `receive` entry point for processing. If I 
read it correctly, then your macro only applies to actors that model ephemeral 
workflows in a single-shot fashion, with full control on which message is 
expected next. That is a very interesting spin, and it might actually work! I 
would love to see how something like the following would pan out:

class OrderFlow(item: Item, client: Client, inventory: ActorRef, shipping: 
ActorRef, billing: ActorRef) extends Workflow {
  implicit val timeout = Timeout(300.millis)
  flow {
    // .await(duration) returns an Option[T]
    val reserved = inventory ? ReserveItem(item) await 500.millis getOrElse 
ReservationTimeout match {
      case ItemReserved(reserved) => reserved
      case other =>
        context.parent ! OrderFailed(other)
        flow.stop() // e.g. throw ActorKilledException
    }
    val shipped = shipping ? ShipItem(reserved, client) await 500.millis 
getOrElse ShippingTimeout
    val status = if (shipped.wasSuccessful) {
      val billed = billing ? InvoiceItem(reserved, client) await 500.millis 
getOrElse InvoiceTimeout
      if (!billed.wasSuccessful) {
        shipping ! RollbackShipItem(shipped)
        BillingFailed
      } else {
        OrderSuccess
      }
    } else {
        ShippingFailed
    }
    context.parent ! status
  }
}

This would be a specialized actor with a `final override def receive` that can 
only be used via the flow{} DSL. The core of this proposal is that an actor is 
either unrestricted (with receive/become) or a single workflow, but never a mix 
of the two.

Regards,

Roland

27 apr 2014 kl. 22:06 skrev 杨博 <[email protected]>:

> 
> 
> 在 2014年4月27日星期日UTC+8上午2时15分31秒,Justin du coeur写道:
> On Fri, Apr 25, 2014 at 4:00 PM, 杨博 <[email protected]> wrote:
> Does this project interest you or scare you?
> 
> Somewhere in-between, I'd say -- I'm intrigued but cautious.  The concept is 
> *quite* interesting, and for some state machines I can imagine it being 
> enormously useful.  That said, while it's obvious how it works for a single 
> entry point, I'm not clear on how it would work with one of my typical 
> Actors, which often respond quite differently to half a dozen different 
> messages.  If this is so deeply become-based, it *sounds* like it might have 
> problems when those are interleaved.
> I guess I won't resolve this problem at any time. Yes, I can resolve it by 
> dispatching different message to different Futures in one actor. But IMHO, 
> it's not the best design model with Akka. I suggest you forward different 
> messages to different actors, and use Future in those actors.
> 
>  
>  But the generated code is so voluminous, I can't quickly figure out if 
> that's true.  (The bulk of the generated code is a mild concern as well, 
> although not a dramatic one if the size of the generated code is roughly 
> linear with the original.)
> 
> How well does the Future mechanism play with more heterogeneous Actors, with 
> a bunch of different entry points?
> 
> -- 
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ: 
> >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> --- 
> You received this message because you are subscribed to the Google Groups 
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to