# Slave-1.2.1

**URL:** <https://www.ruby-forum.com/t/slave-1-2-1/93136>\
**Category:** Ruby\
**Created:** [April 28, 2007, 12:43am UTC](https://www.ruby-forum.com/t/slave-1-2-1/93136 "2007-04-28T00:43:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [April 28, 2007, 12:43am UTC](https://www.ruby-forum.com/t/slave-1-2-1/93136/1 "2007-04-28T00:43:31Z")

</div>

SYNOPSIS

the Slave class forks a process and starts a drb server in the child  
using  
any object as the server. the process is detached so it is not  
required  
(nor possible) to wait on the child pid. a Heartbeat is set up  
between the  
parent and child processes so that the child will exit of the parent  
exits  
for any reason - preventing orphaned slaves from running  
indefinitely. the  
purpose of Slaves is to be able to easily set up a collection of  
objects  
communicating via drb protocols instead of having to use IPC.

typical usage:

```
 slave = Slave::new{ AnyObject.new }

 slave.object #=> handle on drb object
 slave.uri #=> uri of the drb object
 slave.socket #=> unix domain socket path for drb 

```

object  
slave.psname #=\> title shown in ps/top

```
 object = slave.object

 value = object.any_method #=> use the object normally

```

slaves may be configured via the environment, the Slave class, or via  
the  
ctor for object itself. attributes which may be configured include

```
 * object : specify the slave object. otherwise block value is 

```

used.  
\* socket\_creation\_attempts : specify how many attempts to create a  
unix domain socket will be made  
\* debug : turn on some logging to STDERR  
\* psname : specify the name that will appear in ‘top’ ($0)  
\* at\_exit : specify a lambda to be called in the _parent_ when the  
child dies  
\* dumped : specify that the slave object should _not_ be  
DRbUndumped (default is DRbUndumped)  
\* threadsafe : wrap the slave object with ThreadSafe to implement  
gross thread safety

URIS

[http://rubyforge.org/projects/codeforpeople/](http://rubyforge.org/projects/codeforpeople/)  
[http://codeforpeople.com/lib/ruby/slave](http://codeforpeople.com/lib/ruby/slave)

HISTORY

1.2.1:  
- jruby/ThreadSafe patches from skaar and ez. using slave.rb with  
jruby,  
how cool is that!?

SAMPLES

\<========\< samples/a.rb \>========\>

~ \> cat samples/a.rb

```
 require 'slave'
 #
 # simple usage is simply to stand up a server object as a slave. 

```

you do not  
# need to wait for the server, join it, etc. it will die when the  
parent  
# process dies - even under ‘kill -9’ conditions  
#  
class Server  
def add\_two n  
n + 2  
end  
end

```
   slave = Slave.new :object => Server.new

   server = slave.object
   p server.add_two(40) #=> 42

   slave.shutdown

```

~ \> ruby samples/a.rb

```
 42

```

\<========\< samples/b.rb \>========\>

~ \> cat samples/b.rb

```
 require 'slave'
 #
 # if certain operations need to take place in the child only a 

```

block can be  
# used  
#  
class Server  
def connect\_to\_db  
“we only want to do this in the child process!”  
@connection = :postgresql  
end  
attr :connection  
end

```
   slave = Slave.new('object' => Server.new){|s| s.connect_to_db}

   server = slave.object

   p server.connection #=> :postgresql
 #
 # errors in the child are detected and raised in the parent
 #
   slave = Slave.new('object' => Server.new){|s| s.typo} #=> raises 

```

an error!

~ \> ruby samples/b.rb

```
 :postgresql
 samples/b.rb:22: undefined method `typo' for #<Server:0xb756ed18> 

```

(NoMethodError)  
from ./lib/slave.rb:369:in `[]' from ./lib/slave.rb:369:in `initialize’  
from samples/b.rb:22:in `new’  
from samples/b.rb:22

\<========\< samples/c.rb \>========\>

~ \> cat samples/c.rb

```
 require 'slave'
 #
 # if no slave object is given the block itself is used to contruct 

```

it  
#  
class Server  
def initialize  
“this is run only in the child”  
@pid = Process.pid  
end  
attr ‘pid’  
end

```
   slave = Slave.new{ Server.new }
   server = slave.object

   p Process.pid
   p server.pid # not going to be the same as parents!
 #
 # errors are still detected though
 #
   slave = Slave.new{ fubar } # raises error in parent

```

~ \> ruby samples/c.rb

```
 7971
 7972
 samples/c.rb:21: undefined local variable or method `fubar' for 

```

main:Object (NameError)  
from ./lib/slave.rb:361:in `call' from ./lib/slave.rb:361:in `initialize’  
from samples/c.rb:21:in `new’  
from samples/c.rb:21

\<========\< samples/d.rb \>========\>

~ \> cat samples/d.rb

```
 require 'slave'
 #
 # at_exit hanlders are handled correctly in both child and parent
 #
   at_exit{ p 'parent' }
   slave = Slave.new{ at_exit{ p 'child' }; 'the server is this 

```

string’ }  
#  
# this will print ‘child’, then ‘parent’  
#

~ \> ruby samples/d.rb

```
 "child"
 "parent"

```

\<========\< samples/e.rb \>========\>

~ \> cat samples/e.rb

```
 require 'slave'
 #
 # slaves never outlive their parent. if the parent exits, even 

```

under kill -9,  
# the child will die.  
#  
slave = Slave.new{ at\_exit{ p ‘child’ }; ‘the server is this  
string’ }

```
   Process.kill brutal=9, the_parent_pid=Process.pid
 #
 # even though parent dies a nasty death the child will still print 

```

‘child’  
#

~ \> ruby samples/e.rb

```
 "child"

```

\<========\< samples/f.rb \>========\>

~ \> cat samples/f.rb

```
 require 'slave'
 #
 # slaves created previously are visible to newly created slaves - 

```

in this  
# example the child process of slave\_a communicates directly with  
the child  
# process of slave\_a  
#  
slave\_a = Slave.new{ Array.new }  
slave\_b = Slave.new{ slave\_a.object }

```
   a, b = slave_b.object, slave_a.object

   b << 42
   puts a #=> 42

```

~ \> ruby samples/f.rb

```
 42

```

\<========\< samples/g.rb \>========\>

~ \> cat samples/g.rb

```
 require 'slave'
 #
 # Slave.object can used when you want to construct an object in 

```

another  
# process. in otherwords you want to fork a process and retrieve a  
single  
# returned object from that process as opposed to setting up a  
server.  
#  
this = Process.pid  
that = Slave.object{ Process.pid }

```
   p 'this' => this, 'that' => that

 #
 # any object can be returned and it can be returned asychronously 

```

via a thread  
#  
thread = Slave.object(:async =\> true){ sleep 2 and [ Process.pid,  
Time.now ] }  
this = [Process.pid, Time.now]  
that = thread.value

```
   p 'this' => this, 'that' => that

```

~ \> ruby samples/g.rb

```
 {"that"=>7990, "this"=>7989}
 {"that"=>[7991, Fri, Apr 27 2007 16:38:30 -0600], "this"=>[7989, 

```

Fri, Apr 27 2007 16:38:28 -0600]}

enjoy.

-a

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 17, 2009, 5:29pm UTC](https://www.ruby-forum.com/t/slave-1-2-1/93136/2 "2009-02-17T17:29:41Z")

</div>

Ara.T.Howard wrote:

> SYNOPSIS
> 
> the Slave class forks a process and starts a drb server in the child  
> using  
> any object as the server. the process is detached so it is not  
> required  
> (nor possible) to wait on the child pid. a Heartbeat is set up  
> between the  
> parent and child processes so that the child will exit of the parent  
> exits  
> for any reason - preventing orphaned slaves from running  
> indefinitely. the  
> purpose of Slaves is to be able to easily set up a collection of  
> objects  
> communicating via drb protocols instead of having to use IPC.

Is this being maintained any more? Should I be using some other module  
for the same functionality in the future? It’s a nice tool to use, but  
I’m going insane trying to debug issues and warnings with the code in my  
Recursive Parallel directory descent tool.

Thanks,  
John
