[ANN] slave-1.2.1

Discussion in 'Ruby' started by Ara.T.Howard, Apr 27, 2007.

  1. Ara.T.Howard

    Ara.T.Howard Guest

    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://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 :eek:bject => 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
    --
    be kind whenever possible... it is always possible.
    - the dalai lama
    Ara.T.Howard, Apr 27, 2007
    #1
    1. Advertising

  2. Ara.T.Howard

    John Stoffel Guest

    Re: slave-1.2.1

    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
    --
    Posted via http://www.ruby-forum.com/.
    John Stoffel, Feb 17, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Jackson

    VHDL for FPGA VME Slave

    Colin Jackson, Aug 15, 2003, in forum: VHDL
    Replies:
    2
    Views:
    4,891
    Tullio Grassi
    Aug 19, 2003
  2. [ANN] slave-0.2.0

    , Sep 23, 2006, in forum: Ruby
    Replies:
    3
    Views:
    115
    Ezra Zygmuntowicz
    Sep 24, 2006
  3. [ANN] slave-1.0.0

    , Oct 13, 2006, in forum: Ruby
    Replies:
    2
    Views:
    119
  4. Ara.T.Howard

    [ANN] slave-1.1.0

    Ara.T.Howard, Nov 28, 2006, in forum: Ruby
    Replies:
    11
    Views:
    191
  5. [ANN] slave-1.2.0.rb

    , Dec 8, 2006, in forum: Ruby
    Replies:
    0
    Views:
    140
Loading...

Share This Page