kquick / Thespian

Python Actor concurrency library
MIT License
189 stars 24 forks source link

An actor for user input to send messages to live system? #59

Closed davideps closed 2 years ago

davideps commented 4 years ago

I'd like to create an actor for user input to send ad-hoc messages to other actors in the system. I don't want to use a true Python REPL for security reasons. I'm pasting in my code and the error trace.

from thespian.actors import *

# Simple message class and a bunch of subclasses
from python_code.Messages.messages import *

class UserInput(Actor):
    def __init__(self):
        self.scheduler_addr = None  # store scheduler address upon initialization
        self.grid_addr = None  # store grid address upon initialization

    def receiveMessage(self, message, sender):
        if type(message) == M_InitTrigger:
            self.initialize(message)

    def initialize(self, message):
        self.scheduler_addr = message.scheduler
        self.grid_addr = message.grid
        self.get_input()

    def get_input(self):
        command = None
        while command != "quit":
            command = input()  # shouldn't this keep a text input field open?
            self.parse(command)

    def parse(self, command):
        pass

Here is the error trace (repeated a few times)

WARNING:python_code.Characters.thespian_userinput.UserInput:Actor python_code.Characters.thespian_userinput.UserInput @ ActorAddr-(T|:64639) retryable exception on message <python_code.Messages.messages.M_InitTrigger object at 0x000001BB1B261248>
Traceback (most recent call last):

  File "C:\Users\dvyd\.conda\envs\activefiction\lib\site-packages\thespian\system\actorManager.py", line 163, in _handleOneMessage
    actor_result = self.actorInst.receiveMessage(msg, envelope.sender)

  File "D:\Documents\Programming\ActiveFiction\python_code\Characters\thespian_userinput.py", line 12, in receiveMessage
    self.initialize(message)

  File "D:\Documents\Programming\ActiveFiction\python_code\Characters\thespian_userinput.py", line 17, in initialize
    self.get_input()

  File "D:\Documents\Programming\ActiveFiction\python_code\Characters\thespian_userinput.py", line 22, in get_input
    command = input()

EOFError: EOF when reading a line
kquick commented 4 years ago

The actor runs in a separate process context and in that context, stdin is closed and stdout/stderr are redirected. This prevents the actor from intercepting and/or competing with input in the main process.

If you need to read from stdin, the best method is to have the main application (which started the actors) be the one to read from stdin and then send the read information to an actor via ActorSystem().tell({ACTOR_ADDR}, {INPUT_MSG}). You would probably wrap the input message in some kind of class so that you could identify it in the actor's receiveMessage and differentiate the user input message from other messages handled by the actor.

davideps commented 4 years ago

Ah, got it. I'll try that later this week. Thank you.

kquick commented 3 years ago

Can this issue be closed, @davideps ? Do you have any updates on trying the above alternative or any others?