<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Segment7: TupleSpace Replicator</title>
    <link>http://blog.segment7.net/articles/2006/04/29/tuplespace-replicator</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>The Blog</description>
    <item>
      <title>TupleSpace Replicator</title>
      <description>&lt;p&gt;At &lt;a href="http://seattlemind.com/"&gt;MindCamp 2.0&lt;/a&gt; I was asked about how you would replicate a TupleSpace.  I whipped up the following implementation:

&lt;pre&gt;&lt;code&gt;class Rinda::TupleSpaceReplicator

  attr_accessor :debug

  attr_reader :local_tuplespace, :remote_tuplespace

  def initialize(remote_tuplespace, templates)
    @local_tuplespace = Rinda::TupleSpace.new
    @remote_tuplespace = remote_tuplespace
    @templates = templates

    @debug = false

    @replicators = ThreadGroup.new
  end

  def replicate
    @templates.each do |template|
      %w[write take].each do |type|
        make_replicator type, template
      end
    end
  end

  def make_replicator(event_type, template)
    thread = Thread.start do
      observer = @remote_tuplespace.notify event_type, template
      observer.each do |event, tuple|
        break if event == 'close'
        @local_tuplespace.send event, tuple
        $stderr.puts "master #{event}: #{tuple.inspect}" if @debug
      end
    end

    @replicators.add thread
  end

end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The core of this is the make_replicator method.  It replicates tuples of the specified template from the remote tuplespace to the local tuplespace.
&lt;p&gt;Here it is in operation:

&lt;pre&gt;&lt;code&gt;# master.rb
require 'rinda/tuplespace'

here = 'druby://127.0.0.1:10000'
ts = Rinda::TupleSpace.new

DRb.start_service here, ts
DRb.thread.join&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;# slave.rb
require 'rinda/tuplespace'
require 'tuplespace_replicator'

here = 'druby://127.0.0.1:10001'
there = 'druby://127.0.0.1:10000'

rts = DRbObject.new_with_uri there
repl = Rinda::TupleSpaceReplicator.new rts, [[nil]]

DRb.start_service here, repl.local_tuplespace
repl.replicate
DRb.thread.join&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;# test.rb
require 'drb'

ts1 = DRbObject.new_with_uri 'druby://127.0.0.1:10000'
ts2 = DRbObject.new_with_uri 'druby://127.0.0.1:10001'

ts1.write [0]
ts1.write [1]
ts1.write [2]

p ts2.read_all([nil])

ts1.take [0]
ts1.take [1]
ts1.take [2]

p ts2.read_all([nil])&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then we run it!

&lt;pre&gt;&lt;samp&gt;$ ruby master.rb &amp;
[1] 18289
$ ruby slave.rb &amp;
[2] 18290
$ ruby test.rb
[[0], [1], [2]]
[]
$&lt;/samp&gt;&lt;/pre&gt;</description>
      <pubDate>Sat, 29 Apr 2006 19:32:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:ab364643-15f2-4cb7-8fc1-9a8d2c2c42d3</guid>
      <author>drbrain@segment7.net (Eric Hodel)</author>
      <link>http://blog.segment7.net/articles/2006/04/29/tuplespace-replicator</link>
      <category>Conference</category>
      <category>DRb</category>
      <category>Hacking</category>
    </item>
  </channel>
</rss>
