greenlet.error: cannot switch to a different thread

Question:

I have a Flask application, getting this error while trying to integrate flask with faust.

app.py

import mode.loop.eventlet
import logging
import logging.config
import json
from flask import Flask
from elasticapm.contrib.flask import ElasticAPM

def create_app():
    app = Flask(__name__)
    configure_apm(app)
    configure_logging()
    register_blueprints(app)
    register_commands(app)
    return app

main.py

from flask import jsonify
from litmus.app import create_app
from intercepter import Intercepter

app = create_app()
app.wsgi_app = Intercepter(app.wsgi_app , app)

@app.route('/status')
def status():
    return jsonify({'status': 'online'}), 200

another controller

@api_blue_print.route('/v1/analyse', methods=['POST'])
def analyse():
    analyse_with_historic_data.send(value=[somedata])
    return jsonify({'message': 'Enqueued'}), 201

analyse_with_historic_data.py

@app.agent(analysis_topic)
async def analyse_with_historic_data(self, stream):
    async for op in stream:
        entity_log = EntityLog.where('id', op.entity_log_id).first()

Error Trace:

Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 461, in fire_timers
    timer()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 59, in __call__
    cb(*args, **kw)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 147, in _do_acquire
    waiter.switch()
greenlet.error: cannot switch to a different thread
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 461, in fire_timers
    timer()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 59, in __call__
    cb(*args, **kw)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 147, in _do_acquire
    waiter.switch()
greenlet.error: cannot switch to a different thread
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/queue.py", line 118, in switch
    self.greenlet.switch(value)
greenlet.error: cannot switch to a different thread
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 551, in wait
    signaled = self._cond.wait(timeout)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/threading.py", line 299, in wait
    gotit = waiter.acquire(True, timeout)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/semaphore.py", line 107, in acquire
    hubs.get_hub().switch()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 298, in switch
    return self.greenlet.switch()
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 350, in run
    self.wait(sleep_time)
  File "/Users/sahilpaudel/.pyenv/versions/3.6.5/lib/python3.6/site-packages/eventlet/hubs/kqueue.py", line 96, in wait
    time.sleep(seconds)

I have trying to fix this issue by monkey.patch_all but that too it didn’t work out giving another stacktrace that lock cannot be released something.

Asked By: Sahil Paudel

||

Answers:

Something similar happened to me when I tried to debug a flask application using Pycharm.

What I finally did to eventually solve my issue was to enable gevent compatibility in Pycharm:
File -> settings -> Build,Execution,Deployment -> Python debugger -> Gevent compatible

Answered By: gilodo

If previous answer do not help, paste before all import:

from gevent import monkey

monkey.patch_all()