<br><br><div class="gmail_quote">On Mon, Jul 12, 2010 at 09:15, Brian Granger <span dir="ltr">&lt;<a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On Fri, Jul 9, 2010 at 3:35 PM, MinRK &lt;<a href="mailto:benjaminrk@gmail.com">benjaminrk@gmail.com</a>&gt; wrote:<br>
&gt; Brian,<br>
&gt; Have you worked on the Heartbeat Device? Does that need to go in 0MQ itself,<br>
<br>
</div>I have not.  Ideally it could go into 0MQ itself.  But, in principle,<br>
we could do it in pyzmq.  We just have to write a nogil pure C<br>
function that uses the low-level C API to do the heartbeat.  Then we<br>
can just run that function in a thread with a &quot;with nogil&quot; block.<br>
Shouldn&#39;t be too bad, given how simple the heartbeat logic is.  The<br>
main thing we will have to think about is how to start/stop the<br>
heartbeat in a clean way.<br>
<div class="im"><br>
&gt; or can it be part of pyzmq?<br>
&gt; I&#39;m trying to work out how to really tell that an engine is down.<br>
&gt; Is the heartbeat to be in a separate process?<br>
<br>
</div>No, just a separate C/C++ thread that doesn&#39;t hold the GIL.<br>
<div class="im"><br>
&gt; Are we guaranteed that a zmq thread is responsive no matter what an engine<br>
&gt; process is doing? If that&#39;s the case, is a moderate timeout on recv adequate<br>
&gt; to determine engine failure?<br>
<br>
</div>Yes, I think we can assume this.  The only thing that would take the<br>
0mq thread down is something semi-fatal like a signal that doesn&#39;t get<br>
handled.  But as long as the 0MQ thread doesn&#39;t have any bugs, it<br>
should simply keep running no matter what the other thread does (OK,<br>
other than segfaulting)<br>
<div class="im"><br>
&gt; If zmq threads are guaranteed to be responsive, it seems like a simple pair<br>
&gt; socket might be good enough, rather than needing a new device. Or even<br>
&gt; through the registration XREP socket.<br>
<br>
</div>That (registration XREP socket) won&#39;t work unless we want to write all<br>
that logic in C.<br>
I don&#39;t know about a PAIR socket because of the need for multiple clients?<br></blockquote><div>I wasn&#39;t thinking of a single PAIR socket, but rather a pair for each engine. We already have a pair for each engine for the queue, but I am not quite seeing the need for a special device beyond a PAIR socket in the heartbeat.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br>
&gt; Can we formalize exactly what the heartbeat needs to be?<br>
<br>
</div>OK, let&#39;s think.  The engine needs to connect, the controller bind.<br>
It would be nice if the controller didn&#39;t need a separate heartbeat<br>
socket for each engine, but I guess we need the ability to track which<br>
specific engine is heartbeating.   Also, there is the question of to<br>
do want to do a reqest/reply or pub/sub style heartbeat.  What do you<br>
think?<br></blockquote><div>The way we talked about it, the heartbeat needs to issue commands both ways. While it is used for checking whether an engine remains alive, it is also the avenue for aborting jobs.  If we do have a strict heartbeat, then I think PUB/SUB is a good choice. </div>

<div><br></div><div>However, if heartbeat is all it does, then we need a _third_ connection to each engine for control commands. Since messages cannot jump the queue, the engine queue PAIR socket cannot be used for commands, and a PUB/SUB model for heartbeat can _either_ receive commands _or_ have results.</div>

<div><br></div><div>control commands:</div><div>beat (check alive)</div><div>abort (remove a task from the queue)</div><div>signal (SIGINT, etc.)</div><div>exit (engine.kill)</div><div>reset (clear queue, namespace)</div>

<div><br></div><div>more?</div><div><br></div><div>It&#39;s possible that we could implement these with a PUB on the controller and a SUB on each engine, only interpreting results received via the queue&#39;s PAIR socket. But then every command would be sent to every engine, even though many would only be meant for one (too inefficient/costly?). It would however make the actual heartbeat command very simple as a single send.</div>

<div><br></div><div>It does not allow for the engine to initiate queries of the controller, for instance a work stealing implementation. Again, it is possible that this could be implemented via the job queue PAIR socket, but that would only allow for stealing when completely starved for work, since the job queue and communication queue would be the same.</div>

<div><br></div><div>There&#39;s also the issue of task dependency.</div><div><br></div><div>If we are to implement dependency checking as we discussed (depend on taskIDs, and only execute once the task has been completed), the engine needs to be able to query the controller about the tasks depended upon. This makes the controller being the PUB side unworkable. </div>

<div><br></div><div>This says to me that we need two-way connections between the engines and the controller. That can either be implemented as multiple connections (PUB/SUB + PAIR or REQ/REP), or simply a PAIR socket for each engine could provide the whole heartbeat/command channel.</div>

<div><br></div><div>-MinRK</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
Brian<br>
</font><div><div></div><div class="h5"><br>
<br>
&gt; -MinRK<br>
<br>
<br>
<br>
--<br>
Brian E. Granger, Ph.D.<br>
Assistant Professor of Physics<br>
Cal Poly State University, San Luis Obispo<br>
<a href="mailto:bgranger@calpoly.edu">bgranger@calpoly.edu</a><br>
<a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a><br>
</div></div></blockquote></div><br>