Skip to content

allow integrating with external event loop - #531

Merged
Guest0x0 merged 15 commits into
mainfrom
external-loop-integration
Aug 7, 2026
Merged

allow integrating with external event loop#531
Guest0x0 merged 15 commits into
mainfrom
external-loop-integration

Conversation

@Guest0x0

@Guest0x0 Guest0x0 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

closes #526

moonbitlang/async relies on an event loop to perform asynchronous IO operations internally. However, some applications may have their own event loop as well. For example, GUI frameworks typically has their own event loop. Event loops are non-modular by nature, so to integrate two event loops, the only possible way is to run each loop in a dedicated thread, and use a self-pipe or similar to communicate between the two loops. Some libraries require their event loop being run in the main thread. In that case, the only possible workaround before this PR is to run all MoonBit code in a dedicated thread, which is tedious.

This PR add native support for such external loop integration. A new API, @async.set_external_event_loop, is introduced, which enables external event loop integration by providing an event loop implementation. The implementation is abstracted via a trait @moonbitlang/async/external_loop_integration.ExternalEventLoop. The user-provided loop should provide its wait function with timeout support, and a callback for waking the loop for use by moonbitlang/async. See the documents of that trait for more details on which operations are needed and semantic caveats.

@async.set_external_event_loop can be used with async fn main. In fact it can be called in async fn main as well, as long as it is invoked before any actual async operations. When moonbitlang/async sees that an external event loop is set, it automatically enter external loop integration mode. In this mode, the waiting part of moonbitlang/async event loop will be spawned in a dedicated thread, and the user-provided loop will be run in the main thread instead.

@coveralls

coveralls commented Aug 5, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 970

Coverage decreased (-0.007%) to 76.222%

Details

  • Coverage decreased (-0.007%) from the base build.
  • Patch coverage: 23 uncovered changes across 4 files (79 of 102 lines covered, 77.45%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
src/internal/event_loop/event_loop.mbt 62 47 75.81%
src/internal/event_loop/event_loop_unix.mbt 15 11 73.33%
src/external_loop_integration/internal/external_loop_test/main.mbt 15 12 80.0%
src/external_loop_integration/internal/external_loop_test/unimplemented.mbt 1 0 0.0%
Total (5 files) 102 79 77.45%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 4971
Covered Lines: 3789
Line Coverage: 76.22%
Coverage Strength: 11455.44 hits per line

💛 - Coveralls

@Guest0x0
Guest0x0 force-pushed the external-loop-integration branch from 62e65b2 to ea6e575 Compare August 5, 2026 10:29
@Guest0x0
Guest0x0 force-pushed the external-loop-integration branch from ff5bf1f to d46f5fe Compare August 6, 2026 07:31
@Guest0x0
Guest0x0 merged commit 35a2b05 into main Aug 7, 2026
21 checks passed
@Guest0x0
Guest0x0 deleted the external-loop-integration branch August 7, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: public embeddable async runtime driver for native host event loops

2 participants