Skip to content

Commit

Permalink
feat(Mutex): add register_printer (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
favonia authored Sep 24, 2023
1 parent f3ef7fc commit 9bb4788
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/Mutex.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sig

val exclusively : (unit -> 'a) -> 'a
val run : (unit -> 'a) -> 'a

val register_printer : ([`Exclusively] -> string option) -> unit
end

module Make () =
Expand All @@ -22,10 +24,16 @@ struct
raise Locked
else begin
S.set true;
(* Favonia: I learn from the developers of eio that Fun.protect is not good at
preserving the backtraces. See https://github.com/ocaml-multicore/eio/pull/209. *)
match f () with
| ans -> S.set false; ans
| exception e -> S.set false; raise e
end

let run f = S.run ~init:false f

let register_printer f = S.register_printer @@ fun _ -> f `Exclusively

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Mutex.run"
end
8 changes: 8 additions & 0 deletions src/Mutex.mli
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ sig
(** [run f] executes the thunk [f] which may perform mutex effects.
Each call of [run] creates a fresh mutex; in particular, calling [run] inside
the thunk [f] will start a new scope that does not interfere with the outer scope. *)

val register_printer : ([`Exclusively] -> string option) -> unit
(** [register_printer p] registers a printer [p] via {!val:Printexc.register_printer} to convert unhandled internal effects into strings for the OCaml runtime system to display. Ideally, all internal effects should have been handled by {!val:run} and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor {!module:Modifier.Make} always registers a simple printer to suggest using {!val:run}, but you can register new ones to override it. The return type of the printer [p] should return [Some s] where [s] is the resulting string, or [None] if it chooses not to convert a particular effect. The registered printers are tried in reverse order until one of them returns [Some s] for some [s]; that is, the last registered printer is tried first. Note that this function is a wrapper of {!val:Printexc.register_printer} and all the registered printers (via this function or {!val:Printexc.register_printer}) are put into the same list.
The input type of the printer [p] is a variant representing internal effects used in this module. It corresponds to all the effects trigger by {!val:exclusively}.
@since 1.1.0
*)
end

module Make () : S
Expand Down
2 changes: 2 additions & 0 deletions src/Reader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ struct
let register_printer f = Printexc.register_printer @@ function
| Effect.Unhandled Read -> f `Read
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Reader.run"
end
2 changes: 1 addition & 1 deletion src/Reader.mli
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ sig
The input type of the printer [p] is a variant representation of the only internal effect used in this module. It corresponds to the effect trigger by {!val:read}.
@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/Sequencer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ struct
let register_printer f = Printexc.register_printer @@ function
| Effect.Unhandled (Yield elt) -> f (`Yield elt)
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.Sequencer.run"
end
2 changes: 1 addition & 1 deletion src/Sequencer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ sig
The input type of the printer [p] is a variant representation of the internal effects used in this module. They correspond to the effects trigger by {!val:yield}. More precisely, [`Yield elt] corresponds to the effect triggered by [yield elt].
@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/State.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ struct
| Effect.Unhandled Get -> f `Get
| Effect.Unhandled (Set state) -> f (`Set state)
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.State.run"
end
2 changes: 1 addition & 1 deletion src/State.mli
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ sig
- [`Get] corresponds to the effect triggered by [get ()].
- [`Set state] corresponds to the effect triggered by [set state].
@since 1.0.0
@since 1.1.0
*)
end

Expand Down
2 changes: 2 additions & 0 deletions src/UniqueID.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ struct
| Effect.Unhandled (Retrieve id) -> f (`Retrieve id)
| Effect.Unhandled Export -> f `Export
| _ -> None

let () = register_printer @@ fun _ -> Some "Unhandled algaeff effect; use Algaeff.UniqueID.run"
end
2 changes: 1 addition & 1 deletion src/UniqueID.mli
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sig
- [`Retrieve id] corresponds to the effect triggered by [retrieve id].
- [`Export] corresponds to the effect triggered by [export ()].
@since 1.0.0
@since 1.1.0
*)
end

Expand Down
4 changes: 4 additions & 0 deletions src/Unmonad.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ struct
; exnc = raise
; effc = function Monadic m -> Option.some @@ fun k -> M.bind m (Effect.Deep.continue k) | _ -> None
}

let () = Printexc.register_printer @@ function
| Effect.Unhandled (Monadic _) -> Some "Unhandled algaeff effect; use Algaeff.Unmonad.run"
| _ -> None
end
5 changes: 3 additions & 2 deletions src/Unmonad.mli
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
(** Effects for any monad (subject to OCaml continuations being one-shot). *)

(** This is a general construction that uses effects to construct monadic expressions.
Here is an alternative implementation of {!module:State} using
the standard state monad:
Here is an alternative implementation of {!module:State} using the standard state monad:
{[
module StateMonad =
Expand Down Expand Up @@ -33,6 +32,8 @@
raise an exception unless it encounters a truly unrecoverable fatal error. Raising an exception
within [bind] will skip the continuation, and thus potentially skipping exception handlers
within the continuation. Those handlers might be crucial for properly releasing acquired resources.
PS: We are not aware of any actual use of this module, but we decided to keep it anyway.
*)

module type Monad =
Expand Down

0 comments on commit 9bb4788

Please sign in to comment.