colstrom/ezmq

View on GitHub
doc/file.README.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>
  File: README
  
    &mdash; Documentation by YARD 0.8.7.6
  
</title>

  <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />

  <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />

<script type="text/javascript" charset="utf-8">
  hasFrames = window.top.frames.main ? true : false;
  relpath = '';
  framesUrl = "frames.html#!file.README.html";
</script>


  <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>

  <script type="text/javascript" charset="utf-8" src="js/app.js"></script>


  </head>
  <body>
    <div id="header">
      <div id="menu">
  
    <a href="_index.html">Index</a> &raquo; 
    <span class="title">File: README</span>
  

  <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
</div>

      <div id="search">
  
    <a class="full_list_link" id="class_list_link"
        href="class_list.html">
      Class List
    </a>
  
    <a class="full_list_link" id="method_list_link"
        href="method_list.html">
      Method List
    </a>
  
    <a class="full_list_link" id="file_list_link"
        href="file_list.html">
      File List
    </a>
  
</div>
      <div class="clear"></div>
    </div>

    <iframe id="search_frame"></iframe>

    <div id="content"><div id='filecontents'><h1><a href="https://colstrom.github.io/ezmq/">EZMQ (Effortless ZeroMQ)</a></h1>

<p><a href="https://gitter.im/colstrom/ezmq?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Join the chat at https://gitter.im/colstrom/ezmq" /></a></p>

<p><a href="http://badge.fury.io/rb/ezmq"><img src="https://badge.fury.io/rb/ezmq.svg" alt="Gem Version" /></a>
<a href="https://gemnasium.com/colstrom/ezmq"><img src="https://gemnasium.com/colstrom/ezmq.svg" alt="Dependency Status" /></a>
<a href="https://codeclimate.com/github/colstrom/ezmq"><img src="https://codeclimate.com/github/colstrom/ezmq/badges/gpa.svg" alt="Code Climate" /></a></p>

<h2>Overview</h2>

<p>EZMQ is a wrapper around the wonderful <code>ffi-rzmq</code> gem, which (as the name suggests) uses FFI, and exposes a fairly raw C-like interface. As elegant as 0MQ is, C doesn't feel like Ruby, and FFI bindings feel like C. EZMQ makes some reasonable assumptions to help you focus on what makes your code special, and not worry about setting up 0MQ.</p>

<p>Any of the magical hand-wavey bits (contexts, sockets, etc) are still exposed for tinkering, EZMQ just starts you off with some sane defaults.</p>

<h1>Examples</h1>

<p>Most of these examples are trivial, because ZMQ is just the fabric of your networked application(s).</p>

<h2>Echo Server</h2>

<p>Waits for a request, replies with the same request.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_message'>message</span><span class='op'>|</span>
  <span class='id identifier rubyid_message'>message</span>
<span class='kw'>end</span>
</code></pre>

<h2>Synchronous Client Request</h2>

<p>Sends a message, prints the reply when it arrives.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_client'>client</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Client</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
<span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_client'>client</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>test</span><span class='tstring_end'>&#39;</span></span>
</code></pre>

<h2>Confirming Logging Server</h2>

<p>Waits for a request, prints it to STDOUT, and thanks the client for it.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_message'>message</span><span class='op'>|</span>
  <span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_message'>message</span>
  <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Thanks for the message!</span><span class='tstring_end'>&#39;</span></span> <span class='comment'># The return of the block is sent to the client.
</span><span class='kw'>end</span>
</code></pre>

<h2>JSON Echo Server</h2>

<p>Waits for JSON message, decodes it, re-encodes it, and sends it back.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>json</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_server'>server</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Server</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>encode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_dump'>dump</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>decode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_load'>load</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>
<span class='id identifier rubyid_server'>server</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_message'>message</span><span class='op'>|</span>
  <span class='id identifier rubyid_message'>message</span>
<span class='kw'>end</span>
</code></pre>

<h2>JSON Synchronous Client Request</h2>

<p>Encodes a message in JSON, sends it twice, prints the first one raw, and decodes the second.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>json</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_client'>client</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Client</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>encode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_dump'>dump</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>
<span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_client'>client</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>test</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_client'>client</span><span class='period'>.</span><span class='id identifier rubyid_decode'>decode</span> <span class='op'>=</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_load'>load</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>
<span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_client'>client</span><span class='period'>.</span><span class='id identifier rubyid_request'>request</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>test</span><span class='tstring_end'>&#39;</span></span>
</code></pre>

<h2>'foorever' Publisher</h2>

<p>Publishes an endless stream of 'foo's with a topic of 'foorever'.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_publisher'>publisher</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='period'>.</span><span class='const'>Publisher</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>

<span class='id identifier rubyid_loop'>loop</span> <span class='kw'>do</span>
  <span class='id identifier rubyid_publisher'>publisher</span><span class='period'>.</span><span class='id identifier rubyid_send'>send</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foo</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>topic:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foorever</span><span class='tstring_end'>&#39;</span></span>
<span class='kw'>end</span>
</code></pre>

<h2>'foorever' Subscriber</h2>

<p>Subscribes to topic 'foorever', prints any messages it receives.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_subscriber'>subscriber</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='period'>.</span><span class='const'>Subscriber</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>topic:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>foorever</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_subscriber'>subscriber</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_message'>message</span><span class='comma'>,</span> <span class='id identifier rubyid_topic'>topic</span><span class='op'>|</span>
  <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>[</span><span class='embexpr_beg'>#{</span> <span class='id identifier rubyid_topic'>topic</span> <span class='embexpr_end'>}</span><span class='tstring_content'>] </span><span class='embexpr_beg'>#{</span> <span class='id identifier rubyid_message'>message</span> <span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
<span class='kw'>end</span>
</code></pre>

<h2>Pipeline Work Generator</h2>

<p>Generates work, distributes it to workers via PUSH socket.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>json</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_generator'>generator</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Pusher</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:bind</span><span class='comma'>,</span> <span class='label'>encode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_dump'>dump</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>

<span class='int'>15</span><span class='period'>.</span><span class='id identifier rubyid_times'>times</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_id'>id</span><span class='op'>|</span>
  <span class='id identifier rubyid_work'>work</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>id</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>task_</span><span class='embexpr_beg'>#{</span> <span class='id identifier rubyid_id'>id</span> <span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>request</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>100</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span>
  <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Generated work </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_work'>work</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
  <span class='id identifier rubyid_generator'>generator</span><span class='period'>.</span><span class='id identifier rubyid_send'>send</span> <span class='id identifier rubyid_work'>work</span>
<span class='kw'>end</span>
</code></pre>

<h2>Pipeline Workers</h2>

<p>3 worker threads PULL work from the Generator and PUSH results to the Collector.</p>

<p>The 'work' here is generating a random number between 1 and a requested maximum.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>json</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_workers'>workers</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='rbracket'>]</span>

<span class='int'>3</span><span class='period'>.</span><span class='id identifier rubyid_times'>times</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_id'>id</span><span class='op'>|</span>
  <span class='id identifier rubyid_workers'>workers</span> <span class='op'>&lt;&lt;</span> <span class='const'>Thread</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
    <span class='id identifier rubyid_input'>input</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Puller</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:connect</span><span class='comma'>,</span> <span class='label'>decode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_load'>load</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>
    <span class='id identifier rubyid_output'>output</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Pusher</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>port:</span> <span class='int'>5556</span><span class='comma'>,</span> <span class='label'>encode:</span> <span class='tlambda'>-&gt;</span> <span class='id identifier rubyid_m'>m</span> <span class='tlambeg'>{</span> <span class='const'>JSON</span><span class='period'>.</span><span class='id identifier rubyid_dump'>dump</span> <span class='id identifier rubyid_m'>m</span> <span class='rbrace'>}</span>
    <span class='id identifier rubyid_input'>input</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_work'>work</span><span class='op'>|</span>
      <span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Worker </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_id'>id</span><span class='embexpr_end'>}</span><span class='tstring_content'> pulled </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_work'>work</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span>
      <span class='id identifier rubyid_result'>result</span> <span class='op'>=</span> <span class='id identifier rubyid_rand'>rand</span><span class='lparen'>(</span><span class='int'>1</span><span class='op'>..</span><span class='id identifier rubyid_work'>work</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>request</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_to_i'>to_i</span><span class='rparen'>)</span>
      <span class='id identifier rubyid_report'>report</span> <span class='op'>=</span> <span class='lbrace'>{</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>id</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='id identifier rubyid_work'>work</span><span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>id</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>result</span><span class='tstring_end'>&#39;</span></span> <span class='op'>=&gt;</span> <span class='id identifier rubyid_result'>result</span> <span class='rbrace'>}</span>
      <span class='id identifier rubyid_output'>output</span><span class='period'>.</span><span class='id identifier rubyid_send'>send</span> <span class='id identifier rubyid_report'>report</span>
    <span class='kw'>end</span>
  <span class='kw'>end</span>
<span class='kw'>end</span>

<span class='id identifier rubyid_workers'>workers</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span><span class='lparen'>(</span><span class='op'>&amp;</span><span class='symbol'>:join</span><span class='rparen'>)</span>
</code></pre>

<h2>Pipeline Results Collector</h2>

<p>PULLs results from workers and prints it to STDOUT.</p>

<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>ezmq</span><span class='tstring_end'>&#39;</span></span>
<span class='id identifier rubyid_require'>require</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>json</span><span class='tstring_end'>&#39;</span></span>

<span class='id identifier rubyid_collector'>collector</span> <span class='op'>=</span> <span class='const'>EZMQ</span><span class='op'>::</span><span class='const'>Puller</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='label'>port:</span> <span class='int'>5556</span>
<span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_listen'>listen</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_message'>message</span><span class='op'>|</span>
  <span class='id identifier rubyid_puts'>puts</span> <span class='id identifier rubyid_message'>message</span>
<span class='kw'>end</span>
</code></pre>

<h1>Operating System Notes</h1>

<p>As this relies on <a href="https://github.com/chuckremes/ffi-rzmq">ffi-rzmq</a>, you will need to have the zeromq libraries available.</p>

<p>For OSX, <a href="http://brew.sh/">Homebrew</a> is probably the easiest way to handle this:</p>

<p><code>brew install zeromq</code></p>

<p>For Ubuntu, <a href="https://launchpad.net/~chris-lea/+archive/ubuntu/zeromq">Chris Lea's PPA</a> is a good choice:</p>

<pre class="code ruby"><code class="ruby">sudo add-apt-repository ppa:chris-lea/zeromq
sudo aptitude update
sudo aptitude install libzmq3-dev
</code></pre>

<p>For Windows, you should really consult the <a href="http://zeromq.org/docs:windows-installations">ØMQ documentation</a>.</p>
</div></div>

    <div id="footer">
  Generated on Tue Feb 24 13:47:49 2015 by
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
  0.8.7.6 (ruby-2.0.0).
</div>

  </body>
</html>