Rospy clean shutdown with gevent
I've had very good luck patching gevent into rospy, opening up opportunity to write a ROS node in a co-operative multitasking style. You can see examples I've put together here: https://github.com/ablakey/rospy_gevent
Has anyone else experimented with gevent and rospy? I cannot get nodes to ever shut down cleanly. They always crash-on-shutdown with gevent.hub.BlockingSwitchOutError: Impossible to call blocking function in the event loop callback
.
I think it has to do with a patched thread not properly yielding. I'm continuing to investigate this, but wanted to see if anyone in the community has already had some luck.
Full stacktrace below:
^C[patched_subscriber-3] killing on exit
[patched_publisher-2] killing on exit
Traceback (most recent call last):
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/core.py", line 606, in _ros_signal
signal_shutdown("signal-"+str(sig))
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/core.py", line 599, in signal_shutdown
t.join(_TIMEOUT_SHUTDOWN_JOIN)
File "/usr/lib/python2.7/threading.py", line 951, in join
self.__block.wait(delay)
File "/usr/lib/python2.7/threading.py", line 359, in wait
_sleep(delay)
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 194, in sleep
hub.wait(loop.timer(seconds, ref=ref))
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 627, in wait
result = waiter.get()
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 875, in get
return self.hub.switch()
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 605, in switch
switch_out()
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 609, in switch_out
raise BlockingSwitchOutError('Impossible to call blocking function in the event loop callback')
BlockingSwitchOutError: Impossible to call blocking function in the event loop callback
Traceback (most recent call last):
File "/home/ablakey/locus_dev/src/rospy_gevent/scripts/patched_publisher", line 28, in <module>
r.sleep()
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/timer.py", line 103, in sleep
sleep(self._remaining(curr_time))
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/timer.py", line 134, in sleep
rospy.rostime.wallsleep(duration)
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/rostime.py", line 277, in wallsleep
time.sleep(duration)
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 194, in sleep
hub.wait(loop.timer(seconds, ref=ref))
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 627, in wait
Traceback (most recent call last):
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/core.py", line 606, in _ros_signal
result = waiter.get()
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 875, in get
signal_shutdown("signal-"+str(sig))
File "/opt/ros/hotdog/lib/python2.7/dist-packages/rospy/core.py", line 599, in signal_shutdown
t.join(_TIMEOUT_SHUTDOWN_JOIN)
File "/usr/lib/python2.7/threading.py", line 951, in join
return self.hub.switch()
File "/usr/lib/python2.7/dist-packages/gevent/hub.py", line 606, in switch
return greenlet.switch(self)
gevent.hub.BlockingSwitchOutError: Impossible to call blocking function in the event loop callback ...