-
Notifications
You must be signed in to change notification settings - Fork 10
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
New hybrid dispatcher concept (enables mirai cancellation) #170
Conversation
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #170 +/- ##
==========================================
- Coverage 99.71% 97.80% -1.92%
==========================================
Files 9 9
Lines 692 864 +172
==========================================
+ Hits 690 845 +155
- Misses 2 19 +17 ☔ View full report in Codecov by Sentry. |
I should probably add a little more on the cancellation implementation itself. R is single-threaded, so the only way of stopping evaluation is through an interrupt signal. This must be delivered concurrent with the evaluation, i.e. from another thread. Fortunately NNG, as a concurrency framework, provides these, and we just re-purpose an async message receive callback for this purpose (in much the same way a callback can make a call into Then at the daemon (worker) we just have an async receive ready while we're evaluating, which will raise an interrupt if a cancellation message is received. The actual cancellation instruction is sent from As to why the whole new architecture, it stems from the fact that previously we didn't eagerly realise the task queue at dispatcher, but kept them buffered at the system sockets, only materializing them when a daemon was ready to accept. This meant that it would have been cumbersome to implement cancellation, as we had no access to queued tasks whatsoever. And if we were going to change this behaviour, then it made sense to think about the design holistically and update everything at the same time. The result is a consciously much cleaner design, whereas previously the development has been pretty much organic and demand/feature-driven. |
I've implemented my suggestion above in dd30542, so |
@jcheng5 I'll keep this open, but you can assume that I'll merge it as is (barring further comments from yourself/Hadley). I'll defer to you what you think is the best way of making promise[["mirai"]] <- x If you're making changes to the promises package, please also take a look at rstudio/promises#111 where I've provided suggestions you can adopt directly in your PR there. |
New default dispatcher
Inviting @jcheng5 @hadley for review and comment.
This is a complete re-design of dispatcher using a more optimal and future-proof architecture.
The key difference is that whereas previously dispatcher used one socket per daemon connection, it now uses one socket for all daemon connections.
The previous configuration was necessary due to limitations of the NNG req/rep (PRC) protocol using a round-robin algorithm. This is typically optimal behaviour for web servers and similar applications, but not for arbitrary execution where evaluation times may vary greatly.
The novel solution is to preserve the req/rep abstraction for the user, with
mirai()
working substantially the same way, but to re-wire the dispatcher / daemon back-end to use an alternative protocol (NNG's pair 1 poly). This allows one-to-many mapping with directed sends, which is exactly what's needed to implement an optimal task queue dispatcher.Mirai Cancellation
Allows actual cancellation of mirai when using
stop_mirai()
, as per the below example:stop_mirai()
returnsTRUE
if the task is awaiting execution - it is discarded from the queue. Cancellation is certain.stop_mirai()
returnsNA
if the task was in-execution. An interrupt is sent to the daemon process, but it may have been partially executed by this point.stop_mirai()
returnsFALSE
if the task has already completed or been cancelled.Created on 2024-12-01 with reprex v2.1.1
Other notable improvements
nanonext
) hence retiring a lot of custom code that was designed to deal with this.Created on 2024-12-01 with reprex v2.1.1