FiberParallel asynchronous function calls.
Read the short concurrency model.
module Id : sig ... endFiber unique identifiers.
async f is a fiber executing function f in parallel to the caller. The caller scope will not return or raise before f returns or raises. priority is the execution priority, it defaults to the caller's priority. If only_main is true, the scheduler ensure that the function only gets excecuted on the main thread (defaults to false).
val from_val : 'a -> 'a tfrom_val v is async (Fun.const v).
Note. Awaiting on fibers can always raise. If you want to guard against this, use the trapping combinators before awaiting them.
val await : 'a t -> 'aawait f blocks until the asynchronous function of f returns or raises.
val await_all : 'a t list -> 'a listawait_all fs blocks until all fs return or raise. Raises the leftmost exception if one of the fiber raises (including Cancelled).
await_first fs awaits the first, leftmost, fs that returns or raises (including Cancelled). The returned list (if any) is fs, in the same order, without the fiber that returned. Raises Invalid_argument if the list is empty.
await_either f0 f1 awaits the first, leftmost, fiber that returns or raises (including Cancelled).
val poll : 'a t -> 'a optionpoll f is None if f is still running and it's return value or raise otherwise.
Picking is for selecting among competing computations.
val pick_first : 'a t list -> 'aval cancel : 'a t -> unitcancel f marks the fiber f and its current and future asynchronous function calls as being cancelled. If f already returned this has no effect.
self_is_cancelled () is true if the excecuting fiber is cancelled.
self_check_cancellation raises Cancelled if self_is_cancelled () is true.
A few conveniences to protect from raising fibers. Avoids multiplying the number of await functions.
trap_user_exn f is f but turns any exception except Cancelled, Stack_overflow, Out_of_memory or Sys.Break into Error _.
trap_cancelled f is f but turns a Cancelled exception into an option.
trap_any_exn is f but turns a Cancelled exception into None and any other exception except Stack_overflow, Out_of_memory, Sys.Break, into Error _.
val cancelled : 'a t -> boolcancelled f is true iff f is marked as cancelled.
module Handle : sig ... endExistential fibers
block ~block ~cancel ~return blocks the calling fiber (hereafter f) on a blocking operation. The given functions are used as follows:
block f is immediately invoked by the scheduler. This should register the blocking operation with an external entity reponsible for unblocking it when the operation result is available. If block f raises, the exception is directly thrown into the fiber f and not blocked.cancel f is invoked in case f gets cancelled while blocked on the operation. If true is returned the scheduler unblocks f and throws Cancelled into f. If false is returned the operation remains blocked and return f will be called once it is unblocked. If cancel f raises the scheduler unblocks f and throws the exception into f.return f is called to get the operation's value once it no longer blocks. This value is used to continue f. If return f raises the exception is thrown into f.Take into account the following points:
Handle.t does not even provide that).Cancelled if their cancel function is called. Either by returning true or by raising in return (Warning, if cancelled f is true in return it does not mean that cancel was called, it could have been blocked while being already cancelled).block is guaranteed to be called by the domain executing the block. Other function may be called by other domains.block is always called. If cancel is called and returns true or raises, return is never called.Note that nothing will ever unblock unless you provide an adequate unblock function to main.
self_non_cancelling_blocks f ensures in f () that blocking operations of the executing fiber do not get notified of cancellation if it gets cancelled (in other words, cancel functions of blocks invoked by f never get called).
Important. Unlike cancel and self_cancel which propagate to the asynchronous calls of a fiber. This does not. Making blocks non-cancelling may be paramount to a fiber's correctness, so it has to remain in control of it.
type unblock = poll:bool -> Handle.t optionThe type for functions to unblock blocked fibers. These functions need to be given to main.
An unblock function is called by the scheduler as follows:
unblock ~poll:true, the function should return a previously blocked fiber that no longer blocks, if any. The call must not block if there is no such fiber as there are other fibers that are willing to run.unblock ~poll:false, the function must return a peviously blocked fiber that no longer blocks. If there is none, it can block for as long as it wishes as there are no fiber to run. If it returns None it will be called again, which amounts to busy waiting.The function must not raise. If it does the exception is trapped and None is returned.
val never_unblock : unblocknever_unblock nevers unblocks anything. Only use this if you are philosophizing.
unblocks us composes us by calling them one after the other in circular order for fairness. FIXME. That doesn't work for poll:false. See todo.
val main : ?domains:int -> unblock:unblock -> (unit -> 'a) -> 'amain f creates a top level fiber with f and runs it to completion.
unblock is the function called by the scheduler to unblock. If you are never blocking but only awaiting you can use unblock_none.domains is the number of domains to use. Defaults to to the value specified in the environment variable AFFECT_DOMAIN_COUNT or if unparseable to Domain.recommended_domain_count.Just interpose main on your main function as follows:
let main () =
Fiber.main ~unblock:Funix.unblock @@ fun () ->
…
let () = if !Sys.interactive then () else exit (main ())val pp : Stdlib.Format.formatter -> 'a t -> unitpp ppf f formats the fiber status f for inspection.
val pp' :
(Stdlib.Format.formatter -> 'a -> unit) ->
Stdlib.Format.formatter ->
'a t ->
unitpp' pp_v is like pp but uses pp_v to format the value if available.
val pp_id : Stdlib.Format.formatter -> 'a t -> unitpp_id ppf f formats a short identifying header for f
val pp_value :
(Stdlib.Format.formatter -> 'a -> unit) ->
Stdlib.Format.formatter ->
'a t ->
unitpp_value pp_v f formats the fiber value of f or a placeholder if its still running.
module Private : sig ... endFor devising your own scheduler.
There is no distinction between concurrency and parallelism. Fibers represent asynchronous function calls that execute in parallel to a calling function. We use the terms fiber and asynchronous function call interchangeably.
The model is as follow:
async it does not return or raise before all these subcalls return or raise.await which waits for an asynchronous function call to return or raise. Other than that, libraries provide suitable direct-style blocking functions that call block underneath and an associated function to unblock them that you specify for running your main function.cancel or self_cancel.Cancelled.Cancelled.See also the design notes.