New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error: cannot switch to a different thread #1437
Comments
I also get this error when I do not patch thread from monkey and call redis |
Trivial reproducer: import threading
from gevent import lock
sem = lock.Semaphore(
1,
# Provide the hub of this thread. If we don't do this
# now, it gets initialized lazily the first time it would have
# to block, which, in the event of threads, would be from an arbitrary
# thread.
gevent.get_hub()
)
assert sem.hub is not None
# Make future acquires block
sem.acquire()
def thread_main():
sem.acquire()
t = threading.Thread(target=thread_main)
t.start()
t.join() Exception in thread Thread-1:
Traceback (most recent call last):
File "src/gevent/_semaphore.py", line 131, in gevent.__semaphore.Semaphore.acquire
def acquire(self, blocking=True, timeout=None):
File "src/gevent/_semaphore.py", line 160, in gevent.__semaphore.Semaphore.acquire
success = self._wait(timeout)
File "src/gevent/_abstract_linkable.py", line 208, in gevent.__abstract_linkable.AbstractLinkable._wait
gotit = self._wait_core(timeout)
File "src/gevent/_abstract_linkable.py", line 178, in gevent.__abstract_linkable.AbstractLinkable._wait_core
with Timeout._start_new_or_dummy(timeout) as timer:
File "src/gevent/_abstract_linkable.py", line 196, in gevent.__abstract_linkable.AbstractLinkable._wait_core
raise
File "src/gevent/_abstract_linkable.py", line 182, in gevent.__abstract_linkable.AbstractLinkable._wait_core
result = self.hub.switch()
File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
def switch(self):
File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
def switch(self):
File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch
return _greenlet_switch(self) # pylint:disable=undefined-variable
File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch
return PyGreenlet_Switch(self, NULL, NULL)
error: cannot switch to a different thread In other words, a greenlet from one thread tries to block on a lock held by a greenlet in another thread. Now, obviously you're Not Supposed To Do That. One cannot mix gevent primitives with native threads like that; gevent objects generally have thread-affinity. (sockets are another example of this.) In such cases, perhaps we could at least provide a more informative error message. In the tracebacks originally posted, though, the entire system was supposed to be monkey-patched, so there's not supposed to be more than one native thread running, so that's a bit puzzling. Here's another recent example:
Here, I happen to know that |
I can confirm that this was fixed in 20.5.1. I have a service which uses gevent, that serves data via an HTTP interface, and a pool which collects this data continuously from many external sources. Because of this blocking, I tried to move the data collection from a pool to a native threadpool, but then came errors with logging, LoopExit (had to following this to resolve), etc. Logging is very minimal, but I would still like to see errors when they occur, even if in another thread. Performance isn't critical here. Upgrading to 20.6.2 (from 1.5.0) which contains PR #1617 meant that the solution from became feasible, which was great. So thanks for this! |
We hit this crash when running PA files in stage today: ``` Traceback (most recent call last): File "/app/recidiviz/persistence/persistence.py", line 334, in write measurements, match_and_write_people, 5): File "/app/recidiviz/persistence/persistence.py", line 225, in retry_transaction should_continue = txn_body(session) File "/app/recidiviz/persistence/persistence.py", line 305, in match_and_write_people session, metadata.region, people) File "/app/recidiviz/persistence/entity_matching/entity_matching.py", line 49, in match return matcher.run_match(session, region, ingested_people) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 279, in run_match ingested_db_persons, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 330, in _run_match self._perform_match_postprocessing(matched_entities_builder.people, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 359, in _perform_match_postprocessing matched_persons) File "/app/recidiviz/persistence/entity_matching/state/us_pa/us_pa_matching_delegate.py", line 76, in perform_match_postprocessing logging.info('[Entity matching] Move supervision violations onto supervision periods by date.') File "/usr/lib/python3.7/logging/__init__.py", line 1989, in info root.info(msg, *args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1378, in info self._log(INFO, msg, args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1514, in _log self.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 1524, in handle self.callHandlers(record) File "/usr/lib/python3.7/logging/__init__.py", line 1586, in callHandlers hdlr.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 892, in handle self.acquire() File "/usr/lib/python3.7/logging/__init__.py", line 843, in acquire self.lock.acquire() File "/usr/lib/python3.7/threading.py", line 148, in acquire rc = self._block.acquire(blocking, timeout) File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.7/site-packages/gevent/thread.py", line 118, in acquire acquired = BoundedSemaphore.acquire(self, blocking, timeout) File "src/gevent/_semaphore.py", line 106, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 134, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_abstract_linkable.py", line 208, in gevent.__abstract_linkable.AbstractLinkable._wait File "src/gevent/_abstract_linkable.py", line 178, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 196, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 182, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch greenlet.error: cannot switch to a different thread" ``` [This issue](gevent/gevent#1437) suggest that this issue has been fixed in a recent `gevent` version. We previously had the version pegged at a particular version, but Colin says we should not longer have to do that. Fixes issue getting in the way of completing Recidiviz/recidiviz-data#3462 GitOrigin-RevId: de289bc6f8e3af0e5654aed74015ca4f4728fe19
We hit this crash when running PA files in stage today: ``` Traceback (most recent call last): File "/app/recidiviz/persistence/persistence.py", line 334, in write measurements, match_and_write_people, 5): File "/app/recidiviz/persistence/persistence.py", line 225, in retry_transaction should_continue = txn_body(session) File "/app/recidiviz/persistence/persistence.py", line 305, in match_and_write_people session, metadata.region, people) File "/app/recidiviz/persistence/entity_matching/entity_matching.py", line 49, in match return matcher.run_match(session, region, ingested_people) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 279, in run_match ingested_db_persons, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 330, in _run_match self._perform_match_postprocessing(matched_entities_builder.people, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 359, in _perform_match_postprocessing matched_persons) File "/app/recidiviz/persistence/entity_matching/state/us_pa/us_pa_matching_delegate.py", line 76, in perform_match_postprocessing logging.info('[Entity matching] Move supervision violations onto supervision periods by date.') File "/usr/lib/python3.7/logging/__init__.py", line 1989, in info root.info(msg, *args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1378, in info self._log(INFO, msg, args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1514, in _log self.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 1524, in handle self.callHandlers(record) File "/usr/lib/python3.7/logging/__init__.py", line 1586, in callHandlers hdlr.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 892, in handle self.acquire() File "/usr/lib/python3.7/logging/__init__.py", line 843, in acquire self.lock.acquire() File "/usr/lib/python3.7/threading.py", line 148, in acquire rc = self._block.acquire(blocking, timeout) File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.7/site-packages/gevent/thread.py", line 118, in acquire acquired = BoundedSemaphore.acquire(self, blocking, timeout) File "src/gevent/_semaphore.py", line 106, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 134, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_abstract_linkable.py", line 208, in gevent.__abstract_linkable.AbstractLinkable._wait File "src/gevent/_abstract_linkable.py", line 178, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 196, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 182, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch greenlet.error: cannot switch to a different thread" ``` [This issue](gevent/gevent#1437) suggest that this issue has been fixed in a recent `gevent` version. We previously had the version pegged at a particular version, but Colin says we should not longer have to do that. Fixes issue getting in the way of completing Recidiviz/recidiviz-data#3462 GitOrigin-RevId: fb1320b9307abd347713d42da638ea2017b2372b
We hit this crash when running PA files in stage today: ``` Traceback (most recent call last): File "/app/recidiviz/persistence/persistence.py", line 334, in write measurements, match_and_write_people, 5): File "/app/recidiviz/persistence/persistence.py", line 225, in retry_transaction should_continue = txn_body(session) File "/app/recidiviz/persistence/persistence.py", line 305, in match_and_write_people session, metadata.region, people) File "/app/recidiviz/persistence/entity_matching/entity_matching.py", line 49, in match return matcher.run_match(session, region, ingested_people) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 279, in run_match ingested_db_persons, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 330, in _run_match self._perform_match_postprocessing(matched_entities_builder.people, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 359, in _perform_match_postprocessing matched_persons) File "/app/recidiviz/persistence/entity_matching/state/us_pa/us_pa_matching_delegate.py", line 76, in perform_match_postprocessing logging.info('[Entity matching] Move supervision violations onto supervision periods by date.') File "/usr/lib/python3.7/logging/__init__.py", line 1989, in info root.info(msg, *args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1378, in info self._log(INFO, msg, args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1514, in _log self.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 1524, in handle self.callHandlers(record) File "/usr/lib/python3.7/logging/__init__.py", line 1586, in callHandlers hdlr.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 892, in handle self.acquire() File "/usr/lib/python3.7/logging/__init__.py", line 843, in acquire self.lock.acquire() File "/usr/lib/python3.7/threading.py", line 148, in acquire rc = self._block.acquire(blocking, timeout) File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.7/site-packages/gevent/thread.py", line 118, in acquire acquired = BoundedSemaphore.acquire(self, blocking, timeout) File "src/gevent/_semaphore.py", line 106, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 134, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_abstract_linkable.py", line 208, in gevent.__abstract_linkable.AbstractLinkable._wait File "src/gevent/_abstract_linkable.py", line 178, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 196, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 182, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch greenlet.error: cannot switch to a different thread" ``` [This issue](gevent/gevent#1437) suggest that this issue has been fixed in a recent `gevent` version. We previously had the version pegged at a particular version, but Colin says we should not longer have to do that. Fixes issue getting in the way of completing Recidiviz/recidiviz-data#3462 GitOrigin-RevId: fb1320b9307abd347713d42da638ea2017b2372b
We hit this crash when running PA files in stage today: ``` Traceback (most recent call last): File "/app/recidiviz/persistence/persistence.py", line 334, in write measurements, match_and_write_people, 5): File "/app/recidiviz/persistence/persistence.py", line 225, in retry_transaction should_continue = txn_body(session) File "/app/recidiviz/persistence/persistence.py", line 305, in match_and_write_people session, metadata.region, people) File "/app/recidiviz/persistence/entity_matching/entity_matching.py", line 49, in match return matcher.run_match(session, region, ingested_people) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 279, in run_match ingested_db_persons, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 330, in _run_match self._perform_match_postprocessing(matched_entities_builder.people, db_persons) File "/app/recidiviz/persistence/entity_matching/state/state_entity_matcher.py", line 359, in _perform_match_postprocessing matched_persons) File "/app/recidiviz/persistence/entity_matching/state/us_pa/us_pa_matching_delegate.py", line 76, in perform_match_postprocessing logging.info('[Entity matching] Move supervision violations onto supervision periods by date.') File "/usr/lib/python3.7/logging/__init__.py", line 1989, in info root.info(msg, *args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1378, in info self._log(INFO, msg, args, **kwargs) File "/usr/lib/python3.7/logging/__init__.py", line 1514, in _log self.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 1524, in handle self.callHandlers(record) File "/usr/lib/python3.7/logging/__init__.py", line 1586, in callHandlers hdlr.handle(record) File "/usr/lib/python3.7/logging/__init__.py", line 892, in handle self.acquire() File "/usr/lib/python3.7/logging/__init__.py", line 843, in acquire self.lock.acquire() File "/usr/lib/python3.7/threading.py", line 148, in acquire rc = self._block.acquire(blocking, timeout) File "/root/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.7/site-packages/gevent/thread.py", line 118, in acquire acquired = BoundedSemaphore.acquire(self, blocking, timeout) File "src/gevent/_semaphore.py", line 106, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 134, in gevent.__semaphore.Semaphore.acquire File "src/gevent/_abstract_linkable.py", line 208, in gevent.__abstract_linkable.AbstractLinkable._wait File "src/gevent/_abstract_linkable.py", line 178, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 196, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 182, in gevent.__abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 61, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 65, in gevent.__greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/__greenlet_primitives.pxd", line 35, in gevent.__greenlet_primitives._greenlet_switch greenlet.error: cannot switch to a different thread" ``` [This issue](gevent/gevent#1437) suggest that this issue has been fixed in a recent `gevent` version. We previously had the version pegged at a particular version, but Colin says we should not longer have to do that. Fixes issue getting in the way of completing Recidiviz/recidiviz-data#3462 GitOrigin-RevId: 013497930fdd97ded9ff1edda7337a4aeffad68d
I observed several of these errors during an automated test run (from 0126 to 0356, 7 of them, across two different machines running gunicorn with very early gevent monkey-patching, in two processes per machine). I don't recall seeing them before.
What's going on here?
The text was updated successfully, but these errors were encountered: