diff --git a/moonpool-lwt/_doc-dir/README.md b/moonpool-lwt/_doc-dir/README.md index c51361df..5a37e6a0 100644 --- a/moonpool-lwt/_doc-dir/README.md +++ b/moonpool-lwt/_doc-dir/README.md @@ -165,6 +165,57 @@ val expected_sum : int = 5050 - : unit = () ``` +### Errors + +We have a `Exn_bt.t` type that comes in handy in many places. It bundles together +an exception and the backtrace associated with the place the exception was caught. + +### Fibers + +On OCaml 5, Moonpool comes with a library `moonpool.fib` (module `Moonpool_fib`) +which provides _lightweight fibers_ +that can run on any Moonpool runner. +These fibers are a sort of lightweight thread, dispatched on the runner's +background thread(s). +Fibers rely on effects to implement `Fiber.await`, suspending themselves until the `await`-ed fiber +is done. + +```ocaml +# #require "moonpool.fib";; + +# (* convenient alias *) + module F = Moonpool_fib;; +module F = Moonpool_fib +# F.main (fun _runner -> + let f1 = F.spawn (fun () -> fib 10) in + let f2 = F.spawn (fun () -> fib 15) in + F.await f1 + F.await f2);; +- : int = 1076 +``` + +Fibers form a _tree_, where a fiber calling `Fiber.spawn` to start a sub-fiber is +the sub-fiber's _parent_. +When a parent fails, all its children are cancelled (forced to fail). +This is a simple form of [Structured Concurrency](https://en.wikipedia.org/wiki/Structured_concurrency). + +Like a future, a fiber eventually _resolves_ into a value (or an `Exn_bt.t`) that it's possible +to `await`. With `Fiber.res : 'a Fiber.t -> 'a Fut.t` it's possible to access that result +as a regular future, too. +However, this resolution is only done after all the children of the fiber have +resolved — the lifetime of fibers forms a well-nested tree in that sense. + +When a fiber is suspended because it `await`s another fiber (or future), the scheduler's +thread on which it was running becomes available again and can go on process another task. +When the fiber resumes, it will automatically be re-scheduled on the same runner it started on. +This means fibers on pool P1 can await fibers from pool P2 and still be resumed on P1. + +In addition to all that, fibers provide _fiber local storage_ (like thread-local storage, but per fiber). +This storage is inherited in `spawn` (as a shallow copy only — it's advisable to only +put persistent data in storage to avoid confusing aliasing). +The storage is convenient for carrying around context for cross-cutting concerns such +as logging or tracing (e.g. a log tag for the current user or request ID, or a tracing +scope). + ### Fork-join On OCaml 5, again using effect handlers, the sublibrary `moonpool.forkjoin` diff --git a/moonpool/Moonpool/Background_thread/For_runner_implementors/index.html b/moonpool/Moonpool/Background_thread/For_runner_implementors/index.html index 681bb222..6d61ea48 100644 --- a/moonpool/Moonpool/Background_thread/For_runner_implementors/index.html +++ b/moonpool/Moonpool/Background_thread/For_runner_implementors/index.html @@ -3,6 +3,6 @@ size:(unit -> int) -> num_tasks:(unit -> int) -> shutdown:(wait:bool -> unit -> unit) -> - run_async:(ls:Task_local_storage.storage -> task -> unit) -> + run_async:(ls:Task_local_storage.t -> task -> unit) -> unit -> t
Create a new runner.
NOTE: the runner should support DLA and Suspend_ on OCaml 5.x, so that Fork_join and other 5.x features work properly.
val k_cur_runner : t option ref Moonpool_private.Thread_local_storage_.keyKey that should be used by each runner to store itself in TLS on every thread it controls, so that tasks running on these threads can access the runner. This is necessary for get_current_runner to work.