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
AsyncResult.get() has at least 1 second latency while executing under gevent #7052
Closed
4 tasks done
Milestone
Comments
Hey @mrmaxi We also offer priority support for our sponsors. |
mrmaxi
added a commit
to mrmaxi/celery
that referenced
this issue
Nov 14, 2021
wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout
mrmaxi
added a commit
to mrmaxi/celery
that referenced
this issue
Nov 14, 2021
wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout
mrmaxi
added a commit
to mrmaxi/celery
that referenced
this issue
Nov 14, 2021
wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout
mrmaxi
added a commit
to mrmaxi/celery
that referenced
this issue
Nov 14, 2021
Wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout. Does not block event loop, because `drain_events` of asynchronous backends with pubsub commonly sleeping for some nonzero time while waiting events.
mrmaxi
added a commit
to mrmaxi/celery
that referenced
this issue
Nov 14, 2021
Wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout. Does not block event loop, because `drain_events` of asynchronous backends with pubsub commonly sleeping for some nonzero time while waiting events.
auvipy
pushed a commit
that referenced
this issue
Nov 15, 2021
Wakeup waiters in `wait_for` after every `drain_events` occurs instead of only after 1 seconds timeout. Does not block event loop, because `drain_events` of asynchronous backends with pubsub commonly sleeping for some nonzero time while waiting events.
craigjbass
added a commit
to uktrade/celery
that referenced
this issue
Jan 25, 2022
)" This reverts commit cc55692.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Checklist
for similar or identical enhancement to an existing feature.
for existing proposed enhancements.
to find out if the if the same enhancement was already implemented in the
master branch.
(If there are none, check this box anyway).
Related Issues and Possible Duplicates
Related Issues
Possible Duplicates
Brief Summary
When it's used asynchronous backend as Redis with pubsub, result of short task (0.1s length, for example) available immediate.
Once i add gevent, result of the same short task became available after 1s, 10 times slower!
I will clarify that in both cases I used identical separate worker runed in docker with standard perfork pool.
celery -A tasks worker --prefetch-multiplier=1 --concurrency=10
This behavior relate with implementation features of GH-5974
AsyncResult.get() in a gevent context has at least 1 second latency, because
I would like the task result to be available as soon as possible after the worker has submitted it. I think that
wait_for
have to return immediate after socket operationresult_consumer.drain_events
occurs, rather than every "timeout" # of seconds.It won't cause overhead, because socket operation still not block event loop, so it let other greenlets executing.
Design
Now in
wait_for
it wait (with timeout 1 second) whengreenletDrainer.run
will finish, of course it's never finish, so it return after 1 second timeout.If in
wait_for
wait the end of socket operation_pubsub.get_message
insteadgreenletDrainer.run
it will less latency and still not block event loop, so it let other greenlets executing.I can prepare PR with changes in backends.asynchronous greenletDrainer, eventletDrainer, geventDrainer, that every time after
result_consumer.drain_events
(in greenletDrainer run loop) will send notification for wakeup all greenlets waiting results inwait_for
.Architectural Considerations
None
Proposed Behavior
Asynchronous backends (for example Redis) will be same efficient under gevent context as without it.
Proposed UI/UX
Diagrams
N/A
Alternatives
Another workaround may be to pass
interval
argument intoBaseResultConsumer._wait_for_pending
for pass it intodrain_events_until
and than intowait_for
.In this case it will be possible define own timeout for
wait_for
interation when execute AsyncResult.get(interval=0.05).Howto reproduce
create tasks.py with your ip address for broker and backend
create Dockerfile
build and run worker
create gevent_example.py
now run gevent_example.py
It is seen that first task with length 0.1s has completed only after ~1.23s (0:00:01.226389)
But if comment line with monkey patching:
# from gevent import monkey; monkey.patch_all()
It is seen that first task with length 0.1s has completed just after ~0.34s (0:00:00.338647)
with proposed changes in backends.asynchronous become:
It is seen that first task with length 0.1s has completed just after ~0.32s (0:00:00.322748)
The text was updated successfully, but these errors were encountered: