{"id":164,"date":"2008-05-11T07:08:33","date_gmt":"2008-05-11T06:08:33","guid":{"rendered":"http:\/\/www.nobugs.org\/blog\/archives\/2008\/05\/11\/squawk-simple-queues-using-awk\/"},"modified":"2008-12-07T00:13:30","modified_gmt":"2008-12-06T23:13:30","slug":"squawk-simple-queues-using-awk","status":"publish","type":"post","link":"https:\/\/www.nobugs.org\/blog\/archives\/2008\/05\/11\/squawk-simple-queues-using-awk\/","title":{"rendered":"Squawk (simple queues using awk)"},"content":{"rendered":"<p>If you are easily offended, look away now &#8230;<\/p>\n<p>Reliable message queues (<a href=\"http:\/\/activemq.apache.org\/\">ActiveMQ<\/a> in particular) are pretty handy things.  They make it a lot easier to build reliable systems which are able to <a href=\"http:\/\/lists.jammed.com\/ISN\/2006\/01\/0065.html\">network problems<\/a>, <a href=\"http:\/\/www.acadweb.wwu.edu\/dbrunner\/cbefire\/\">hardware trouble<\/a> and <a href=\"http:\/\/www.ida.liu.se\/~abdmo\/SNDFT\/docs\/ram-soft.html\">temporary weirdness<\/a>.  However, they always feel pretty heavyweight; suitable for &#8220;enterprise systems&#8221; but not quick shell scripts.<\/p>\n<p>Well, let&#8217;s fix that.  My aim is publish and receive messages to an ActiveMQ broker from the unix shell with a minimum of overhead.  I want to have a &#8216;consume&#8217; script which reads messages from a queue and pipes them to a handler.  If the handler script succeeds, the message is acknowledged and we win.  If the handler script fails, the message is returned back to the queue, and can be re-tried later (possibly by a different host).<\/p>\n<p><a href=\"http:\/\/stomp.codehaus.org\/Protocol\">STOMP<\/a> is what makes this easy.  It&#8217;s a &#8216;simple text-oriented message protocol&#8217; which is supported directly by ActiveMQ.  So we won&#8217;t need to mess around with weighty client libraries.  A good start.<\/p>\n<p>But we still need to write a &#8216;consume&#8217; program which will speak STOMP and invoke the message handler script.  There are existing STOMP bindings for perl and ruby, but I&#8217;m pitching for a pure unix solution.<\/p>\n<p>In STOMP, messages are NUL separated which made me wonder if it&#8217;d be possible to use <a href=\"http:\/\/en.wikipedia.org\/wiki\/Awk\">awk<\/a>, by setting its &#8216;record separator&#8217; to NUL.  The short answer is: yes, awk can do reliable messaging &#8211; win!<\/p>\n<p>We&#8217;ll need some network glue.  Recent versions of awk have builtin network support, but I&#8217;m going to use netcat because it&#8217;s more common than bleeding-edge awks.<\/p>\n<p>I also want to keep &#8216;consume&#8217; to be a single file, but I don&#8217;t want to pull my hair out trying to escape everything properly.  So, I&#8217;ll use a bash <a href=\"http:\/\/tldp.org\/LDP\/abs\/html\/here-docs.html\">here document<\/a> to write the awk script out to a temporary file before invoking awk.  (is there a nicer way to do this?)<\/p>\n<p>There&#8217;s not much more to say except here&#8217;s the scripts: <a href=\"http:\/\/www.nobugs.org\/developer\/squawk\/consume\">consume<\/a> and <a href=\"http:\/\/www.nobugs.org\/developer\/squawk\/produce\">produce<\/a>.<\/p>\n<p>To try it out, you&#8217;ll need to <a href=\"http:\/\/activemq.apache.org\/activemq-510-release.html\">download ActiveMQ<\/a> and start it up; just do .\/bin\/activemq and you&#8217;ll get a broker which has a stomp listener on port 61613.<\/p>\n<p>To publish to a queue, run: echo &#8216;my message&#8217; | .\/produce localhost 61613 \/queue\/a<\/p>\n<p>To consume, first write a message handler, such as:<\/p>\n<pre>\r\n#!\/bin\/bash\r\necho Handling a message at $(date).  Message follows:\r\ncat\r\necho '(message ends)'\r\nexit 0\r\n<\/pre>\n<p>and then run: .\/consume localhost 61613 \/queue\/a .\/myhandler.<\/p>\n<p>To simulate failure, change the handler to &#8220;exit 1&#8221;.  The message will be returned to the queue.  By default, the consumer will then immediately try again, so I added in a &#8216;sleep 1&#8217; to slow things down a bit.  ActiveMQ has many tweakable settings to control backoff, redelivery attempts and dead-letter queue behaviour.<\/p>\n<p>I&#8217;m done.<\/p>\n<p>If you want to learn more about awk, check out the awk book on <a href=\"http:\/\/astore.amazon.com\/nobugs-20\">my amazon.com bookshelf<\/a>.<\/p>\n<p>Y&#8217;know, come the apocalypse, the cockroaches&#8217;s programming language of choice is probably going to be awk.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are easily offended, look away now &#8230; Reliable message queues (ActiveMQ in particular) are pretty handy things. They make it a lot easier to build reliable systems which are able to network problems, hardware trouble and temporary weirdness. However, they always feel pretty heavyweight; suitable for &#8220;enterprise systems&#8221; but not quick shell scripts. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[26,27,25,13],"class_list":["post-164","post","type-post","status-publish","format-standard","hentry","category-programming","tag-awk","tag-hack","tag-mq","tag-unix"],"_links":{"self":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/comments?post=164"}],"version-history":[{"count":1,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/164\/revisions"}],"predecessor-version":[{"id":198,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/posts\/164\/revisions\/198"}],"wp:attachment":[{"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/media?parent=164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/categories?post=164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nobugs.org\/blog\/wp-json\/wp\/v2\/tags?post=164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}