-
Notifications
You must be signed in to change notification settings - Fork 125
/
resourceTracker.mli
186 lines (142 loc) · 6.72 KB
/
resourceTracker.mli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
(*
Copyright © 2011 MLstate
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.
You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
(**
Module to track resources and to collect them if needed
@author Hugo Heuzard
*)
(**
This module provides functions to
- create resources
- connect resources to each other
- kill, call resources
- collect resources
*)
(** {6 Types definitions} *)
(** Type of resource parameterized by the type of message it can reveive and
by the type of result it will answer.*)
type ('message,'result) t
(** Type of black resource. Same as resource with hidden type's parameters. Its
only purpose is to be able to store different kind of resource in the same
structure (list, table). You should only deal with this type when you need
to give resource dependencies (a list of black resources). *)
type b
(** Type of signal. A resource can be remove with one of the following signal *)
type signal =
[ `Expired (** The resource has expired. *)
| `Killed (** The resource has been forced to close. *)
| `Closed (** The resource has been closed properly. *)
| `Collected (** The resource has been collected by caml garbage collector *)
]
(** Type of resource handler parameterized by the type of message, the type of
result and the type of the internal state *)
type ('message,'result,'state) h
(** [black resource] hide type's parameters from a ('message,'result) resource *)
external black : (_,_) t -> b = "%identity"
(** Exception raised when trying to do operation on an already removed resource *)
exception Not_Alive
(** Exception raised when trying to do synchore operation with asynchrone resource *)
exception Async_Call
module type M = sig
(** Module expire provide helpers to set the expiration of the resource *)
module Expire : sig
type 'a t = 'a state -> signal option * Time.t option
(** Type of expiration context *)
and context =
[ `Date of Time.t
| `Timeout of Time.t
| `Limit of int
| `And of context list
| `Or of context list ]
and 'a state =
{
mutable limit: int;
mutable last_use: Time.t;
mutable cancel: Scheduler.async_key option;
mutable state: 'a;
}
val init : 'a -> 'a state
(** [make context] make a value of type 'a t. Use this with handler_timer *)
val make : context -> 'a t
end
(** {6 Creations} *)
(** [handler name kill_fun expire_fun on_message_fun decide_fun] Make a resource
handler.
[name] is the kind of resource created with this handler (ie: Cookie, Ping)
[kill_fun] is called in order to remove the ressource. It take the current
internal state of the resource and the signal it has been removed with
[expire_fun] is called to know if the resource has expired. When expired,
it should return [Some `Expired]
[on_message_fun] is call when you send a message to the resource. It takes
as arguments the resource itself, the current internal state and a
message. It returns the new state and the result.
[decide_fun] is call when a resource you depend on (a parent resource) is removed. It allows
to decide what to do (remove the resource aswell, ignore it, ...). It
takes as arguments the resource itself, the current internal state and the
signal the parent resource has been removed with. *)
val handler :
string ->
( 'state -> signal -> unit ) ->
( 'state -> signal option ) ->
(('message,'result) t -> 'state -> 'message -> 'state*'result ) ->
(('message,'result) t -> 'state -> signal -> unit) ->
('message,'result,'state) h
(** Same as handler with asynchrone function (taking continuation as last arguments) *)
val handler_cps :
string ->
( 'state -> signal -> (unit -> unit) -> unit ) ->
( 'state -> (signal option -> unit ) -> unit ) ->
(('message,'result) t -> 'state -> 'message -> ( ('state*'result) -> unit ) -> unit ) ->
(('message,'result) t -> 'state -> signal -> (unit -> unit) -> unit) ->
('message,'result,'state) h
(** Same as handler except that you have to create the expire_fun with
[Expire.create]. It helps you the create resource with temporal expiration.
*)
val handler_timer :
string ->
('state -> signal -> unit) ->
('state Expire.t) ->
(('message,'result) t -> 'state -> 'message -> 'state * 'result) ->
(('message, 'result) t -> 'state -> signal -> unit) ->
('message, 'result, 'state Expire.state) h
(** [resource handler state ~depends:lst ()] Make a resource from an handler,
the initial state of the resource and the resource it depends on.
*)
val resource : ('message,'result,'state) h -> 'state -> ?depends: b list -> unit -> ('message,'result) t
(** Same as resource but has to be used with handler created by handler_timer
*)
val resource_timer : ('m,'r,'s Expire.state) h -> 's -> ?depends: b list -> unit -> ('m,'r)t
(** {6 Operations on resources}*)
(** [expire resource] return whether or not the resource has expired *)
val expire : (_,_)t -> signal option
(** Same has expire but has to be used when dealing with asynchone resource *)
val expire_cps : (_,_)t -> ?err_cont:(exn -> unit) -> (signal option -> unit) -> unit
(** [call resource message] send a message to the resource, change its internal
state and return a result *)
val call : ('m,'r)t -> 'm -> 'r
(** Same as call but has to be used when dealing with asynchrone resource *)
val call_cps : ('m,'r)t -> 'm -> ?err_cont:(exn -> unit) -> ('r -> unit) -> unit
(** [kill resource signal] remove the resource with the signal *)
val kill : (_,_)t -> signal -> unit
(** [alive resource] return true if the resource has not been already remove *)
val alive : (_,_)t -> bool
(** [collect ()] goes throw all resources, checks their expiration and remove
the expired one *)
val collect : unit -> unit
(** [register resource f] register a callback to the resource. This callback
will be called when the resource will be removed *)
val register : (_,_)t -> (signal -> unit) -> unit
(** Same as register but has to be used when the function is asynchrone *)
val register_cps : (_,_)t -> (signal -> unit) -> unit
end
module Default : M