Library
Module
Module type
Parameter
Class
Class type
La propriété, c'est le vol!
Beyond the capitalist idea (even if certain libertarians would qualify the notion of private property), it is often useful to associate resources with the execution of a task in order to free them as soon as the said task is completed (abnormally or not).
Miou offers such a mechanism where the user can associate a resource 'a
with a promise (with own
). When the task associated with this promise is terminated, Miou will check that all the resources have been released (using disown
). If this is not the case, Miou will call the "finaliser" specified by the user and fail with an "uncatchable" exception: Resource_leak
.
Note that the user must release these resources and disown
. In fact, disown
does not call the finaliser (which is only executed in an abnormal situation: when the task has raised an exception or when a resource has not been released).
val own : finally:('a -> unit) -> 'a -> t
own ~finally value
associates the value and this finaliser with the current promise. This way, if the current promise fails abnormally, the finally function will be called.
# let show () = print_endline "Resource released"
# Miou.run @@ fun () ->
let p = Miou.call_cc @@ fun () ->
let _ = Miou.Ownership.own ~finally:show () in
failwith "p" in
await_exn p ;;
Resource released!
Exception: Failure "p".
NOTE: Finaliser can not perform OCaml's effects. This is because it is not "ordered" like a usual task. Using Miou functions (such as await
or cancel
) in the finaliser will raise an exception: Effect.Unhandled
.
It is also important to note that if a task finishes abnormally, as well as freeing up the resources of that task, the resources owned by the children will also be freed up (hence the uselessness of using await or cancel).
val disown : t -> unit
disown t
informs Miou that you have properly released the resource. If the current promise ends well and the user has not disown
the resource, Miou raises the uncatchable exception: Resource_leak
# let show () = print_endline "Resource released" ;;
# Miou.run @@ fun () ->
let p = Miou.call_cc @@ fun () ->
let _ = Miou.Ownership.own ~finally:show () in
() in
await_exn p ;;
Resource released!
Exception: Miou.Resource_leak.
Note that even in this situation, Miou calls the finaliser.
val transfer : t -> unit
transfer t
transfers the ownership to the parent. This can be interesting when the resource is locked into a small promise in conjunction with others and the parent will make real use of it such as:
# exception Timeout
# Miou.await_one
[ Miou.call_cc (fun () ->
let socket = tcpv4 () in
Miou_unix.connect socket addr;
Ownership.transfer socket;
socket)
; Miou.call @@ fun () ->
Miou_unix.sleep 10.; raise Timeout ]
|> function
| Ok socket_connected -> ...
| Error Timeout -> ...