Hi Bartłomiej,

have you seen this article:
http://techblog.net-a-porter.com/2013/12/ask-tell-and-per-request-actors/

It deals with the "timeout hell" that you have described with an
introduction of per-request-actor. This would solve some of the
disadvantages that you have outlined in your solution. Mainly you will not
need to pass around context, because that can be saved in a
per-request-actor.


On Mon, Jul 28, 2014 at 12:49 AM, Bartłomiej Szczepanik <mequ...@gmail.com>
wrote:

> 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 akka-user+unsubscr...@googlegroups.com.
> To post to this group, send email to akka-user@googlegroups.com.
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Martynas Mickevičius
Typesafe <http://typesafe.com/> – Reactive
<http://www.reactivemanifesto.org/> Apps on the JVM

-- 
>>>>>>>>>>      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 akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
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