<div>I have a couple of patch files I can send the the appropriate place. One for packet and one for backgroundrb. Am I supposed to send them to this list for review, email them to hemant, request write access to a SubVersion or Git repository, or something else? </div>

<div>&nbsp;</div>
<div>I need a little handholding with this part so please be patient. :-)&nbsp;I haven&#39;t participated in open source very much so I&#39;m not sure what the conventions are.</div>
<div>&nbsp;</div>
<div>- Brian<br><br></div>
<div class="gmail_quote">On Sun, Apr 13, 2008 at 5:44 PM, Brian Morearty &lt;<a href="mailto:brian@morearty.org">brian@morearty.org</a>&gt; wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<div>Hello all,</div>
<div>&nbsp;</div>
<div>I have some good news to announce. I have made some changes to a local copy of BackgrounDRb 1.0.3 (actually most of the changes were in Packet 0.1.5) and I&#39;ve got it working on Windows. From what I&#39;ve read, this is the first time it&#39;s worked on Windows in a year and a half, since 0.2 was released.</div>

<div>&nbsp;</div>
<div>
<div>In my research I can see that a number of people have asked for Windows support so I&#39;m excited that I can help out. </div></div>
<div>&nbsp;</div>
<div>I&#39;m new to this mailing list and new to BackgrounDRb so I would appreciate advice and help from you all on things like:</div>
<div>- how to test my changes. When I run rake it just exits without running any tests. I&#39;m not sure why. I also don&#39;t know how to test Packet.</div>
<div>- how to send a patch. I mostly do Windows development where textual patches are not commonplace. But I did submit a patch to Rails that was accepted, so at least I&#39;ve done it once with success. :-)</div>
<div>- a code review to make sure I&#39;m doing things in an approved way</div>
<div>- someone with *nix to make sure I didn&#39;t break anything by accident. I tried hard to not but you can&#39;t be sure without testing.</div>
<div>&nbsp;</div>
<div>Since I haven&#39;t figured out how to run automated tests I have created some ad hoc tests of my own. These cases work:</div>
<div>
<div>- ad hoc scheduling by calling a method on the worker</div>- passing parameters to the worker</div>
<div>- cron scheduling</div>
<div>- register_status and ask_status</div>
<div>- making a synchronous call and getting a result back kind of works, except I get the whole hash back with the result in the :data key instead of just getting the result alone. In other words I get a hash like this:</div>

<div>&nbsp;&nbsp; {:type=&gt;:response, :client_signature=&gt;25, :result=&gt;true, :data=&gt;1}</div>
<div>&nbsp; which is odd because it&#39;s calling the same &quot;extract&quot; function that ask_status uses, so I&#39;m not sure why this is any different.</div>
<div>&nbsp;</div>
<div>There are some things I haven&#39;t tried yet but it&#39;s great that this many cases work. </div>
<div>&nbsp;</div>
<div>I definitely have to try to figure out why the return value of a synchronous call is the whole hash, and I might need help on that because I&#39;m mystified.</div>
<div>&nbsp;</div>
<div>The primary obstacles to making BackgrounDRb work on Windows were:</div>
<div>1. UNIXSocket - it wasn&#39;t too hard to add code that uses TCPSocket unless defined? UNIXSocket. And there were four lines of code that checked if a socket was a UNIXSocket to decide whether it&#39;s an &quot;internal&quot; read or write, but those lines were crashing because UNIXSocket isn&#39;t even defined on Windows, much less used. My fix for that was to create a marker Module called &quot;Packet::InternalSocket.&quot; Each time I created an internal socket (where the code used to create a UNIXSocket) I now call socket.extend Packet::InternalSocket so that later on the code can distinguish the internal ones from the others.</div>

<div>2. fork - well that&#39;s a harder matter. Windows doesn&#39;t support fork() and probably never will. I saw a recent post by Hemant Kumar mentioning a fix that uses fork and exec rather than just fork, but it still requires fork. Simulating fork in a generic way is nearly impossible but replacing it in a single application is conceivable, depending on what the app does. And in this case I was able to do this:</div>

<div>&nbsp;a) Leave the existing fork call there</div>
<div>&nbsp;b) Fall back on IO.popen for operating systems where fork is not supported</div>
<div>&nbsp;What I did is for each worker I launch (instead of fork) a new&nbsp;child process, pass the read/write port numbers to the child on the command line, and wait for it to connect to them. </div>
<div>&nbsp;</div>
<div>Because Rails takes a long time to start up on Windows (11 seconds, ugh) you can wait a pretty long time before all your workers are ready (11sec&nbsp;* (number of workers+2)). But still, it&#39;s better than not being able to use it at all. It&#39;s perfectly acceptable for a development machine, which is how I use Rails on Windows. (My project is going to deploy on something that ends in nix.) </div>

<div>&nbsp;</div>
<div>On the other hand if you&#39;re going to be dynamically creating background workers (e.g. reload_on_schedule true or set_no_auto_load true) you&#39;ll wait a while for the worker to start up on Windows. </div>
<div>&nbsp;</div>
<div>Will this slow startup time ever block a Rails server request? Not that I&#39;ve seen. From what I&#39;ve seen BackgrounDRb never starts a new worker process because of an API call. The only case I&#39;ve seen where it starts a new worker process on the fly is for a scheduled background task using the cron feature. But I may have missed something.</div>

<div>&nbsp;</div>
<div>Another thing that I didn&#39;t implement (at least not for now): support for the &quot;start&quot; parameter to run the background processes as hidden processes. For now on Windows you just have to run script/backgroundrb without the start parameter and just leave it running in a console. (But I did make the error message nicer.) The reason I didn&#39;t: Ruby does not seem to have implemented a way to kill a process tree in Windows.&nbsp;Windows doesn&#39;t have a single API to kill a process tree. You can add all the processes to a Job and kill that, or you can enumerate the descendants of a process and kill them all one by one. I just didn&#39;t want to bother adding the code to Ruby do that, at least not now, because it works well enough in a console. </div>

<div>&nbsp;</div>
<div>And the nice thing is Ctrl+C from the console does indeed kill the whole process tree.</div>
<div>&nbsp;</div>
<div>That&#39;s it for now. Please let me know how to proceed so us Windows users can benefit from the wonderfulness of BackgrounDRb.</div>
<div>&nbsp;</div>
<div>-- <br>Brian Morearty</div>
<div>&nbsp;</div></blockquote></div><br><br clear="all"><br>-- <br>Brian