Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actors that drive their own event processing (or maybe have idle processing) #44

Open
abingham opened this issue Aug 19, 2014 · 5 comments · May be fixed by #102
Open

Actors that drive their own event processing (or maybe have idle processing) #44

abingham opened this issue Aug 19, 2014 · 5 comments · May be fixed by #102

Comments

@abingham
Copy link

abingham commented Aug 19, 2014

As I currently understand Pykka actors, they are entirely event driven in the sense that they don't do anything unless they've received an event. What I'm looking for is a way to have an actor that "does things" all of the time, and which handles messages when it's ready.

The motivating example I've got is an actor which monitors a camera (say, a web cam), examining an image every second. When it detects a face in the image, it send a message to some other actor. The obvious (perhaps naive) approach to this is an actor that sits in a loop, taking pictures and, after each picture, explicitly letting events be processed. Something like this:

class CameraActor(pykka.Actor):
    . . .
   def process_events(self):
       if self.its_been_one_second():
           img = take_picture()
           if face_in_img(img): 
               self.target.tell({'face_rect': face_rect(img)})
       super().process_events()

Or something like that. Perhaps an "idle handler" is a better approach. The main point, though, is that I'd like the actor to be able to do processing even in the absence of any external stimulus, e.g. events.

I think I can simulate this currently by having the actor send messages to itself. This feels to me like a lot of ceremony for something that's conceptually simple.

I've looked briefly at Actor._actor_loop(), and this seems like the likely place to insert these kinds of changes.

In any case, hopefully you can understand what I'm looking for. Is something like this supported in Pykka already, or would it require changes? Maybe this is just a bad idea, but then I wonder how I should implement something like my CameraActor.

@jodal
Copy link
Owner

jodal commented Aug 23, 2014

I think my own pragmatic solution would be to have a plain daemon thread which polls for an image, checks for faces, sends event to an actor for further processing, and sleeps until it is time to poll again.

Having an actor message itself (through self.actor_ref) is a useful trick for splitting up tasks that take a long time to complete, so that e.g. stop messages can be processed in the middle of a large task. Nobody likes their program to spend a minute on shutting down.

In a program with an event loop, like GLib, Twisted, or asyncio, the sleep part could be replaced with asking the event loop to call the poller regularly.

I want to bring Pykka to asyncio in the not too distant future, but have yet to think about if Pykka should have any abstraction for scheduling functions to be executed in the future by the asyncio event loop, or if you'll just have to use asyncio directly yourself for such use cases.

Do you know how this is solved in any other actor systems, like Akka?

@abingham
Copy link
Author

I don't know about Akka. But in e.g. stackless, d, and go you have more explicit control over message processing, deciding when to pull messages from channels. D and go (but not stackless, for some reason) let you wait on messages with a timeout, so that makes it relatively easy to implement "sleep for a few seconds" without risking long shutdown times.

My sense is that a system with explicit message handling is more general than what pykka currently provides, and that pykka's current functionality could be implemented in terms of such a general system. But that's mostly just speculation right now; I haven't spent time trying to implement anything!

@drozzy
Copy link

drozzy commented Sep 18, 2014

Sending messages to yourself is exactly the right way of doing this.
In an Actor system actors cannot do anything out of their own will - they only respond to messages. This is what gives the guarantee that nothing will deadlock, or produce other concurrency issues (shared state etc..)
Here are two ways of handling sending messages to yourself:
http://doc.akka.io/docs/akka/2.3.6/scala/howto.html#scheduling-periodic-messages

The alternative is to manage the concurrency on your own, through thread scheduling or constant polling (which will tie-up 1 cpu 100% of the time anyways). Avoiding the former of these is the reason for me to pick actor-based system in the first place.

Also, nothing is stopping you from creating a plain "thread" with sleep functionality, or the class similar to the one in your example, which checks for new pictures, has a "reference" to an actor, and simply sends a message to an actor anytime new photo is available.

Finally, take a look at Futures vs Actors, and see if they may be relevant to you instead of actors:
http://doc.akka.io/docs/akka/2.3.6/scala/futures.html

@fjarri
Copy link

fjarri commented Nov 2, 2020

Sorry for raising an old question, but if I'm understanding correctly, this hasn't been resolved so far. I encountered the same problem, and the periodic messaging solution from the post above would indeed solve it - if this functionality was available in Pykka. Are there any plans to implement it?

@fjarri fjarri linked a pull request Nov 2, 2020 that will close this issue
@fjarri
Copy link

fjarri commented Nov 2, 2020

I made a draft PR for this feature, comments appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants