<?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>8th Light Blog: Rinda and setting up Rindlets</title>
    <link>http://blog.8thlight.com/articles/2008/04/17/rinda-and-setting-up-rindlets</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Rinda and setting up Rindlets</title>
      <description>&lt;p&gt;Jim Suchy recently laid down some basics of Rinda in his blog &lt;a href="http://blog.8thlight.com/articles/2008/02/12/rinda-101"&gt;Rinda 101&lt;/a&gt;.  I would like to build on that and talk a little about the rindlet architecture.  A rindlet is some process that is listening to the tuplespace, waiting to read or take messages.  &lt;/p&gt;

&lt;p&gt;When a tuple is written to the tuplespace, the rindlet will look at the message and determine if this is a tuple of interest to it.  If it is, then the engines warm up and the tuple gets processed by the logic in the rindlet.  Otherwise, the rindlet will take a pass, and wait for another message to be written to the tuplespace.&lt;/p&gt;

&lt;p&gt;These rindlets are autonomous and asynchronous pieces of business logic that are messaging across many systems, or across many modules of the same system.  We deploy them as daemon processes.&lt;/p&gt;

&lt;p&gt;As a proof of concept, Jim and I built a trivia game, with two different interfaces.  One will be a rich client, developed using a ruby framework called &lt;a href="http://blog.8thlight.com/articles/2008/02/05/limelight-at-railsconf-2008"&gt;limelight&lt;/a&gt;, and one will be a command line ruby client.&lt;/p&gt;

&lt;p&gt;Lets look at the code in the rich client application which updates the question on a screen for all the trivia participants to answer.&lt;/p&gt;

&lt;pre&gt;
require 'rinda_client'

module CurrentQuestion

  def start_update_question
    Thread.new(self) do |current_question|
      while true
        update_question(current_question)
        sleep 1
      end
    end
  end

  def question_update(current_question)
    client = Rinda::RindaClient.new
    tuple = client.read ["questioner", "response", "current question"], 1

    unless tuple.nil?
      current_question.text = tuple[3] 
      current_question.update
    end

  end

end
&lt;/pre&gt;

&lt;p&gt;This code spawns a thread to sit and listen to the rinda server to see if there are any new questions.  The questioner rindlet will post a tuple called &#8220;current question&#8221; every 30 seconds to change the question.  After we create a rinda client, we set up the match criteria for the tuples we are interested in.&lt;/p&gt;

&lt;pre&gt;
tuple = client.read ["questioner", "response", "current question"], 1
&lt;/pre&gt;

&lt;p&gt;We want to read all tuples that match&lt;/p&gt;

&lt;pre&gt; 
["questioner", "response", "current question"]
&lt;/pre
with a timeout of 1 second.  The matching criteria we used was very deliberate, we use the first parameter to indicate the name of the rindlet the tuple was written from, the second parameter indicating if this tuple is a request or response, and the third parameter indicating the action being requested or responded to.  All parameters after this third parameter (by convention only) are the information you need to send to the client of your tuple.  In this case, after we check to see if we have a tuple, we are interested in:

&lt;pre&gt;
current_question.text = tuple[3] 
&lt;/pre&gt;

&lt;p&gt;The fourth parameter, which is the question text to display on the screen.  &lt;/p&gt;

&lt;p&gt;This example shows you can integrate your application with rinda.  Your application can listen to the tuplespace to get messages that are relevant only to it.  If you are writing a rails application, then you would have to use the view helper periodically call remote, since rails is single threaded, it isn&amp;#8217;t as easy as firing a thread and moving on.&lt;/p&gt;

&lt;p&gt;Lets start with some rindlet code.&lt;/p&gt;

&lt;pre&gt;
require "rindlet"

class QuestionerRindlet &lt; Rinda::Rindlet

  def run
    with_standard_tuple("questioner", "next question") do |tuple|
      game = Game.active_game

      question_text = nil
      if game.nil?
        question_text = "No active game!"
      else
        question = game.next_question
        question_text = question.nil? ? "No more questions!" : question.text
      end

      @rinda_client.write(["questioner", "response", "current question", "#{question_text}"])
    end
  end

end
&lt;/pre&gt;

&lt;p&gt;First, the with&lt;em&gt;standard&lt;/em&gt;tuple method is a standard wrapper to match elements and take the tuple if it matches and pass it into the block.  Alternatively, you could do:&lt;/p&gt;

&lt;p&gt;tuple = client.take [&amp;#8220;questioner&amp;#8221;, &amp;#8220;request&amp;#8221;, &amp;#8220;next question&amp;#8221;] &lt;/p&gt;

&lt;p&gt;The rindlet itself then gets the next question from the game, and writes a tuple back to the tuplespace with a response, containing the question text.  Notice the code in this rindlet feels a lot like controller code in the MVC pattern.  Since rinda is a technology and notation of communication, it will just call the business logic in the models and respond to the actions performed if needed.  Rindlets often behave as system level controllers, not specific to any one application.&lt;/p&gt;

&lt;p&gt;I have had lots of fun getting rindlets to work, and they have been an interesting tool for decoupling business logic from any specific application.  Happy coding!&lt;/p&gt;

&lt;p&gt;Note:  I will soon be releasing a rinda gem with the rinda server and the base rindlet class, amongst some of its functionality.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 02:59:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:72f3a71e-67ef-48e6-89f9-db4ba5a9a069</guid>
      <author>Paul Pagel</author>
      <link>http://blog.8thlight.com/articles/2008/04/17/rinda-and-setting-up-rindlets</link>
      <category>Coding</category>
      <category>Rinda</category>
    </item>
  </channel>
</rss>
