Module B000.Op

Build operations.

This module provides a type for specifying operations and their result. Operation execution and caching are respectively handled by the Exec and Reviver modules.

Operation status

type failure =
| Exec of string option

Execution failure with a potential error msg.

| Missing_writes of B0_std.Fpath.t list

Write specification failure.

| Missing_reads of B0_std.Fpath.t list

Read synchronisation failure.

The type for operation failures.

type status =
| Aborted

Aborted due to prerequisite failure.

| Done

Executed successfully.

| Failed of failure

Executed unsuccessfully.

| Waiting

Waiting for execution.

The type for operation statuses.

Operations

type id = int

The type for build operation identifiers.

type group = string

The type for build operation groups.

type t

The type for build operations.

type op = t

Again.

module Copy : sig ... end

File copy.

module Delete : sig ... end

Path deletion.

module Mkdir : sig ... end

Directory creation.

module Notify : sig ... end

End-user notifications.

module Read : sig ... end

File reads.

module Spawn : sig ... end

Tool spawns.

module Wait_files : sig ... end

Waiting on files.

module Write : sig ... end

File writes.

type kind =
| Copy of Copy.t
| Delete of Delete.t
| Mkdir of Mkdir.t
| Notify of Notify.t
| Read of Read.t
| Spawn of Spawn.t
| Wait_files of Wait_files.t
| Write of Write.t

The type for operation kinds.

val kind_name : kind -> string

kind_name k is an end user name for kind k.

val v : id -> group:group -> time_created:B0_std.Time.span -> time_started:B0_std.Time.span -> duration:B0_std.Time.span -> revived:bool -> status:status -> reads:(B0_std.Fpath.t list * B0_std.Fpath.t list) -> writes:(B0_std.Fpath.t list * B0_std.Fpath.t list) -> hash:B0_std.Hash.t -> ?⁠post_exec:(op -> unit) -> ?⁠k:(op -> unit) -> kind -> t

v constructs an operation. See the corresponding accessors for the semantics of various arguments.

val kind : t -> kind

kind o is o's kind.

val equal : t -> t -> bool

equal o0 o1 is id o0 = id o1.

val compare : t -> t -> int

compare o0 o1 is compare (id o0) (id o1).

val id : t -> id

id o is the identifier of operation o.

val group : t -> string

group o is the group of o.

val time_created : t -> B0_std.Time.span

time_created o is o's creation time.

val time_started : t -> B0_std.Time.span

time_started o is o's execution start time. This is different from B0_std.Time.Span.max once the operation has been submitted for execution.

val time_ended : t -> B0_std.Time.span

exec_end_time o is o's execution end time. This is different from B0_std.Time.Span.max once the operation has been completed and collected.

val waited : t -> B0_std.Time.span

waited is o's waiting time between creation and execution.

val duration : t -> B0_std.Time.span

duration is o's execution duration time.

val revived : t -> bool

revived o is true iff o was revived from a cache. Only relevant if hash is not Hash.nil.

val status : t -> status

status o is o execution status.

val reads : t -> B0_std.Fpath.t list * B0_std.Fpath.t list

reads o are the file paths read by the operation. Paths on the left are those that need to be ready. Those on the right must exist but may not be ready as far as the Guard is concerned.

val reads_to_list : t -> B0_std.Fpath.t list

reads_to_list o concatenates reads o.

val writes : t -> B0_std.Fpath.t list * B0_std.Fpath.t list

writes o are the file paths written by o. Paths on the left are path that are made ready. Those on the right must also be written but they are not made ready in the Guard.

val writes_to_list : t -> B0_std.Fpath.t list

writes_to_list o concatenates writes o.

val hash : t -> B0_std.Hash.t

hash o is the operation's hash. This is Hash.nil before the operation hash has been effectively computed and set via set_hash. This remains Hash.nil for operations that are not revivable.

Updating the build operation

val invoke_k : t -> unit

exec_k o () invokes and discards o's continuation. Note that this does not protect against the continuation raising.

val discard_k : t -> unit

discard o discards o's continuation.

val invoke_post_exec : t -> unit

exec_post_exec o invokes and discards o's post execution hook. This hook called is right after the operation execution and, if applicable, before reviver recording. It is always called even if the operation fails or is revived (use status and revived to check these conditions). Note that if the hook unexpectedly raises this turns o in to a failure.

val discard_post_exec : t -> unit

discard_post_exec o discards o's post execution hook.

val abort : t -> unit

abort o sets the status of o to Op.status.Aborted and discards the operation closures (including kind specific ones).

val set_time_started : t -> B0_std.Time.span -> unit

set_time_started o t sets o's execution start time to t.

val set_time_ended : t -> B0_std.Time.span -> unit

set_time_ended o t sets o's execution end time to s.

val set_revived : t -> bool -> unit

set_revived o b sets o's cache revival status to b.

val set_status : t -> status -> unit

set_status o s sets the execution status to s.

val set_status_from_result : t -> ('a, string) Stdlib.result -> unit

set_status_from_result o r sets status of operation o to Executed if r is Ok _ and Failed (Exec e) if r is Error e.

val set_reads : t -> (B0_std.Fpath.t list * B0_std.Fpath.t list) -> unit

set_reads t fs sets the file paths read by o to fs. Note that this resets the hash.

val set_writes : t -> (B0_std.Fpath.t list * B0_std.Fpath.t list) -> unit

set_writes t fs sets the file paths written by o to fs.

val set_hash : t -> B0_std.Hash.t -> unit

set_hash o h sets the operation hash to h.

Operation sets and map

module Set : Stdlib.Set.S with type Set.elt = t

Operation sets

module Map : Stdlib.Map.S with type Map.key = t

Operation maps

Analyzing operations

val did_not_write : t -> B0_std.Fpath.t list

did_not_write o compares writes with the current state of the file system and reports those files that do not exist.

val cannot_read : t -> B0_std.Fpath.t list

cannot_read o compares reads with the current state of the file system and reports those files that cannot be read.

val unwritten_reads : t list -> B0_std.Fpath.Set.t

unwritten_reads os are the file read by os that are not written by those.

val ready_read_write_maps : t list -> Set.t B0_std.Fpath.Map.t * Set.t B0_std.Fpath.Map.t

ready_read_write_maps ops is reads, writes with reads mapping file paths to operations that reads them and writes mapping file paths to operations that write them. Unready reads and writes are excluded for these maps.

val ready_write_map : t list -> Set.t B0_std.Fpath.Map.t

ready_write_map os is snd (read_write_maps os). If one of the operation sets in the map is not a singleton the operations should likely not be run toghether.

val find_ready_read_write_cycle : t list -> t list option

find_ready_read_write_cycle os is Some cs if there exists a ready read/write cycle among the operations os. This means each each element of cs ready writes a file ready read by its successor in the list with the successor of the last element being the first.

type aggregate_error =
| Failures

Some operations failed.

| Cycle of t list

Dependency cycle.

| Never_became_ready of B0_std.Fpath.Set.t

Some files never became ready.

The type for errors related to a list of operations. This is:

  • Failures, if there is one or more operations in the list that Failed (and hence for a B00.Memo also if a fiber failed, see here).
  • Cycle ops, if there is a set of Waiting operations in the list whose individual reads and writes leads to a dependency cycle. See also find_read_write_cycle.
  • Never_became_ready fs, with fs files that are in the reads of Waiting operations but are written by no operation from the list.

Note that formally more than one of these conditions can be true at the same time. But Never_became_ready is only reported once the first two kind of errors have been ruled out. The reason is that those files that never became ready may be created by continuations of the failed or cyclic operations and reporting them would not lead the user to focus on the right cause.

val find_aggregate_error : t list -> (unit, aggregate_error) Stdlib.result

find_aggregate_error os finds an aggregate error among the list of operation os. This is Ok () if all operations os Executed.