Skip to content

gevent breaking threading #167

@Shiny380

Description

@Shiny380

gevent monkey patching seems to be breaking threads.
This can be seen in mqtt_client_base.py https://github.com/NubeIO/rubix-point-server/blob/master/src/services/mqtt_client/mqtt_client_base.py#L32

self._client.connect(self.config.host, self.config.port, self.config.keepalive)

This line somehow splits the thread into two separate threads. One thread the normal FlaskThread and one gevent.threading._DummyThread. Seems to be linked to accessing threading.currentThread() or similar.

This is causing a constant reconnection issue for mqtt and probably other issues. It stops happening if monkey.patch_all() (https://github.com/NubeIO/rubix-point-server/blob/master/src/server.py#L14) is removed.


Debug code from mqtt_client_base.py:

print('mqtt client connecting...')
self._client.connect(self.config.host, self.config.port, self.config.keepalive)
print('    mqtt client connected')
print('    ', threading.currentThread())
print('    ', type(threading.currentThread()))

Output:

mqtt starting
mqtt client connecting...
    mqtt client connected
     <FlaskThread(Thread-1, started daemon 140669658012112)>
     <class 'src.background.FlaskThread'>
        mqtt client looping
    mqtt client connected
     <_DummyThread(Dummy-2, started daemon 140669658012112)>
     <class 'gevent.threading._DummyThread'>

Prevent threading being patched with curious_george.patch_all(thread=False) :

/home/dan/rubix-point-server/venv/lib/python3.8/site-packages/gunicorn/workers/ggevent.py:53: MonkeyPatchWarning: Patching more than once will result in the union of all True parameters being patched
  monkey.patch_all()

But then the event dispatching across threads breaks in a weird way where it appears to function correctly but the event never gets added to the event queue. The event queue object is the exact same object (address) across the different threads but the loop in the target thread never seems to receive the event.
seen in this line https://github.com/NubeIO/rubix-point-server/blob/master/src/services/event_service_base.py#L70 where it functions correctly on the correct object address but just disappears.
can be seen by calling this function https://github.com/NubeIO/rubix-point-server/blob/master/src/source_drivers/modbus/resources/point/point_singular.py#L88 from a Flask http request
/api/modbus/poll/point

{
    "network_type": "RTU",
    "network_rtu_port": "/dev/ttyUSB0", 

    "device_address": 1,

    "point_register": 1,
    "point_register_length": 2,
    "point_function_code": "READ_INPUT_REGISTERS",
    "point_data_type": "FLOAT",
    "point_write_value": 0
}

Some links:

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions