-
Notifications
You must be signed in to change notification settings - Fork 0
Description
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: