feat: add Moonpool_fib.main

this is a convenient entrypoint for programs that use fibers. The main
thread can thus await fibers that run in the background.
This commit is contained in:
Simon Cruanes 2024-03-04 15:48:45 -05:00
parent 9df848cd17
commit 48fbf876dc
3 changed files with 44 additions and 0 deletions

16
src/fib/main.ml Normal file
View file

@ -0,0 +1,16 @@
exception Oh_no of Exn_bt.t
let main (f : Runner.t -> 'a) : 'a =
let st = Fifo_pool.Private_.create_state ~threads:[| Thread.self () |] () in
let runner = Fifo_pool.Private_.runner_of_state st in
try
let fiber = Fiber.spawn_top ~on:runner (fun () -> f runner) in
Fiber.on_result fiber (fun _ -> Runner.shutdown_without_waiting runner);
(* run the main thread *)
Fifo_pool.Private_.run_thread st runner ~on_exn:(fun e bt ->
raise (Oh_no (Exn_bt.make e bt)));
match Fiber.peek fiber with
| Some (Ok x) -> x
| Some (Error ebt) -> Exn_bt.raise ebt
| None -> assert false
with Oh_no ebt -> Exn_bt.raise ebt

25
src/fib/main.mli Normal file
View file

@ -0,0 +1,25 @@
(** Main thread.
This is evolved from [Moonpool.Immediate_runner], but unlike it,
this API assumes you run it in a thread (possibly
the main thread) which will block until the initial computation is done.
This means it's reasonable to use [Main.main (fun () -> do_everything)]
at the beginning of the program.
Other Moonpool pools can be created for background tasks, etc. to do the
heavy lifting, and the main thread (inside this immediate runner) can coordinate
tasks via [Fiber.await].
Aside from the fact that this blocks the caller thread, it is fairly similar to
{!Background_thread} in that there's a single worker to process
tasks/fibers.
This handles effects, including the ones in {!Fiber}.
@since NEXT_RELEASE
*)
val main : (Moonpool.Runner.t -> 'a) -> 'a
(** [main f] runs [f()] in a scope that handles effects, including {!Fiber.await}.
This scope can run background tasks as well, in a cooperative fashion. *)

View file

@ -3,4 +3,7 @@
module Fiber = Fiber module Fiber = Fiber
module Fls = Fls module Fls = Fls
module Handle = Handle module Handle = Handle
module Main = Main
include Fiber include Fiber
let main = Main.main