Add worker loops: run and drive an ErlangEventLoop inside a context - #71
Merged
Conversation
py_context:start_loop/stop_loop/loop_ref/submit/submit_await and the erlang.server helper let Erlang run N owngil workers that serve TCP/UDP on a socket Erlang bound (py:dup_fd per worker) or adopt accepted fds, and inject coroutines into the running loop. Fixes behind it: owngil contexts had no ErlangEventLoop and returned the main loop from context_get_event_loop; owngil dispatch was blocking on a dirty scheduler with a 30 s cap; transports closed fds still in the poll set (erts_poll reports under churn); READ re-arm from the loop thread crashed in enif_select; task start failures were dropped. Includes CT suite, Python unit tests, gated stress suite, bench script and docs/workers.md.
…ng loop Tasks beyond MAX_TASK_BATCH queued before the worker ran were stranded: submit_task sends no new wakeup while one is pending and the running-loop branch returned ok. Seen as test_submit_ordering timeouts on slow CI.
The io queue can store several small task binaries in one iovec element; dequeuing iov_len per task dropped every task after the first in that element (every second submit lost on slow CI runners).
A loop running on its own thread consumes pending events itself; sending task_ready for every timer or fd event made the worker attach to the subinterpreter and take its GIL for nothing. Track that state in the loop struct (_set_running_for) and only wake the loop thread.
asyncio cancels a handle after it ran (sleep's finally); a recycled handle then cancels the callback that reused it. Only _dispatch fd handles are pooled now. Explains the every-second-task loss on CI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Runtime API for gunicorn-style Python workers inside the VM (the arbiter itself will live in hornbeam).
Added
py_context:start_loop/1,2,stop_loop/1,2,loop_ref/1,submit/4,5,submit_await/4,5,6;{py_loop_exit, Ctx, Result}to the owner;{error, loop_running}for call/eval/exec while a loop runs;preloadoption onpy_context:new/1.erlang.server:serve(listen_fd, factory, udp=False),adopt(fd, factory),stop_serving.process_ready_tasksattaches to the subinterpreter), wake on inject, task start failures reported to the caller.Fixed
ErlangEventLoop;context_get_event_loopreturned the main loop and re-pointed its worker.erts_poll/ stealing control reports); READ re-arm from the loop thread crashed inenif_select.Tests:
py_worker_loop_SUITE(22 cases), Python unit tests (test_server,test_transport_close,test_loop_helpers),py_worker_loop_stress_SUITE(STRESS=1). Bench:examples/bench_worker_loop.erl. Docs:docs/workers.md.Full CT on Python 3.14: 619 passed, 14 expected skips. Python 3.12: owngil group skips, rest passes.