Open patriknw opened 6 years ago
I agree it would be better to implement this using ordinary actor features rather than introducing async effects: if we would implement this as a general feature, we would have to stash all messages while the async request is in flight. That is potentially a big cost that is not obvious when just looking at the code. When implementing this explicitly, the different possible behaviors become much more obvious.
It might make sense to cover this use case explicitly in the documentation, with a code example. This would achieve 'at-most-once' semantics when the actor system crashes between persisting and performing the async effect. A second example could extend the implementation with 'at-most-once' semantics by re-triggering the effect after recovery.
I agree that this could be implemented using ordinary actor features and it’s on the user to choose what to do. Stashing is not a requirement. For instance, you could change behaviour and reject new commands while awaiting some confirmation. It’s own the user to build that up.
On the topic of using projections, I think both cases are valid and we can summarise it as:
This also allows us to build Sagas or Process Managers using a PersistentBehavior. And I don’t think this is something that should be provided out-of-the-box because there is a myriad of possible implementations. Instead we have flexible building blocks and let the users choose and assemble they way they prefer.
I think it needs to be built in. The second a user needs to call something which returns a Future as a part of their command processing, they're currently going to do Await.
See also https://github.com/akka/akka/issues/17522 from 2015
ok, I'll think more about this. Somewhat related to https://github.com/akka/akka/pull/24809, which is also about stashing until a Future is completed.
I still think that when such Future is completed it should result in a new command (message) and not be based on nested callbacks (hell).
Support for async effects has popped up a few times. Recently in the discussion about auto confirmations https://github.com/akka/akka/issues/25482#issuecomment-422734323
Let's first put this in context by coming up with a somewhat realistic example. Here is one that I can imagine.
OrderPlaced
Future
OrderConfirmed
when call is completed successfullyDone
afterwards to the original requesterRetry mechanisms are left out for simplicity.
The way I would implement that is with ordinary actor facilities. When the
Future
is completed a new message is sent toself
, which will persist the confirmation event and then finally reply. Stashing can be used in the meanwhile if only one order at a time can be handled (probably not realistic for this example). TheActorRef
of the original requester can be carried along to theself
message without problems.This would also work with other interaction patterns than a
Future
, e.g. actor messages viatell
orActorContext.ask
.I don't see the need for a special async effect type.
I know, sending to the external order system might be better to do from an event processor (Akka Projections (read-side)), but let's say you don't want to complicate it by using an event processor.