<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Spootnik</title>
  <link href="http://spootnik.org/atom.xml" rel="self"/>
  <link href="http://spootnik.org/"/>
  <updated>2011-09-19T15:50:48+02:00</updated>
  <id>http://spootnik.org/</id>
  <author>
    <name>Pierre-Yves Ritschard</name>
    
  </author>

  
  <entry>
    <title>The death of the configuration file</title>
    <link href="http://spootnik.org/blog/2011/09/18/the-death-of-the-configuration-file/"/>
    <updated>2011-09-18T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/09/18/the-death-of-the-configuration-file</id>
    <content type="html">&lt;p&gt;Taking on a new platform design recently I thought it was interesting to
see how things evolved in the past years and how we design and think
about platform architecture.&lt;/p&gt;

&lt;h2&gt;So what do we do ?&lt;/h2&gt;

&lt;p&gt;As system developers, system administrators and system engineers, what
do we do ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We develop software&lt;/li&gt;
&lt;li&gt;We design architectures&lt;/li&gt;
&lt;li&gt;We configure systems&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;But it isn't the purpose of our jobs, for most of us, our purpose is to
generate business value. From a non technical perspective we generate
business value by creating a system which renders one or many functions
and provides insight into its operation.&lt;/p&gt;

&lt;p&gt;And we do this by developing, logging, configuration and maintaining
software across many machines.&lt;/p&gt;

&lt;p&gt;When I started doing this - back when knowing how to write a sendmail
configuration file could get you a paycheck - it all came down to
setting up a few machines, a database server a web server a mail server,
each logging locally and providing its own way of reporting metrics.&lt;/p&gt;

&lt;p&gt;When designing custom software, you would provide reports over a
local &lt;code&gt;AF_UNIX&lt;/code&gt; socket, and configure your software by writing
elegant parsers with &lt;code&gt;yacc&lt;/code&gt; (or its GNU equivalent, &lt;code&gt;bison&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;When I joined the &lt;code&gt;OpenBSD&lt;/code&gt; team, I did a lot of work on configuration
files, ask any members of the team, the configuration files are a big
concern, and careful attention is put into clean, human readable and
writable syntax, additionally, all configuration files are expected
to look and feel the same, for consistency.&lt;/p&gt;

&lt;p&gt;It seems as though the current state of large applications now demands
another way to interact with operating systems, and some tools are
now leading the way.&lt;/p&gt;

&lt;h2&gt;So what has changed ?&lt;/h2&gt;

&lt;p&gt;While our mission is still the same from a non technical perspective,
the technical landscape has evolved and went through several phases.&lt;/p&gt;

&lt;h3&gt;The first era of repeatable architecture&lt;/h3&gt;

&lt;p&gt;We first realized that as soon as several machines performed the same
task the need for repeatable, coherent environments became essential.
Typical environments used a combination of &lt;code&gt;cfengine&lt;/code&gt;, &lt;code&gt;NFS&lt;/code&gt; and mostly
&lt;code&gt;perl&lt;/code&gt; scripts to achieve these goals.&lt;/p&gt;

&lt;p&gt;Insight and reporting was then providing either by horrible proprietary
kludges that I shall not name here, or emergent tools such as &lt;code&gt;netsaint&lt;/code&gt;
(now &lt;code&gt;nagios&lt;/code&gt;), &lt;code&gt;mrtg&lt;/code&gt; and the like.&lt;/p&gt;

&lt;h3&gt;The XML mistake&lt;/h3&gt;

&lt;p&gt;Around that time, we started hearing more and more about &lt;code&gt;XML&lt;/code&gt;, then
touted as the solution to almost every problem. The rationale was that
&lt;code&gt;XML&lt;/code&gt; was - &lt;em&gt;somewhat&lt;/em&gt; - easy to parse, and would allow developers to
develop configuration interfaces separately from the core functionality.&lt;/p&gt;

&lt;p&gt;While this was a noble goal, it was mostly a huge failure. Above all, it
was a victory of developers over people using their software, since they
didn't bother writing syntax parsers and let users cope with the
complicated syntax.&lt;/p&gt;

&lt;p&gt;Another example was the difference between Linux's &lt;code&gt;iptables&lt;/code&gt; and
OpenBSD's &lt;code&gt;pf&lt;/code&gt;. While the former was supposed to be the backend for a
firewall handling tool that never saw the light of day, the latter
provided a clean syntax.&lt;/p&gt;

&lt;h3&gt;Infrastructure as code&lt;/h3&gt;

&lt;p&gt;Fast forward a couple of years, most users of &lt;code&gt;cfengine&lt;/code&gt; were fed up
with its limitations, architectures while following the same logic
as before became bigger and bigger. The need for repeatable and sane
environments was as important as it ever was.&lt;/p&gt;

&lt;p&gt;At that point of time, &lt;code&gt;PXE&lt;/code&gt; installations were added to the mix of
big infrastructures and many people started looking at &lt;code&gt;puppet&lt;/code&gt; as
a viable alternative to &lt;code&gt;cfengine&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;puppet&lt;/code&gt; provided a cleaner environment, and allowed easier
formalization of technology, platform and configuration.
Philosophically though, &lt;code&gt;puppet&lt;/code&gt; stays very close to &lt;code&gt;cfengine&lt;/code&gt; by
providing a way to configure large amounts of system through a
central repository.&lt;/p&gt;

&lt;p&gt;At that point, large architectures also needed command and control
interfaces. As noted before, most of these were implemented as
&lt;code&gt;perl&lt;/code&gt; or shell scripts in &lt;code&gt;SSH&lt;/code&gt; loops.&lt;/p&gt;

&lt;p&gt;On the monitoring and graphing front, not much was happening, &lt;code&gt;nagios&lt;/code&gt;
and &lt;code&gt;cacti&lt;/code&gt; were almost ubiquitous, while some tools such as &lt;code&gt;ganglia&lt;/code&gt;
and &lt;code&gt;collectd&lt;/code&gt; were making a bit of progress.&lt;/p&gt;

&lt;h2&gt;Where are we now ?&lt;/h2&gt;

&lt;p&gt;At some point recently, our applications started doing more. While for a
long time the canonical dynamic web application was a busy forum, more
complex sites started appearing everywhere. We were not building and
operating sites anymore but applications. And while with the help of
&lt;code&gt;haproxy&lt;/code&gt;, &lt;code&gt;varnish&lt;/code&gt; and the likes, the frontend was mostly a settled
affair, complex backends demanded more work.&lt;/p&gt;

&lt;p&gt;At the same time the advent of social enabled applications demanded
much more insight into the habits of users in applications and thorough
analytics.&lt;/p&gt;

&lt;p&gt;New tools emerged to help us along the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In memory key value caches such as &lt;code&gt;memcached&lt;/code&gt; and &lt;code&gt;redis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Fast elastic key value stores such as &lt;code&gt;cassandra&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Distributed computing frameworks such as &lt;code&gt;hadoop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;And of course on demand virtualized instances, aka: &lt;em&gt;The Cloud&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Some daemons only provide small functionality&lt;/h3&gt;

&lt;p&gt;The main difference in the new stack found in backend systems is
that the software stacks that run are not useful on their own
anymore.&lt;/p&gt;

&lt;p&gt;Software such as &lt;code&gt;zookeeper&lt;/code&gt;, &lt;code&gt;kafka&lt;/code&gt;, &lt;code&gt;rabbitmq&lt;/code&gt; serve no other
purpose that to provide supporting services in applications and
their functionality are almost only available as libraries to
be used in distributed application code.&lt;/p&gt;

&lt;h3&gt;Infrastructure as code is not infrastructure in code !&lt;/h3&gt;

&lt;p&gt;What we missed along the way it seems is that even though our
applications now span multiple machines and daemons provide a
subset of functionality, most tools still reason with the
machine as the top level abstraction.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;puppet&lt;/code&gt; for instance is meant to configure nodes, not cluster
and makes dependencies very hard to manage. A perfect example
is the complications involved in setting up configurations
dependent on other machines.&lt;/p&gt;

&lt;p&gt;Monitoring and graphing, except for &lt;code&gt;ganglia&lt;/code&gt; has long suffered from the
same problem.&lt;/p&gt;

&lt;h2&gt;The new tools we need&lt;/h2&gt;

&lt;p&gt;We need to kill local configurations, plain and simple. With a simple
enough library to interact with distant nodes, starting and stopping
service, configuration can happen in a single place and instead of
relying on a repository based configuration manager, configuration
should happen from inside applications and not be an external process.&lt;/p&gt;

&lt;p&gt;If this happens in a library, command &amp;amp; control must also be added to
the mix, with centralized and tagged logging, reporting and metrics.&lt;/p&gt;

&lt;p&gt;This is going to take some time, because it is a huge shift in the way
we write software and design applications. Today, configuration
management is a very complex stack of workarounds for non standardized
interactions with local package management, service control and
software configuration.&lt;/p&gt;

&lt;p&gt;Today dynamically configuring &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;haproxy&lt;/code&gt; and &lt;code&gt;nginx&lt;/code&gt;, installing
a package on a &lt;code&gt;Debian&lt;/code&gt; or &lt;code&gt;OpenBSD&lt;/code&gt;, restarting a service,
all these very simple tasks which
we automate and operate from a central repository force us to build
complex abstractions. When using &lt;code&gt;puppet&lt;/code&gt;, &lt;code&gt;chef&lt;/code&gt; or &lt;code&gt;pallet&lt;/code&gt;,
we write complex templates because software was meant to be configured
by humans.&lt;/p&gt;

&lt;p&gt;The same goes for checking the output of running arbitrary scripts on
machines.&lt;/p&gt;

&lt;h3&gt;Where we'll be tomorrow&lt;/h3&gt;

&lt;p&gt;With the ease PaaS solutions bring to developers, and offers such as the
ones from VMWare and open initiatives such as OpenStack, it seems as
though virtualized environments will very soon be found everywhere, even
in private companies which will deploy such environments on their own
hardware.&lt;/p&gt;

&lt;p&gt;I would not bet on it happening but a terse input and output format for
system tools and daemons would go a long way in ensuring easy and fast
interaction with configuration management and command and control software.&lt;/p&gt;

&lt;p&gt;While it was a mistake to try to push &lt;code&gt;XML&lt;/code&gt; as a terse format replacing
configuration file to interact with single machines, a terse format is
needed to interact with many machines providing the same service, or
to run many tasks in parallel - even though, admittedly , tools such
as &lt;code&gt;capistrano&lt;/code&gt; or &lt;code&gt;mcollective&lt;/code&gt; do a good job at running things and
providing sensible output.&lt;/p&gt;

&lt;h3&gt;The future is now !&lt;/h3&gt;

&lt;p&gt;Some projects are leading the way in this new orientation, 2011 as
I've seen it called will be the year of the time series boom. For
package management and logging, Jordan Sissel released such great tools
as &lt;code&gt;logstash&lt;/code&gt; and &lt;code&gt;fpm&lt;/code&gt;. For easy graphing and deployment &lt;em&gt;etsy&lt;/em&gt;
released great tools, amongst which &lt;code&gt;statsd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As for bridging the gap between provisionning, configuration management,
command and control and deploys I think two tools, both based on
&lt;a href=&quot;http://www.jclouds.org&quot;&gt;jclouds&lt;/a&gt; are going in the right direction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://whirr.apache.org&quot;&gt;Whirr&lt;/a&gt;: Which let you start a cluster through code, providing
recipes for standard deploys (&lt;code&gt;zookeeper&lt;/code&gt;, &lt;code&gt;hadoop&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pallet/pallet&quot;&gt;pallet&lt;/a&gt;: Which lets you describe your infrastructure as code and
interact with it in your own code. &lt;code&gt;pallet&lt;/code&gt;'s phase approach to cluster
configuration provides a smooth dependency framework which allows easy
description of dependencies between configuration across different
clusters of machines.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Who's getting left out ?&lt;/h3&gt;

&lt;p&gt;One area where things seem to move much slower is network device
configuration, for people running open source based load-balancers
and firewalls, things are looking a bit nicer, but the switch
landscape is a mess. As tools mostly geared towards public cloud
services will make their way in private corporate environments,
hopefully they'll also get some of the programmable&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>A bit of protocol</title>
    <link href="http://spootnik.org/blog/2011/08/12/a-bit-of-protocol/"/>
    <updated>2011-08-12T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/08/12/a-bit-of-protocol</id>
    <content type="html">&lt;h2&gt;Protocols and mixins&lt;/h2&gt;

&lt;p&gt;I recently had to implement something in clojure i've done
many times in ruby, which involved using protocols. I thought
it would be a nice example of comparing class re-opening in
ruby and protocol extension in clojure.&lt;/p&gt;

&lt;h2&gt;The problem&lt;/h2&gt;

&lt;p&gt;I use cassandra, and in many places, cassandra needs to
work with UUID types a lot. When exposing results
over &lt;code&gt;JSON&lt;/code&gt;, this is often a problem since standard serializers
don't support these types.&lt;/p&gt;

&lt;p&gt;What we want to do in ruby and clojure is simple:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;ruby-uuid.rb &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rb'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;simple_uuid&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;json&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;# This fails&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This code fails because the &lt;code&gt;json&lt;/code&gt; module looks for a &lt;code&gt;to_json&lt;/code&gt; method
in each object. Failing to do so, it calls &lt;code&gt;Object#to_s.to_json&lt;/code&gt;. Now this
would work fine if &lt;code&gt;to_s&lt;/code&gt; gave a good textual representation of a UUID,
but it returns the byte array for that UUID.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;clojure-uuid.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;foo&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;clojure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:import&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;; This fails&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;println &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json-str&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:uuid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UUID/randomUUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;In clojure we are informed that &lt;code&gt;java.util.UUID&lt;/code&gt; doesn't respond to &lt;code&gt;write-json&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;Fixing the problem in ruby&lt;/h2&gt;

&lt;p&gt;How to fix this in ruby is no problem, and widely known,
since the &lt;code&gt;simple_uuid&lt;/code&gt; gem provides a &lt;code&gt;to_guid&lt;/code&gt; method which returns
the textual representation, it's as easy as:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;- json_uuid.rb &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rb'&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;simple_uuid&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;json&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SimpleUUID&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UUID&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;to_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_guid&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleUUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This was simple enough, reopening the module then class is
allowed - and to some extent, encouraged - in ruby. We just
added a &lt;code&gt;to_json&lt;/code&gt; method which is what the &lt;code&gt;JSON&lt;/code&gt; module
looks for when walking through objects.&lt;/p&gt;

&lt;h2&gt;Fixing the problem in clojure&lt;/h2&gt;

&lt;p&gt;clojure has the ability to provide so-called &lt;em&gt;protocols&lt;/em&gt;, similar
to java &lt;em&gt;interfaces&lt;/em&gt;. Protocols are defined with &lt;code&gt;defprotocol&lt;/code&gt; and
implemented anywhere. Here is the appropriate bit from &lt;code&gt;clojure.data.json&lt;/code&gt;&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;json.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;;; JSON PRINTER&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defprotocol&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Write-JSON&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;write-json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;escape-unicode?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class=&quot;s&quot;&gt;&amp;quot;Print object to PrintWriter out as JSON&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This defines that &lt;code&gt;write-json&lt;/code&gt; will be dispatched based on class to an
appropriate writer. The &lt;a href=&quot;http://clojure.org/protocols&quot;&gt;clojure page on protocols&lt;/a&gt; has all the detailed
information, but I'll focus on the &lt;code&gt;extend&lt;/code&gt; part here, which allows to
extend a type with new protocol implementations. &lt;code&gt;extend&lt;/code&gt; expects a type
then pairs of protocol names to maps, the map containing function name
to implementation mappings.&lt;/p&gt;

&lt;p&gt;Protocol functions always have the object they need to operate on
as their first argument, here the function takes two additional arguments&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;out&lt;/code&gt; which is the output stream the representation should be pushed to&lt;/li&gt;
&lt;li&gt;&lt;code&gt;escape-unicode?&lt;/code&gt; which determines whether unicode characters should be
escaped.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Following that logic, the implementation can now be written like this:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;json_uuid.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;somewhere&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:import&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;clojure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;write-json-uuid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;escape-unicode?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;binding &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;*out*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pr &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toString&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;extend&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UUID&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Write-JSON&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:write-json&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;write-json-uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;println &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json-str&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:uuid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UUID/randomUUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;Writing the protocol extension&lt;/h3&gt;

&lt;p&gt;The actual function &lt;code&gt;write-json-uuid&lt;/code&gt; is quite simple, I initially wrote it
as:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;write-json-uuid.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;write-json-uuid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;escape-unicode?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pr-str &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;toString&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;But it seems a bit overkill to go to the trouble of writing to a string, then
pushing that string out to the &lt;em&gt;writer&lt;/em&gt; object.&lt;/p&gt;

&lt;h3&gt;Dynamic bindings&lt;/h3&gt;

&lt;p&gt;A small digression is needed here, clojure has &lt;em&gt;dynamic&lt;/em&gt; symbols, defined like
so: &lt;code&gt;(def ^{:dynamic true} *my-dyn-symbol*)&lt;/code&gt; The enclosing stars are a
convention but widely used.&lt;/p&gt;

&lt;p&gt;Dynamic symbols can be manipulated with &lt;code&gt;binding&lt;/code&gt;, which operates like &lt;code&gt;let&lt;/code&gt; but
the bindings will follow the rest of the execution enclosed, not just the
function's context.&lt;/p&gt;

&lt;p&gt;Clojure uses the &lt;code&gt;*out*&lt;/code&gt; symbol everywhere to denote the current output stream,
many functions operate on it, &lt;code&gt;pr&lt;/code&gt; is among them.&lt;/p&gt;

&lt;p&gt;By binding &lt;code&gt;*out*&lt;/code&gt; to the stream that was given as argument to &lt;code&gt;write-json&lt;/code&gt;,
&lt;code&gt;pr&lt;/code&gt; can simply be called on the function.&lt;/p&gt;

&lt;h2&gt;Closing words&lt;/h2&gt;

&lt;p&gt;The most common dispatching idiom in clojure is &lt;code&gt;defmethod&lt;/code&gt;/&lt;code&gt;defmulti&lt;/code&gt;, but
protocols also provide a very fast and useful way to implement polymorphism in
clojure. It's also nice to note that the implementation wasn't longer in clojure
than ruby.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>A wrapping macro</title>
    <link href="http://spootnik.org/blog/2011/08/06/wrapping-macro/"/>
    <updated>2011-08-06T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/08/06/wrapping-macro</id>
    <content type="html">&lt;h2&gt;A bit of sugar&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;wrap-with&lt;/em&gt; function described in &lt;a href=&quot;http://spootnik.org/blog/2011/08/04/clojure-wrappers&quot;&gt;my last post&lt;/a&gt;
is useful, but you still end-up having
to write closures which might be confusing to people who just want
to write simple wrappers.&lt;/p&gt;

&lt;p&gt;Fortunately, clojure provides the ability to enhance the
language with syntactic sugar for use cases such as this one.&lt;/p&gt;

&lt;h2&gt;A word of warning&lt;/h2&gt;

&lt;p&gt;I'm obviously going to talk about macros in this article. I still
think one has to postpone the writing macros as much as possible,
to avoid creating code that feels too &lt;em&gt;magic&lt;/em&gt; to the outside reader.&lt;/p&gt;

&lt;p&gt;There are two use cases where resorting to macro is idiomatic,
we'll explore the first one here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;macros which help define symbols, usually named def_resource_&lt;/li&gt;
&lt;li&gt;macros which wrap access to a resource within a closure, usually named
with-&lt;em&gt;resource&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The first kind of macro is used on a common basis by the clojure programmer:
&lt;a href=&quot;http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/defn&quot;&gt;defn&lt;/a&gt;. Yep, that's right
the idiomatic way to declare functions in clojure is a macro that
wraps a call to def.&lt;/p&gt;

&lt;p&gt;The second kind's most popular example is &lt;a href=&quot;http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/with-open&quot;&gt;with-open&lt;/a&gt;  which encloses access to a resource and
ensures that it gets closed. The &lt;em&gt;with-resource&lt;/em&gt; calls have become
common idioms in clojure libraries and provide a great equivalent to
the similar ruby co-block idiom. This type of macros will be described
in a later post though.&lt;/p&gt;

&lt;h2&gt;Macro terminology&lt;/h2&gt;

&lt;p&gt;Macros need access to all kind of resources and reading them
might be hard on the eyes at first, several people have written
on the subject of macros, and books have been written that go into
great detail on the subject. So I'll just go with a cheat sheet:&lt;/p&gt;

&lt;h3&gt;The body of a macro is usually quoted&lt;/h3&gt;

&lt;p&gt;Macros insert are expanded to code, hence you must provide the
&lt;em&gt;s-exprs&lt;/em&gt; you want to be executed by quoting them otherwise
they won't be executed at the time of execution.&lt;/p&gt;

&lt;p&gt;Beware that there are two types of quoting available in clojure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard quoting, using '&lt;/li&gt;
&lt;li&gt;Backtick quoting, using ` which expands forms into the current
namespace, and is generally used for macros&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Accessing data from within the quoted &lt;em&gt;s-exprs&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;There are two ways to access data from within a quoted list
of expressions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;unquote&lt;/em&gt;: which takes the value of a symbol and replaces it in the
expanded list, &lt;em&gt;~expr&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;unquote-splicing&lt;/em&gt;: which takes the value of a symbol pointing to a list
and expands it spliced, &lt;em&gt;~@expr&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;The canonical unless example&lt;/h3&gt;

&lt;p&gt;Unless is the most common example macro described, let's see how it
is written&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;unless.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defmacro &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;not &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~@exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Short but dense! The code reads like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define an unless macro which takes an arbitrary number of
arguments, the first one being bound to &lt;em&gt;test&lt;/em&gt;, the rest to
a list called &lt;em&gt;exprs&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Test the veracity of &lt;em&gt;test&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Execute the expressions in a &lt;em&gt;do&lt;/em&gt; block&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Wrapping up&lt;/h2&gt;

&lt;p&gt;Building on our previous function &lt;em&gt;wrap-with&lt;/em&gt;, we can
then help people write wrapper functions more easily:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;defwrapper.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defmacro &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defwrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrapper-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bindings&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~wrapper-name&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~bindings&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~@exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This is somewhat inelegant since we still need to
supply a symbol which is going to be bound to the handler.
We can wrap it up using our previous function:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;wrapped.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;to-be-wrapped&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:reply&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defwrapper&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;wrap-add-foo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:foo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;wrap-with&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;to-be-wrapped&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrap-add-foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;Room for improvement&lt;/h3&gt;

&lt;p&gt;Now let's play a bit of magic, how about creating a macro which
rebinds a symbol altogether:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;rebinding.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defmacro &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrap-around&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bindings&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;    &lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;         &lt;span class=&quot;nv&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;meta &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~bindings&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~@exprs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;alter-meta!&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;~handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;merge&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Notice the last call to &lt;a href=&quot;http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/alter-meta!&quot;&gt;alter-meta1&lt;/a&gt; which preserves
the initial var's metadata, such as &lt;em&gt;:tag&lt;/em&gt; or &lt;em&gt;:arglists&lt;/em&gt;.
Now here are the macros in context:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;using-rebind.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;wrap-around&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:foo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;c1&quot;&gt;;; store elapsed time in &lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;wrap-around&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;assoc &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;- &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h2&gt;Closing words&lt;/h2&gt;

&lt;p&gt;This is just a peak into the power of macros in clojure, and it was a fun
journey getting to the bottom of the last macro. However the last form
complicates reading to some extend and should thus be avoided if possible.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Clojure Wrappers</title>
    <link href="http://spootnik.org/blog/2011/08/04/clojure-wrappers/"/>
    <updated>2011-08-04T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/08/04/clojure-wrappers</id>
    <content type="html">&lt;h2&gt;Functions in the wild&lt;/h2&gt;

&lt;p&gt;Functional programming rears its head in the most unusual places in software
design. Take the web stack interfaces (&lt;a href=&quot;http://rack.rubyforge.org/&quot;&gt;rack&lt;/a&gt;, &lt;a href=&quot;http://plackperl.org/&quot;&gt;plack&lt;/a&gt;,
&lt;a href=&quot;http://wsgi.org/wsgi/&quot;&gt;WSGI&lt;/a&gt;), they all implement a very functional view of what a web application
is: a function that takes a map as input and returns a map as output.&lt;/p&gt;

&lt;p&gt;Middleware then build on that abstraction composing themselves down to the
actual handler call.&lt;/p&gt;

&lt;p&gt;The graylog2 extension mechanism is a good example of this, the bulk of which is
really simple:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;Excerpt from graylog2 - graylog2_exceptions.rb &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='rb'&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;c1&quot;&gt;# Call the app we are monitoring&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;vi&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;c1&quot;&gt;# An exception has been raised. Send to Graylog2!&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;n&quot;&gt;send_to_graylog2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;c1&quot;&gt;# Raise the exception again to pass backto app.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;All the code does is wrap application call in an exception catching block and
returning the original result. Providing such a composition interface enables
doing two useful things for middleware applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Taking action before the handler is called, for instance parsing json data as arguments.&lt;/li&gt;
&lt;li&gt;Taking action after the handler was called, in this case catching exceptions.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Composition in clojure&lt;/h2&gt;

&lt;p&gt;The russian doll approach taken in rack was a natural fit for clojure's web
stack, &lt;a href=&quot;https://github.com/mmcgrana/ring&quot;&gt;ring&lt;/a&gt;. What I want to show here is how easy it is to write a simple
wrapping layer for any type of function, enabling building simple input and output
filters for any type of logic.&lt;/p&gt;

&lt;h3&gt;The basics&lt;/h3&gt;

&lt;p&gt;Let's say we have a simple function interacting with a library, taking
a map as parameter, yielding an operation status map back:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;command.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;send-command&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;send a command&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class=&quot;nv&quot;&gt;serialize&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;; translate into a format for on-wire&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class=&quot;nv&quot;&gt;send-sync&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;; send command and wait for answer&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class=&quot;nv&quot;&gt;deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;; translate result back as map&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now let's say we need the following filters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need certain keys in the command map sent out&lt;/li&gt;
&lt;li&gt;We want to provide defaults for the reply map&lt;/li&gt;
&lt;li&gt;We want to time command execution for statistics usage&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The functions are easy to write:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;filters.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filter-required&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;required&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;when &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;some &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;invalid payload&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filter-defaults&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defaults&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:unknown,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:guest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;merge &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defaults&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;time-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;start-ts&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;nv&quot;&gt;end-ts&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;merge &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:elapsed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;- &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;end-ts&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;start-ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)})))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now all that is required is linking those functions together.
A very naive approach would be to go the imperative way,
with let:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;linking.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;linking-wrappers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-required&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter-defaults&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;time-command&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;Evolving towards a wrapper interface&lt;/h3&gt;

&lt;p&gt;Thinking about it in a more functional way, it becomes
clear that this is just threading the payload through functions.
Clojure even has a nice macro that does just that.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;composition.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;composing-wrappers&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filter-required&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filter-defaults&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;time-command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This is already very handy, but needs a bit of work when we want to
move the filters around, or if we wanted to be able to provide
the filters as a list, even though using &lt;em&gt;loop&lt;/em&gt; and &lt;em&gt;recur&lt;/em&gt; it
seems feasible.&lt;/p&gt;

&lt;p&gt;One of the gripes of such an approach is that you need two types
of middleware functions, those that happen before and those that
happen after an action, writing a generic timing filter that can
be plugged in anywhere would involve writing two filter functions!&lt;/p&gt;

&lt;p&gt;The other gripe is that there is no way to bypass the execution
of the filter chain, except by throwing exceptions, what we want
is to wrap around the command call to be able to interfere with the
processing.&lt;/p&gt;

&lt;p&gt;Looking back on the &lt;em&gt;rack&lt;/em&gt; approach, we see that the
call to the actual rack handler is enclosed within the middleware,
doing the same in clojure would involve returning a function wrapping
the original call, which is exactly what has been done for &lt;a href=&quot;https://github.com/mmcgrana/ring&quot;&gt;ring&lt;/a&gt;,
by the way:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;function-building.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;span class='line'&gt;18&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filter-required&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;required&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;some &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:fail&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:message&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;invalid payload&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filter-defaults&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defaults&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:unknown,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:guest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;merge &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defaults&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;time-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;start-ts&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class=&quot;nv&quot;&gt;end-ts&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;System/nanoTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;merge &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;:elapsed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;- &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;end-ts&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;start-ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}))))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Reusing the threading operator, building the composed handler is now dead
easy:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;threading - threaded-compositer.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;composed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;send-command&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                  &lt;span class=&quot;nv&quot;&gt;time-command&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                  &lt;span class=&quot;nv&quot;&gt;filter-defaults&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                  &lt;span class=&quot;nv&quot;&gt;filter-required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;Tying it all together&lt;/h3&gt;

&lt;p&gt;We have now reached the point where composition is very easy,
at the expense of a bit of overhead when writing wrappers.&lt;/p&gt;

&lt;p&gt;The last enhancement that could really help is being able to
provide a list of functions to decorate a function with which
would yield the composed handler.&lt;/p&gt;

&lt;p&gt;We cannot apply to &lt;em&gt;-&gt;&lt;/em&gt; since it is a macro, so we call
&lt;em&gt;loop&lt;/em&gt; and &lt;em&gt;recur&lt;/em&gt; to the rescue:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;wrap-with.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrap-with&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;all-decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cur-handler&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;         &lt;span class=&quot;nv&quot;&gt;decorators&lt;/span&gt;   &lt;span class=&quot;nv&quot;&gt;all-decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;decorators&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;recur&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cur-handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class=&quot;nv&quot;&gt;cur-handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Or as &lt;em&gt;scottjad&lt;/em&gt; noted:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;reduced.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrap-with&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;all-decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;reduce &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;%2&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;all-decorators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now, you see this function has no knowledge at all of the logic of handlers,
making it very easy to reuse in a many places, writing composed
functions is now as easy as:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;wrapped.clj &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='clj'&gt;&lt;div class='line'&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wrapped-command&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;wrap-with&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;send-command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;time-command&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filter-defaults&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filter-required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;I hope this little walkthrough helps you navigate more easily through
projects such as ring, compojure, and the likes. You'll see that
in many places using such a mechanism allows elegant test composition.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Introducing: TRON</title>
    <link href="http://spootnik.org/blog/2011/07/11/introducing-tron/"/>
    <updated>2011-07-11T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/07/11/introducing-tron</id>
    <content type="html">&lt;p&gt;I just uploaded a small library to github (and clojars), It&amp;rsquo;s a
generalisation of what I use for recurrent tasks in my clojure
programs, the fact that the recent pragprog &lt;a href=&quot;http://pragprog.com/magazines/2011-07/create-unix-services-with-clojure&quot;&gt;article&lt;/a&gt; had a
handrolled version of it too convinced me it was worth putting
together in a lib.&lt;/p&gt;

&lt;p&gt;The library provides an easy mechanism to register process for later
execution, either recurrent or ponctual. It is called TRON,
replacing&amp;rsquo;s CRON&amp;rsquo;s C which stands for command &amp;ndash; as in: command run on
&amp;ndash; with a T for task.&lt;/p&gt;

&lt;p&gt;Here is a short excerpt of what it can do:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;ns sandbox
  &lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;:require tron&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;defn- periodic &lt;span class=&quot;of&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;println &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;periodic&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;defn- ponctual &lt;span class=&quot;of&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;println &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ponctual&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;;; Run the fonction 10 seconds from now&lt;/span&gt;
&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;tron/once ponctual &lt;span class=&quot;i&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;;; Run the periodic function every second&lt;/span&gt;
&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;tron/periodically :foo periodic &lt;span class=&quot;i&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;;; Cancel the periodic run 5 seconds from now&lt;/span&gt;
&lt;span class=&quot;of&quot;&gt;(&lt;/span&gt;tron/once &lt;span class=&quot;of&quot;&gt;#(&lt;/span&gt;tron/cancel :foo&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;i&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;of&quot;&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The lcode is hosted on github: &lt;a href=&quot;https://github.com/pyr/tron&quot;&gt;https://github.com/pyr/tron&lt;/a&gt;, the full
annotated source can be found &lt;a href=&quot;http://spootnik.org/files/tron.html&quot;&gt;here&lt;/a&gt; and the artifacts are already
on clojars (see &lt;a href=&quot;http://clojars.org/tron&quot;&gt;here&lt;/a&gt;).
The library still needs a better way of expressing delays which will
be worked on, and might benefit from macros allowing you to embed the
body to be executed later. All in due time.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Some more thoughts on monitoring</title>
    <link href="http://spootnik.org/blog/2011/07/08/some-more-thoughts-on-monitoring/"/>
    <updated>2011-07-08T00:00:00+02:00</updated>
    <id>http://spootnik.org/blog/2011/07/08/some-more-thoughts-on-monitoring</id>
    <content type="html">&lt;p&gt;Lately, monitoring has been a trending topic from the devops crowd.
&lt;a href=&quot;http://www.devco.net/archives/2011/03/19/thinking_about_monitoring_frameworks.php&quot;&gt;ripienaar&lt;/a&gt; and &lt;a href=&quot;http://obfuscurity.com/2011/07/Monitoring-Sucks-Do-Something-About-It&quot;&gt;jason dixon&lt;/a&gt; amongst other have voiced what
many are thinking. They&amp;rsquo;ve done a good job describing what&amp;rsquo;s wrong and
what sort of tool the industry needs. They also express clearly the
need to part from a monolithic supervision solution and monolithic
graphing solution.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll take my shot at expressing what I feel is wrong in the current tools:&lt;/p&gt;

&lt;h3&gt;Why won&amp;rsquo;t you cover 90% of use cases&lt;/h3&gt;

&lt;p&gt;Supervision is hard, each production is different, and complex
business logic must be tested, so indeed, a monitoring tool must be
able to be extended easily, that&amp;rsquo;s a given and every supervision tool
got this right. But why on earth should tests that every production
will need be implemented as extensions ? Let&amp;rsquo;s take a look at the
expected value which is the less intrusive way to check for a
machine&amp;rsquo;s load average:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The nagios core engine determines that an snmp check must be run for a machine&lt;/li&gt;
&lt;li&gt;Fork, execute a shell which execs the check_snmp command&lt;/li&gt;
&lt;li&gt;Feed the right arguments to snmpget&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You think I am kidding ? I am not. Of course each machine needing a
check will need to go through this steps. So for as few as 20 machines
requiring supervision  at each check interval 60 processes would be
spawned. 60 processes spawned for what ? Sending 20 udp packets,
waiting for a packet in return. Same goes for TCP, ICMP, and many
more.&lt;/p&gt;

&lt;p&gt;But it gets better ! Want to check more than one SNMP OIDs on the same
machine ? The same process happens for every OID, which means that if
you have&lt;/p&gt;

&lt;p&gt;Now consider the common use case, what does a supervision and graphing
engine do most of its time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Poll ICMP&lt;/li&gt;
&lt;li&gt;Poll TCP &amp;ndash; sometimes sending or expecting a payload, say for HTTP or
SMTP checks&lt;/li&gt;
&lt;li&gt;Poll SNMP&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So for a simple setup of 20 machines, checking these simple services,
you could be well into the thousands of process spawning &lt;em&gt;every&lt;/em&gt; check
interval &lt;em&gt;per machine&lt;/em&gt;. If you have a reasonable interval, say 30
seconds or a minute.&lt;/p&gt;

&lt;p&gt;Add to that some custom hand written scripts in perl, python, ruby &amp;ndash;
or worse, bash &amp;ndash; to check for business logic and you end up having to
sacrifice a large machine (or cloud instance) for simple checks.&lt;/p&gt;

&lt;p&gt;That would be my number one requirement for a clean monitoring system:
Cover the simple use cases ! Better yet, do it asynchronously !
Because for the common use case, all monitoring needs to do is wait on
I/O. Every language has nice interfaces for handling evented I/O the
core of a poller should be evented.&lt;/p&gt;

&lt;p&gt;There are of course a few edge cases which make it hard to use that
technique, ICMP coming to mind since it requires root access on UNIX
boxes, but either privilege separation or a root process for ICMP
checks can mitigate that difficulty.&lt;/p&gt;

&lt;h3&gt;Why is alerting supposed to be different than graphing ?&lt;/h3&gt;

&lt;p&gt;Except from some less than ideal solutions &amp;ndash; looking at you
&lt;a href=&quot;http://zabbix.com&quot;&gt;zabbix&lt;/a&gt; &amp;ndash; Supervision and Graphing are most of the time two
separate tool suites, which means that in many cases, the same metrics
are polled several times. The typical web shop now has a cacti and
nagios installation, standard metrics such as available disk space
will be polled by cacti and then by nagios (in many cases through an
horrible private mechanism such as nrpe).&lt;/p&gt;

&lt;p&gt;Functionally speaking the tasks to be completed are rather simple:
* Polling a list of data-points
* Ability to create compound data-points based on polled values
* Alerting on data-point thresholds or conditions
* Storing time-series of data-points&lt;/p&gt;

&lt;p&gt;These four tasks are all that is needed for a complete monitoring and
graphing solution. Of course this is only the core of the solution and
other features are needed, but as far as data is concerned these four
tasks are sufficient.&lt;/p&gt;

&lt;h3&gt;How many times will we have to reinvent SNMP&lt;/h3&gt;

&lt;p&gt;I&amp;rsquo;ll give you that, SNMP sucks, the S in the name &amp;ndash; simple &amp;ndash; is a
blatant lie. In fact, for people running in the cloud, a collector
such as &lt;a href=&quot;http://collectd.org&quot;&gt;collectd&lt;/a&gt; might be a better option. But the fact that
every monitoring application &amp;ldquo;vendor&amp;rdquo; has a private non
inter-operable collecting agent is distressing to say the least.&lt;/p&gt;

&lt;p&gt;SNMP can rarely be totally avoided and when possible should be relied
upon. Well thought out, easily extensible collectors are nice
additions but most solutions are clearly inferior to SNMP and added
stress on machines through sequential, process spawning solutions.&lt;/p&gt;

&lt;h3&gt;A broken thermometer does not mean your healthy&lt;/h3&gt;

&lt;p&gt;(LLDP, CDP, SNMP) are very useful to make sure assumptions you make on
a production environment match the reality, they should never be the
basis of decisions or considered exhaustive.&lt;/p&gt;

&lt;p&gt;A simple analogy, using discovery based monitoring solutions is
equivalent to saying you store your machine list in a DNS zone file.
It should be true, there should be mechanisms to ensure it is true,
but might get out of sync over time: it cannot be treated as a source
of truth.&lt;/p&gt;

&lt;h3&gt;Does everyone need a horizontally scalable solution ?&lt;/h3&gt;

&lt;p&gt;I appreciate the fact that every one wants the next big tool to be
horizontally scalable, to distribute checks geographically. The thing
is, most people need this because a single machine or instance&amp;rsquo;s
limits are very easily reached with today&amp;rsquo;s solutions. A single
process evented check engine, with an embedded interpretor allowing
simple business logic checks should be small enough to allow matching
most peoples needs.&lt;/p&gt;

&lt;p&gt;This is not to say, once the single machine limit is reached, a
distributed mode should not be available for larger installations. But
the current trend seems to recommend using AMQP type transports (e.g:
which while still being more economic than nagios' approach will put
an unnecessary strain on singe machine setups and also raise the bar
of prerequisites for a working installation.&lt;/p&gt;

&lt;p&gt;Now as far as storage is concerned, there are enough options out there
to choose from which make it easy to scale storage. Time-series and
data-points are perfect candidates for non relational databases and
should be leveraged in this case. For single machine setups, RRD type
databases should also be usable.&lt;/p&gt;

&lt;h3&gt;Keep it decoupled&lt;/h3&gt;

&lt;p&gt;The above points can be addressed by using decoupled software. Cacti
for instance is a great visualization interface but has a strongly
coupled poller and storage engine, making it very cumbersome to change
parts of its functionality (for instance replacing the RRD storage
part).&lt;/p&gt;

&lt;p&gt;Even though I believe in making it easy to use single machine setups,
each part should be easily exported elsewhere or replaced. Production
setups are complex and demanding, each having their specific
prerequisites and preferences.&lt;/p&gt;

&lt;p&gt;Some essential parts stand out as easily decoupled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data-point pollers&lt;/li&gt;
&lt;li&gt;Data-point storage engine&lt;/li&gt;
&lt;li&gt;Visualization Interface&lt;/li&gt;
&lt;li&gt;Alerting&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Current options&lt;/h3&gt;

&lt;p&gt;There are plenty of tools which even though they need a lot of work to
be made to work together still provide a &amp;ldquo;good enough&amp;rdquo; feeling,
amongst those I have been happy to work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Nagios&lt;/em&gt;: The lesser of many evils&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Collectd&lt;/em&gt;: Nice poller which can be used from nagios for alerting&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Graphite&lt;/em&gt; (&lt;a href=&quot;http://graphite.wikidot.com&quot;&gt;http://graphite.wikidot.com&lt;/a&gt;) : Nice grapher which is inter-operable with collectd&lt;/li&gt;
&lt;li&gt;&lt;em&gt;opentsdb&lt;/em&gt; (&lt;a href=&quot;http://opentsdb.net&quot;&gt;http://opentsdb.net&lt;/a&gt;) : Seems like a step in the right direction but
requires a complex stack to be setup.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Final Words&lt;/h3&gt;

&lt;p&gt;Now of course if all that time spent writing articles was spent
coding, we might get closer to a good solution. I will do my best to
unslack(); and get busy coding.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Removing duplicate gems</title>
    <link href="http://spootnik.org/blog/2011/02/17/removing-duplicate-gems/"/>
    <updated>2011-02-17T00:00:00+01:00</updated>
    <id>http://spootnik.org/blog/2011/02/17/removing-duplicate-gems</id>
    <content type="html">&lt;p&gt;Found myself typing this in a shell:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;gem list --local | egrep '.*(.*,.*)' | sed 's/^\([^ ]*\) ([^,]*,\(.*\))/\1\2/' | sed 's/,//g' | awk '{for (i = 2; i &amp;lt;=NF ;i++) {printf &amp;quot;sudo gem uninstall %s --version=%s\n&amp;quot;, $1, $i}}'&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Sometimes perl or ruby with -e is just faster&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>pf: limits and extending collectd metrics</title>
    <link href="http://spootnik.org/blog/2011/02/17/pf-limits-and-extending-collectd-metrics/"/>
    <updated>2011-02-17T00:00:00+01:00</updated>
    <id>http://spootnik.org/blog/2011/02/17/pf-limits-and-extending-collectd-metrics</id>
    <content type="html">&lt;p&gt;When running pf firewalls and loadbalancers with relayd, some metrics
are critical. One thing that might not be obvious when looking at pf is
that the maximum number of sessions a firewall can handle is fixed, as
evidenced from looking at the output of &lt;code&gt;pfctl -si&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;Status: Enabled for 10 days 00:39:47             Debug: err

State Table                          Total             Rate
 current entries                        6               
 searches                         7970148            9.2/s
 inserts                            60227            0.1/s
 removals                           60221            0.1/s
Counters
 match                              67984            0.1/s
 bad-offset                             0            0.0/s
 fragment                               1            0.0/s
 short                                167            0.0/s
 normalize                              0            0.0/s
 memory                                 0            0.0/s
 bad-timestamp                          0            0.0/s
 congestion                             0            0.0/s
 ip-option                              0            0.0/s
 proto-cksum                            0            0.0/s
 state-mismatch                        34            0.0/s
 state-insert                           0            0.0/s
 state-limit                            0            0.0/s
 src-limit                              0            0.0/s
 synproxy                               0            0.0/s&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Now this can be compared to the limit values you have set which can be
queried through &lt;code&gt;pfctl -sm&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;states        hard limit   200000
src-nodes     hard limit    10000
frags         hard limit     5000
tables        hard limit     1000
table-entries hard limit   200000&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;In this particular example, the limit won&amp;rsquo;t be reached for a while!&lt;/p&gt;

&lt;p&gt;By default pf has a very low state limit to cope with machines with very
small amounts of RAM, OpenBSD still runs on VAX where 32m of RAM is a
lot. On a default install only 10k states are allowed, for a production
firewall this is likely to be too small really soon. To raise this limit
use the &lt;code&gt;set limit { states  }&lt;/code&gt;. My advice would be to start at
10000 and to raise appropriately if need be.&lt;/p&gt;

&lt;p&gt;Beware that once the state limit is reached, no new states will be
allowed to keep old ones functioning leading to a difficult debugging
situation.&lt;/p&gt;

&lt;p&gt;As a bonus, here is a simple github gist which implements statistics
collection for collectd, allowing you to graph state consumption and
alert when the limit is nearly reached.&lt;/p&gt;

&lt;p&gt;&lt;script src=&quot;https://gist.github.com/829791.js&quot;&gt;&lt;/script&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>puppet, extlookup and yamlvar</title>
    <link href="http://spootnik.org/blog/2011/02/05/puppet-extlookup-and-yamlvar/"/>
    <updated>2011-02-05T00:00:00+01:00</updated>
    <id>http://spootnik.org/blog/2011/02/05/puppet-extlookup-and-yamlvar</id>
    <content type="html">&lt;p&gt;When you dive in a complex project, even though you try to be as good as
possible with documentation, sometime you just miss things.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve had a good opportunity to realize this just recently while working
on puppet. A common head scratcher in puppet is finding a way to keep
system, technology and platform specifics separate. I will probably
write at length on this particular subject a bit later, but to give a
quick explanation, just consider this quick scenario:
* You host web servers for the same vhosts in two different locations
* You manage them with the same puppet instance
* They need a unique configuration
* Some details such as their name server change&lt;/p&gt;

&lt;p&gt;Puppet allows you to get to the point where you can just write this:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;class webserver {
    include unix
    include nginx

    nginx::upstream { rails_app:
        servers =&amp;gt; [&amp;quot;127.0.0.1:8000&amp;quot;, &amp;quot;127.0.0.1:8001&amp;quot;]
    }
    nginx::upstream_vhost { &amp;quot;www.example.com&amp;quot;:
        upstream    =&amp;gt; rails_app,
        listen      =&amp;gt; 80
    }
    nginx::static_vhost { &amp;quot;static.example.com&amp;quot;:
        root    =&amp;gt; &amp;quot;/srv/www/static.example.com&amp;quot;,
        listen  =&amp;gt; 80
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This is great, generic and allows you to deploy configurations to many
machines, so it&amp;rsquo;s a bit of a hassle to have to go through the trouble of
going through case statements just for DNS.&lt;/p&gt;

&lt;p&gt;&lt;script src=&quot;https://gist.github.com/810995.js&quot;&gt;&lt;/script&gt;&lt;/p&gt;

&lt;p&gt;This allows me do do clever local variables like these:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;head&quot;&gt;&lt;span class=&quot;head&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;ke&quot;&gt;order&lt;/span&gt;:  &lt;span class=&quot;s&quot;&gt;[ fqdn, operatingsystem ]&lt;/span&gt;
&lt;span class=&quot;ke&quot;&gt;values&lt;/span&gt;:
    &lt;span class=&quot;ke&quot;&gt;ns_server&lt;/span&gt;:
        &lt;span class=&quot;ke&quot;&gt;www01.remote.example.com&lt;/span&gt;: &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;10.1.1.1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;ke&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;10.1.2.1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And call them from classes like this:&lt;/p&gt;

&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;class unix {
    [...]
    $ns_server = yamlvar(ns_server)
    file { &amp;quot;/etc/resolv.conf&amp;quot;:
        owner =&amp;gt; root,
        group =&amp;gt; $root_group,
        mode =&amp;gt; 0644,
        content =&amp;gt; template(&amp;quot;unix/resolv.conf.erb&amp;quot;)
    }
    [...]
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Well this is all fine and dandy until I came upon this:
&lt;a href=&quot;http://www.devco.net/archives/2009/08/31/complex_data_and_puppet.php&quot;&gt;http://www.devco.net/archives/2009/08/31/complex_data_and_puppet.php&lt;/a&gt; .
That&amp;rsquo;s right, @ripienaar already did the work and guess what ?
&lt;a href=&quot;http://www.devco.net/archives/2010/09/14/puppet_261_and_extlookup.php&quot;&gt;http://www.devco.net/archives/2010/09/14/puppet_261_and_extlookup.php&lt;/a&gt;
it&amp;rsquo;s already in puppet 2.6.1 !&lt;/p&gt;
</content>
  </entry>
  
</feed>

