Values built on first use, safely from several domains

README.md

once #

Values built on first use, safely from several domains.

A library that declares an expensive constant at the top level (a parsed table, a compiled codec, a checked state machine) builds it when the program starts, so every program that links the library pays for it, including one that never uses it. Deferring the construction with Stdlib.Lazy is unsafe under OCaml 5: Lazy.force raises Lazy.Undefined in a domain that forces a suspension while another domain is forcing it, which is exactly what happens when a server's first requests arrive on several domains at once.

Once.v build is a cell that calls build on first use. Callers that find the cell empty at the same time each build a value and offer it with one Atomic.compare_and_set; the first offer is published and every caller returns it. No caller blocks and none raises because another is building. A race costs a duplicate build in each caller that took part in it, once per cell, so build must be pure.

Install #

opam install once

Usage #

A cell is declared at the top level and read where the value is needed:

# let squares = Once.v (fun () -> Array.init 256 (fun i -> i * i));;
val squares : int array Once.t = <abstr>
# let square i = (Once.get squares).(i);;
val square : int -> int = <fun>
# square 12;;
- : int = 144

Licence #

ISC.