basically this demonstrates that gevent & eventlet will mess up badly when you use non-thread safe code
Warning: while this is written for now EOLed stack, the results can be replicated for the recent most versions of python and/or celery as well
- have dependecies installed using
requirements.txt
- run redis on localhost:
docker run -d -p 6379:6379 redis
- init db:
python2 manage.py migrate
expectation : No errors, everything runs fine. (ok there might be some database locked errors, but that's not what we're looking for)
- run
python2 manage.py fill
to prefill the queue with tasks - run
celery worker -A demo -c 8 --pool prefork -l INFO
to run tasks
expectation : few "IntegrityError: NOT NULL constraint failed: core_store.val", proving that shared state was mutated while the other thread was running concurrently.
- run
python2 manage.py fill
to prefill the queue with tasks - run
celery worker -A demo -c 8 --pool gevent -l INFO
to run tasks
expectation : few "IntegrityError: NOT NULL constraint failed: core_store.val", proving that shared state was mutated while the other thread was running concurrently.
- run
python2 manage.py fill
to prefill the queue with tasks - run
celery worker -A demo -c 8 --pool eventlet -l INFO
to run tasks
Stay the fuck away from gevent
and eventlet
if you have thread unsafe code, or you'll end up with inconsistent behaviour which can go catastrophically wrong.