Using Ask

57 views
Skip to first unread message

BR

unread,
Apr 29, 2019, 7:40:38 PM4/29/19
to thespian.py
I've avoided using ask() because of the various warnings and gotchas from the documentation, but I realized that I may be interpreting things incorrectly. From the documentation:

The "response message" is any message received by the local endpoint. The local endpoint looks like a normal Actor with an ActorAddress to the rest of the system. Any Actor sending a message to this address will cause the ask() operation to complete with that message.

When an ask() is sent, does it create a unique ActorAddress for this particular ask()? This would mean that to complete the ask(), an actor would need to send to a specific address, and this actually makes ask() quite useful. However, the other way of interpreting things is to assume that the ask() endpoint has a generic ActorAddress that is used for ALL ask() into an ActorSystem. This would mean that if you issued an ask(), but another place in the code issued another ask(), then the responses could potentially get mixed up.

I can try to clarify my interpretations a bit more if needed. Hopefully you could shed some light on this.

Kevin Quick

unread,
Apr 29, 2019, 8:49:49 PM4/29/19
to BR, thespian.py
The ask calls all share a single address. The private method will return a different address that will be distinct.

The ask, tell, and listen methods are only intended for code outside of the actor system to communicate with actors in the system. Actors themselves should use only self.send.

Kevin

--
You received this message because you are subscribed to the Google Groups "thespian.py" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thespianpy+...@googlegroups.com.
To post to this group, send email to thesp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/thespianpy/f96ed972-8805-41c5-86e9-4751b3b03c26%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

BR

unread,
Apr 29, 2019, 8:53:08 PM4/29/19
to thespian.py
Ah yes, I should have read my previous question and answers. My use case is to request something from an actor from the outside, so I think private() should do the trick.

Erdem Eser Ekinci

unread,
Feb 25, 2021, 4:56:41 AM2/25/21
to thespian.py
Hi Kevin, 

"The ask, tell, and listen methods are only intended for code outside of the actor system to communicate with actors in the system. Actors themselves should use only self.send." 


You know similar libraries do not have the same restriction.

Best.  


Kevin Quick

unread,
Feb 25, 2021, 12:55:38 PM2/25/21
to Erdem Eser Ekinci, thespian.py
Hi Erdem,

I'm not entirely sure of what concern you are addressing here.  It could be (a) the desire to use functions like `ask()` from within an Actor, (b) the desire to have the same API from within an Actor as from external code, or (c) something else.

With regards to (a):

Many actor system implementations mix in concepts like Futures and blocking that have their origins in synchronous programming environments or thread-based synchronization.  This allows code inside the actor to perform operations like "ask", which will block until a response is received (either immediately, or when the corresponding Future value is needed).

I chose not to implement this type of functionality for Thespian because I believe it is fundamentally at odds with the Actor paradigm: an actor should respond to a message, and when it has finished that message it should be prepared to handle the next message (instead of being unavailable because it is blocked internally).  This requires multi-part operations to be handled in a truly asynchronous manner, but from a systems level perspective provides better fidelity to the underlying paradigm and helps avoid system-responsible deadlocks in your Actor application.  It also leads to a perception of 1:1 send/receive functionality for messages, but an Actor is a 1:N outbound only concept: every received message may cause the Actor to `send()` N outbound messages (where N is 0 to some reasonably large number), and there is no expectation of any responses to those messages (from a system level; your Actor implementation's "business logic" is up to you to define). 

If you do wish your Actors to function in this type of blocking manner, you could provide that via a subclass layer between Thespian's `Actor` class and your target actor implementation.  This intermediate subclass would receive messages and queue them internally to a "pending" queue, and the final implementation subclass would retrieve messages from this queue when ready to process something new.  A "future" object would be handled by a separate "in-progress" queue in the intermediate subclass; while the "in-progress" queue was non-empty, no messages would be taken from the "pending" queue, and new incoming messages would be checked for satisfaction of a "future" on the "in-progress" queue before being placed on the "pending" queue.  This is not an approach I would recommend, but provides a general sketch of an approach you wanted a blocking-style functionality for your implementation.   The approach I would recommend is to attach any necessary resumption information to outbound messages that you expect to receive a response to; the receiving actor should maintain that information in the response such that the first actor can resume the operation using only the information in the response message (i.e. operation context is maintained in the exchanged messages, not within the actor's internal state).

With regards to (b):

External code operates in a conventional synchronous manner (possibly threaded) that does not allow it to be "interrupted" at any point when a message is available for it to process, thus the `ask()` and `listen()` functions provide endpoints where the synchronous external code can indicate a desire to receive a message.  The `tell()` endpoint is the most direct analogy to the Actor's `send()` function, but here I felt that a different name would be good to clarify that it was an extra-Actor v.s. intra-Actor usage.

If you'd like more detail on any of the above, or if you were referencing something else entirely (option (c) above), please let me know and I'd be happy to address it.

Regards,
  Kevin

--
You received this message because you are subscribed to the Google Groups "thespian.py" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thespianpy+...@googlegroups.com.


--
-KQ
Reply all
Reply to author
Forward
0 new messages