2 * Copyright (c) 2015, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
12 (*****************************************************************************)
13 (* Module building workers.
14 * A worker is a subprocess executing an arbitrary function.
15 * You should first create a fixed amount of workers and then use those
16 * because the amount of workers is limited and to make the load-balancing
17 * of tasks better (cf multiWorker.ml).
19 (*****************************************************************************)
24 (* Worker killed by Out Of Memory. *)
26 | Worker_quit
of Unix.process_status
27 exception Worker_failed
of (process_id
* worker_failure
)
28 (** Raise this exception when sending work to a worker that is already busy.
29 * We should never be doing that, and this is an assertion error. *)
32 val failure_to_string
: worker_failure
-> string
34 type send_job_failure
=
35 | Worker_already_exited
of Unix.process_status
36 | Other_send_job_failure
of exn
38 exception Worker_failed_to_send_job
of send_job_failure
40 (* The type of a worker visible to the outside world *)
42 (*****************************************************************************)
43 (* The handle is what we get back when we start a job. It's a "future"
44 * (sometimes called a "promise"). The scheduler uses the handle to retrieve
45 * the result of the job when the task is done (cf multiWorker.ml).
47 (*****************************************************************************)
51 (* Get the worker's id *)
52 val worker_id
: worker
-> worker_id
53 (* Has the worker been killed *)
54 val is_killed
: worker
-> bool
55 (* Mark the worker as busy. Throw if it is already busy *)
56 val mark_busy
: worker
-> unit
57 (* If the worker is busy, what is it doing. Note that calling this is not
58 * type safe: 'a and 'b are free type variables, and they depend on what is the
59 * job being executed by worker. *)
60 val get_handle_UNSAFE
: worker
-> ('a
, 'b
) handle
option
61 (* Mark the worker as free *)
62 val mark_free
: worker
-> unit
63 (* If the worker isn't prespawned, spawn the worker *)
64 val spawn
: worker
-> (void
, Worker.request
) Daemon.handle
65 (* If the worker isn't prespawned, close the worker *)
66 val close
: worker
-> (void
, Worker.request
) Daemon.handle
-> unit
67 (* If there is a call_wrapper, apply it and create the Request *)
68 val wrap_request
: worker
-> ('x
-> 'b
) -> 'x
-> Worker.request
70 type call_wrapper
= { wrap
: 'x 'b
. ('x
-> 'b
) -> 'x
-> 'b
}
73 val register_entry_point
:
74 restore
:('a
-> unit) -> 'a entry
76 (* Creates a pool of workers. *)
78 (** See docs in WorkerController.worker for call_wrapper. *)
79 ?call_wrapper
: call_wrapper
->
83 gc_control
: Gc.control
->
84 heap_handle
: SharedMem.handle
->
87 (* Call in a sub-process (CAREFUL, GLOBALS ARE COPIED) *)
88 val call
: ?call_id
:int -> worker
-> ('a
-> 'b
) -> 'a
-> ('a
, 'b
) handle
90 (* See MultiThreadedCall.call_id *)
91 val get_call_id
: ('a
, 'b
) handle
-> int
93 (* Retrieves the job that the worker is currently processing *)
94 val get_job
: ('a
, 'b
) handle
-> 'a
96 (* Retrieves the result (once the worker is done) hangs otherwise *)
97 val get_result
: ('a
, 'b
) handle
-> 'b
99 (* Selects among multiple handles those which are ready. *)
100 type ('a
, 'b
) selected
= {
101 readys
: ('a
, 'b
) handle list
;
102 waiters
: ('a
, 'b
) handle list
;
103 (* Additional (non worker) ready fds that we selected on. *)
104 ready_fds
: Unix.file_descr list
;
106 val select
: ('a
, 'b
) handle list
-> Unix.file_descr list
-> ('a
, 'b
) selected
108 (* Returns the worker which produces this handle *)
109 val get_worker
: ('a
, 'b
) handle
-> worker
111 (* Killall the workers *)
112 val killall
: unit -> unit
114 val cancel
: ('a
, 'b
) handle list
-> unit