Dear Hakkers,


In my current project I have experienced that ask pattern is a kind of 
awkward solution. I really like it for its elegance and readability but 
besides not very efficient implementation (spawning actor per each request) 
it introduces a phenomenon which I call `timeout hell`. It is really hard 
to introduce a consistent timeout for a user request when you use several 
ask requests in your pipeline.

 

I have also seen that many people discourage from using that pattern and 
encourage to replace it with actor per request pattern. Personally I don't 
see any difference with the ask implementation with a new actor spawned 
each time. It would be great if someone convince me why it is different and 
better.

 

I'm guessing the cause of this problem is not about the usage of the ask 
pattern itself but due to crappy, not reactive design of the system. I 
agree that the best is not to wait or block for anything. But currently I 
cannot use fully reactive pipeline with pushing events to GUI and so on. 
However, I'd like to block user only on HTTP request and be fully reactive 
in the rest of the pipeline. But still there is a problem. Let me describe 
it on a simple example.

 

Let's say the backend can handle ChangeColorOfItem command. In the 
old-style application we probably would write something like (pseudocode):

on(ChangeColorOfItem cmd) {

     item = itemRepository.getById(cmd.itemId)

     item.changeColorTo(cmd.getColor)

     itemRepository.save(item)

}

 

It's easy for me to translate it to akka using ask pattern. But as I said, 
I would like to avoid it. I came up with several possible solutions:

 

Fire and forget solution

 

The idea is to move all but first steps to recipients of respective 
messages. For example the repository command retrieves the requested item 
and sends message to the retrieved item basing on the passed context. I 
don't like the idea because of scattering of business logic and hindering 
the reusability of components. 

 

Create an actor and split the business logic on multiple steps

 

Something more sophisticated. Here's some sample of code:

 

Receive = {

  match msg @ ChangeColorOfItem(itemId, color) => {

     itemRepository ! GetById(itemId, Context(sender, msg))

  }

  match RepositoryResponse(item: ActorRef, context) => {

     item ! ChangeColorTo(context.msg.color, context)

  }

  match event @ ColorChanged(itemId, color, context) => {

     itemRepository ! SaveEvent(event)

  }

  match ItemSaved(context) => {

      context.sender ! ColorSuccessfullyChanged(context.msg.id, 
context.msg.color)

  }

}

 

Advantages (comparing to ask pattern):

   - The entire use case logic is still in one place (one actor) 
   - Timeouts handling moved on a higher level (e.g. REST interface level) 
   what enables easy timeout management per entire use case 
   - No problem with resource leaks when there is a timeout or heavy load 
   (no stale future objects in memory, only lightweight message) 

 

Disadvantages:

   - Need to pass context explicitly all the time 
   - Logic is harder to read due to steps introduction (a little similar to 
   use of callbacks) 
   - Exclusive processing of steps that in fact don't need that 

 

Different ideas

 

I was thinking about leveraging Futures for similar idea as above. I wanted 
to pass some kind of callback with the message and it's context to the next 
recipient. That allows me to keep code in one place (unfortunately in 
callbacks but still). However I think it is impossible to send a lambda in 
a message to the actor. Is that any workaround? If so, would you find this 
approach useful?

 

Generally I would prefer to use a solution that keeps the idea of 
"application/use case service" which orchestrates the fine-grained classes 
and encapsulates use cases in the code in exactly one place. If you think 
it's impossible in reactive approach, please explain that and give some 
alternatives. I'd be very grateful for that.


Best,

Bartłomiej


 

-- 
>>>>>>>>>>      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