Pools dispatch computations among registered agents, re-issuing pending
tasks if agents do not send computation outcomes.
Given a pool p, returned by create ():
p.register w is used by agents to indicate that they can perform
computations, mapping xi values to yi results, using the
synchronous channel w.
p.fold c comb y0 returns the combined result
comb y1 (comb y2 (... (comb yn y0))),
where the yi values are the results of the xi
transformed by the functions
registered by the agents. The xi result from enumerating the collection
c. The enumeration technique is specified by the module argument E
(signature JoinPool.Shared.Enumerable)
to the functor JoinPool.Shared.Make.
p.register_interruptible (w,k) is used by agents to indicate that
they can perform computations as above.
Additionally the pool logics will attempt to abort computations
found to be useless by issusing messages on channel k.
More specifically, when
given an argument (id,xi) by the pool logics,
the synchronous channel w should return Some yi,
where xi and yi are the same as in the description of p.fold above.
However, if the pool sends id on channel k before yi is
available, then the agent may abort the computation of yi,
so as to spare computing power.
In that case, w(xi) must reply None.
It is the agent responsability to check that subtask identifiers
sent on the w and k channels
are equal before aborting the subtask and having w to reply None