Infinite asynchronous loop in the Thespian actors

31 views
Skip to first unread message

Andrei Krivoshei

unread,
Oct 27, 2020, 4:25:14 AM10/27/20
to thespian.py

I want to do infinite loop (for some continuous process) inside an Thespian actor.

I tried to start the loop in the receiveMessage_Run() method (see code below), but I cannot to end the loop. The actor is blocked to receive new messages.

Can somebody help me with this task? How can I run infinite loop (it seems, asynchronous) and save possibility to react to other messages and possibility to stop the loop and actor?

My testing code:

```

from thespian.actors import ActorExitRequest, ActorSystem, Actor, ActorTypeDispatcher
import time
import random

# Message 'Run'
class Run():
    pass

# Message 'Stop'
class Stop():
    pass


class Actor(ActorTypeDispatcher):
    def __init__(self):
        self.stop = False

    # It seems, it must be asynchronous
    def loop(self):
        while not self.stop:
            time.sleep(1)
            print(random.random())

    def receiveMsg_Run(self, data, sender):
        self.loop()
        self.send(sender, 'Finished the loop.')

    def receiveMsg_Stop(self, msg, sender):
        self.stop = True
        self.send(self.myAddress, ActorExitRequest)
        print('*' * 1000)

    def receiveMsg_ActorExitRequest(self, msg, sender):
        self.stop = True
        time.sleep(1)


if __name__ == '__main__':
    asys = ActorSystem('multiprocQueueBase')

    loop = asys.createActor(Actor)

    resp = asys.ask(loop, Run())
    print(resp)
    time.sleep(4)
    asys.tell(loop, Stop())

    ActorSystem().shutdown()

```

Kevin Quick

unread,
Oct 28, 2020, 11:45:59 AM10/28/20
to Andrei Krivoshei, thespian.py
Thespian essentially runs each actor in an infinite loop until the `ActorExitRequest()` is received or the Actor System is shutdown.  However, each actor is just a single thread of execution, so as you discovered, if the actor's `receiveMessage()` method never exits, Thespian cannot run to process additional incoming requests (or to complete the asynchronous outbound sends either).  The advantage to the single thread of execution is that the context of the Actor is simple and straightforward: it does not need mutex protections or to consider data races, deadlocks, or value corruption.

```
class Actor(ActorTypeDispatcher):
    def __init__(self):
        self.stop = False
        self.requestor = None

    def run_single(self):

            print(random.random())

    def receiveMsg_Run(self, data, sender):
        self.requestor = sender
        self.run_single()
        self.wakeupAfter(datetime.timedelta(seconds=1))

    def receiveMsg_WakeupMessage(self, msg, sender):
        if self.stop:
            self.send(self.requestor, 'Finished the loop.')
        else:
            self.run_single()
            self.wakeupAfter(datetime.timedelta(seconds=1))


    def receiveMsg_Stop(self, msg, sender):
        self.stop = True
        # Note that this line will probably remove the need for self.stop entirely: receiveMsg_WakeupMessage will not get a chance to run when self.stop is True

        self.send(self.myAddress, ActorExitRequest)
        print('*' * 1000)

    def receiveMsg_ActorExitRequest(self, msg, sender):
        self.stop = True
        time.sleep(1)
```


If your `run_once` really does block for long periods of time and cannot be periodically scheduled via the above methodology, you can consider using a separate thread; this is an unfortunate mixing of different processing and scheduling concepts (Actor Model v.s. threads), but sometimes necessary when the Actor must run code written in that alternative model.

-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 view this discussion on the web visit https://groups.google.com/d/msgid/thespianpy/d93e1c54-d879-47d2-9ad1-41925ec1f318n%40googlegroups.com.


--
-KQ

Andrei Krivoshei

unread,
Oct 29, 2020, 5:40:45 AM10/29/20
to thespian.py
Thank you Kevin!
I will try this.

среда, 28 октября 2020 г. в 17:45:59 UTC+2, kq1q...@gmail.com:
Reply all
Reply to author
Forward
0 new messages