Charting the route to multi-threading support

We’re working hard on improving multi-threading support in Crystal.

Current focus is on refactoring the event loop to use system selectors and lifetime subscriptions: New Event Loop (UNIX): call for reviews & tests) (RFC 7).
The multi-threaded scheduler implementation from RFC 2 is also pretty evolved and available as a standalone shard for testing: ysbaddaden/execution_context.

These efforts are the core components for multi-threading support and do most of the heavy lifting. But they won’t get us all the way there.

This thread is supposed to identify and collect that tasks needed for making multi-threading a prime-time feature, in an informal way.
Please note that this is a meta thread and not the place to discuss details of individual tasks. That should happen in the specific task discussions.

I’ll extend and edit the list following the discussion.
Once we have sufficiently identified the tasks, we’ll convert them into actionable items for the issue tracker.

Runtime:

Stdlib:

Documentation:

  • Lead an initiative to test and document the multi-threading capabilities in the ecosystem (i.e. shards).
  • Generate learning materials on execution contexts and safe multi-threading in Crystal.

Infrastructure:

  • Plan the transitioning process from current single-threaded scheduler (and optional -Dpreview_mt) to execution contexts.
  • Enhance the CI matrix to test several runtime configurations on all supported platforms (especially during the transitioning process)

Related efforts:

These are not strictly required, but relevant side-quests.

16 Likes

Another related effort to explore is aio for async read/write over regular disk files with kqueue on *BSD and Darwin —aio is different on Linux where we should prefer io_uring.

I’ve been working the DNS side quest and think I have a reasonable first pass for a native solution: GitHub - spider-gazelle/dns: extensible non blocking DNS for crystal lang
Would be happy to have some feedback

Allowing the developer to choose between native crystal or system getaddrinfo (and equivalents) provides decent flexibility. We could always introduce this solution, leaving getaddrinfo as default, even indefinitely, with the native solution options for those that need / want it.

The above implementation makes it simple to define domain name regexes for routing DNS requests to different resolvers, providing quite a bit of flexibility - could wrap the getaddrinfo option as part of this so it’s the one interface for all things DNS and then make getaddrinfo the overridable default for A and AAAA records

5 Likes

Instead of ordered queue consider a hierarchical timer wheel - hashed-and-hierarchical-timing-wheels. example implementation ratas

2 Likes

Thanks for the reference. That’s really helpful.
“ordered queue” is meant in a very general way, unrelated to any specific implementation. Finding a good data structure is still something to explore.
We’ll start a dedicated discussion about this.