pythontwistedreactoreel

How to stop a Twisted Reactor with a GUI event from Eel?


I'm working on building a Python GUI app (using Eel) that uses a Twisted Reactor to continuously make calls to a network connected RFID reader. The data that's collected needs to be parsed and the GUI needs to be updated.

During this loop, the GUI needs to also be responsive, with the ability to stop a connection with a function call that is passed from the JS front-end with Eel. Here's a simplified version of what the code looks like now:

def callback(RFID_tag):
    print(RFID_tag)

@eel.expose
def stopInventory():
    reactor.stop()

@eel.expose
def startInventory():
    RFID_factory = <SETTING UP FACTORY>
    RFID_factory.addRFIDtagReportCallback(callback)
    reactor.connectTCP(host, port, RFID_factory, timeout=3)
    reactor.start()

Here's where I'm having trouble. Once I call reactor.run(), the script hangs. Any Eel calls that I make from the JS front-end are not registered with the Python script until after the entire script is killed.

I'm not exactly sure if/how I can use the Twisted Reactor API to handle these GUI events while also continuing to process new data from the RFID reader. I was avoiding trying to use threading to solve this, but I can't seem to find how to do it otherwise.


Solution

  • eel has an event loop. Twisted has an event loop. As a rule, to run two event loops in one thread those event loops need to cooperate with each other.

    It looks like eel uses gevent and gevent's event loop. Fortunately, it looks like someone has built the integration between Twisted and gevent already - https://github.com/jyio/geventreactor. Somewhat less fortunately, it doesn't look particularly maintained. Perhaps it can be salvaged, though.