Module B00.Memo

module Memo: sig .. end

Build memoizer.

A memoizer ties together and environment, an operation cache, a guard and an executor.


type feedback = [ `Fiber_exn of exn * Stdlib.Printexc.raw_backtrace
| `Fiber_fail of string
| `Miss_tool of B00.Tool.t * string
| `Op_cache_error of B00.Op.t * string
| `Op_complete of B00.Op.t * [ `Did_not_write of B0_std.Fpath.t list ] ]

The type for memoizer feedback.

val pp_feedback : feedback B0_std.Fmt.t

pp_feedback ppf formats feedback.

type t 

The type for memoizers. This ties together an environment, a aguard, an operation cache and an executor.

val create : ?clock:B0_std.Time.counter ->
?cpu_clock:B0_std.Time.cpu_counter ->
feedback:(feedback -> unit) ->
cwd:B0_std.Fpath.t ->
B00.Env.t -> B00.Guard.t -> B00.Op_cache.t -> B00.Exec.t -> t
val memo : ?hash_fun:(module B0_std.Hash.T) ->
?env:B0_std.Os.Env.t ->
?cwd:B0_std.Fpath.t ->
?cachedir:B0_std.Fpath.t ->
?max_spawn:int ->
?feedback:([ `Exec_submit of option * B00.Op.t
| `Fiber_exn of exn * Stdlib.Printexc.raw_backtrace
| `Fiber_fail of string
| `File_cache_need_copy of B0_std.Fpath.t
| `Miss_tool of B00.Tool.t * string
| `Op_cache_error of B00.Op.t * string
| `Op_complete of
B00.Op.t * [ `Did_not_write of B0_std.Fpath.t list ] ] ->
unit) ->
unit -> (t, string) Stdlib.result

memo is a simpler B00.Memo.create

val clock : t -> B0_std.Time.counter

clock m is m's clock.

val cpu_clock : t -> B0_std.Time.cpu_counter

cpu_clock m is m's cpu clock.

val env : t -> B00.Env.t

env m is m's environment.

val op_cache : t -> B00.Op_cache.t

op_cache m is m's operation cache.

val guard : t -> B00.Guard.t

guard m is m's guard.

val exec : t -> B00.Exec.t

exec m is m's executors.

val hash_fun : t -> (module B0_std.Hash.T)

hash_fun m is m's hash function.

val stir : block:bool -> t -> unit

stir ~block m runs the memoizer a bit. If block is true blocks until the memoizer is stuck with no operation to perform.

val finish : t -> (unit, B0_std.Fpath.Set.t) Stdlib.result

finish m finishes the memoizer. This blocks until there are no operation to execute like B00.Memo.stir does. If no operations are left waiting this returns Ok (). If there are remaining wiating operations it aborts them and returns Error fs with fs the files that never became ready and where not supposed to be written by the waiting operations.

val ops : t -> B00.Op.t list

ops m is the list of operations that were submitted to the memoizer


type 'a fiber = ('a -> unit) -> unit 

The type for memoizer operation fibers.

val fail : ('b, Stdlib.Format.formatter, unit, 'a) Stdlib.format4 -> 'b

fail fmt ... fails the fiber with the given error message.

val fail_error : ('a, string) Stdlib.result -> 'a

fail_error fails the fiber with the given error.

Files and directories

val file_ready : t -> B0_std.Fpath.t -> unit

ready m p declares path p to be ready, that is exists and is up-to-date in b. This is typically used with source files and files external to the build (e.g. installed libraries).

val wait_files : t -> B0_std.Fpath.t list -> unit fiber

wait_files m files k continues with k () when files become ready. FIXME Unclear whether we really want this though this is kind of a reads constraint for a pure OCaml operation, but then we got

val read : t -> B0_std.Fpath.t -> string fiber

read m file k reads the contents of file file as s when it becomes ready and continues with k s.

val write : t ->
?salt:string ->
?reads:B0_std.Fpath.t list ->
?mode:int ->
B0_std.Fpath.t -> (unit -> (string, string) Stdlib.result) -> unit

write m ~reads file w writes file with data w () and mode mode (defaults to 0o644) when reads are ready. w's result must only depend on reads and salt (defaults to "").

val mkdir : t -> B0_std.Fpath.t -> unit fiber

mkdir m dir k creates directory dir and continues with k () at which point file dir is ready.

Memoizing tool spawns

type tool 

The type for memoized tools.

type cmd 

The type for memoized tool invocations.

val tool : t -> B00.Tool.t -> B0_std.Cmd.t -> cmd

tool m t is tool t memoized. Use the resulting function to spawn the tool with the given arguments.

val spawn : t ->
?reads:B0_std.Fpath.t list ->
?writes:B0_std.Fpath.t list ->
?env:B0_std.Os.Env.t ->
?cwd:B0_std.Fpath.t ->
?stdin:B0_std.Fpath.t ->
?stdout:B00.Op.Spawn.stdo ->
?stderr:B00.Op.Spawn.stdo ->
?success_exits:B00.Op.Spawn.success_exits ->
?k:(int -> unit) -> cmd -> unit

spawn m ~reads ~writes ~env ~cwd ~stdin ~stdout ~stderr
      ~success_exits cmd
spawns cmd once reads files are ready and makes files writes ready if the spawn succeeds and the file exists. The rest of the arguments are:

TODO. More expressive power could by added by:

  1. Support to refine the read and write set after the operation returns.

Note. If the tool spawn acts on a sort of "main" file (e.g. a source file) it should be specified as the first element of reads, this is interpreted specially by certain build tracer.

Future values

module Fut: sig .. end

Future values.