<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>metajack.im</title>
  <link rel="alternate" type="text/html" href="http://metajack.im/" />
  
  <id>http://metajack.im/atom.xml</id>
  <updated>2009-08-27T16:49:28Z</updated>
  <subtitle>a blog about startups and code</subtitle>

  
  
  
  <link rel="self" href="http://feeds.feedburner.com/metajack" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>Strophe Tutorial: Pubsub Weather Alert Demo</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/bClFsJUkE7s/" />
    <id>tag:metajack.im:/2009/08/27/strophe-tutorial-pubsub-weather-alert-demo/</id>
    <updated>2009-08-27T10:08:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Strophe has been getting more popular lately, and I keep finding it in new places. Boris Okner has just written an interesting demo application showing off the power of the real-time Web and Strophe. He didn't just stop with the demo, either; he has provided a detailed walk-through of how it...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;&lt;a href="http://code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt; has been getting more
popular lately, and I keep finding it in new places.  &lt;a href="http://rfid-ale.blogspot.com/"&gt;Boris
Okner&lt;/a&gt; has just written an &lt;a href="http://rfid-ale.blogspot.com/2009/08/real-time-web-applications-with-xmpp.html"&gt;interesting
demo
application&lt;/a&gt;
showing off the power of the real-time Web and Strophe.  He didn't
just stop with the demo, either; he has provided a &lt;a href="http://rfid-ale.blogspot.com/2009/08/xmpp-web-project-walkthrough.html"&gt;detailed
walk-through&lt;/a&gt;
of how it all works as well.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/weazard.png' width='400' alt='Weather Demo Screenshoot'/&gt;&lt;/p&gt;

&lt;p&gt;The demo is an imaginary system for weather alerting that allows users
to subscribe to various weather stations and receive updates in
real-time.  It uses Strophe and JavaScript for the front end and
&lt;a href="http://www.ejabberd.im"&gt;ejabberd&lt;/a&gt; and some custom
&lt;a href="http://www.erlang.org"&gt;Erlang&lt;/a&gt; modules for the back end.  The XMPP
API exposed by the server is similar to standard
&lt;a href="http://xmpp.org/tech/pubsub.shtml"&gt;XMPP pubsub&lt;/a&gt;, which can be browsed via
&lt;a href="http://xmpp.org/extensions/xep-0030.html"&gt;service discovery&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also really like Boris's description of XMPP's advantages to tackling this problem:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Another important thing is ability to reuse XMPP server
    features. For instance, there is no need to have separate database
    of registered users and their subscriptions, as this is already
    maintained by XMPP server. All changes in user's presence
    (i.e. logged in/out, disconnected) and component presence (restart,
    disconnection etc.) are also taken care of. It is possible to easily
    implement IM features, such as live support or chat between users.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'd add that if he had used standard pubsub, there is very little
protocol design work that needs to be done for this type of
application.  Pubsub and service discovery already have all the
standard usage models covered as well as many error cases.  It's a lot
easier to implement a well thought out protocol than to design your
own and re-discover all the non-obvious issues.&lt;/p&gt;

&lt;p&gt;Give Boris's demo application a spin if you're interested in what is
possible with the real-time Web and how it works.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/bClFsJUkE7s" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/08/27/strophe-tutorial-pubsub-weather-alert-demo/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>JavaScript Function Tricks for Making Callbacks Better</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/ZxeM1qoTLkU/" />
    <id>tag:metajack.im:/2009/08/06/javascript-function-tricks-for-making-callbacks-better/</id>
    <updated>2009-08-06T21:02:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Have you ever needed to pass an extra parameter to a library callback? Perhaps you were confused the first time your method callback was invoked but didn't have the right this pointer. Someone recently e-mailed me asking how to do this in Strophe, and I figured it was time to finally...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;Have you ever needed to pass an extra parameter to a library callback?
Perhaps you were confused the first time your method callback was
invoked but didn't have the right &lt;code&gt;this&lt;/code&gt; pointer.  Someone recently
e-mailed me asking how to do this in
&lt;a href="http;//code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt;, and I figured it was time
to finally write up the techniques I use to solve these problems.&lt;/p&gt;

&lt;p&gt;In these days of ever-larger JavaScript applications, callbacks have
become extremely common and important.  Unfortunately, JavaScript
doesn't have &lt;a href="http://stackoverflow.com/questions/114214/class-method-differences-in-python-bound-unbound-and-static/114267#114267"&gt;bound
methods&lt;/a&gt;
like Python and not every JavaScript library allows passing arbitrary
state to callbacks, so getting the right state in callbacks can be
irksome.  It doesn't have to be this way though; JavaScript has plenty
of primitives available to build tools that make callbacks easier.&lt;/p&gt;&lt;h2&gt;Bound Methods&lt;/h2&gt;

&lt;p&gt;In JavaScript, if you pass a method to a callback, that object that
the method belongs to is lost.  The &lt;code&gt;this&lt;/code&gt; pointer will be the
function object itself, not the actual object that it would be if you
called &lt;code&gt;obj.foo()&lt;/code&gt;.  You can make your own bound methods, though, and
some JavaScript implementations, like Firefox,  even have this built
in as &lt;code&gt;Function.prototype.bind()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;bind()&lt;/code&gt; method takes the function object it is called on, and
returns a new function object.  The new function will invoke the
original function with &lt;code&gt;this&lt;/code&gt; set to the parameter passed to &lt;code&gt;bind()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, to create a Python style bound method, you'd write:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var bound_method = some_obj.some_func.bind(some_obj);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now when &lt;code&gt;bound_method()&lt;/code&gt; is invoked, &lt;code&gt;some_func()&lt;/code&gt; will have access
to &lt;code&gt;some_obj&lt;/code&gt; through the &lt;code&gt;this&lt;/code&gt; pointer, exactly as if it had been
invoked as &lt;code&gt;some_obj.some_func()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is extremely useful because your code can store state in the
object as normal, and not have to worry about passing it along through
the callback chain.  When your method is invoked, it will know exactly
where to find the state it needs.&lt;/p&gt;

&lt;h2&gt;Prepending Arguments&lt;/h2&gt;

&lt;p&gt;A lot of frameworks pass a well known set of parameters to callback
functions, but sometimes, you need a little extra piece of
information.  Wouldn't it be nice if you could create a callback that
prepended some arguments to the libraries normal parameters?  You can!&lt;/p&gt;

&lt;p&gt;Here's an example using &lt;a href="http://code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
// non-standard stanza handler which takes an extra argument at the beginning
function on_message(response, message) {
    var m = $msg({to: message.getAttribute('from'), type: 'chat'})
                .c('body').text(response);
    connection.send(m);
}

// register the handler for different cases
connection.addHandler(on_message.prependArg('Hi!'), null, "message");
connection.addHandler(on_message.prependArg('Hola'), null, "message");
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Two &lt;code&gt;&amp;lt;message&amp;gt;&lt;/code&gt; stanza handlers are registered for the XMPP
connection; the first responds with "Hi!" and the second with
"Hola!".  &lt;code&gt;prependArg()&lt;/code&gt; is used to add an extra argument at the
beginning of &lt;code&gt;on_message()&lt;/code&gt;'s argument list.&lt;/p&gt;

&lt;p&gt;The code for &lt;code&gt;prependArg()&lt;/code&gt; appears below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
Function.prototype.prependArg = function (arg) {
    var func = this;

    return function () {
        var newargs = [arg];
        for (var i = 0; i &lt; arguments.length; i++)
            newargs.push(arguments[i]);
        return func.apply(this, newargs);
    };
};
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Strophe uses both &lt;code&gt;bind()&lt;/code&gt; and &lt;code&gt;prependArg()&lt;/code&gt; to make sure that
&lt;code&gt;XMLHttpRequest&lt;/code&gt; events are sent along with the proper state since hte
XHR implemenations don't allow passing along arbitrary data with
callbacks.  I found found &lt;code&gt;bind()&lt;/code&gt; to be extremely useful when trying
to build large JavaScript projects, as bound methods can make a lot of
tasks much easier.&lt;/p&gt;

&lt;p&gt;Please leave a comment if you have a favorite function manipulation
trick in JavaScript!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/ZxeM1qoTLkU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/08/06/javascript-function-tricks-for-making-callbacks-better/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Updated ejabberd-snapshot Packages for Jaunty and Intrepid</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/dVKomA9a-No/" />
    <id>tag:metajack.im:/2009/05/06/updated-ejabberdsnapshot-packages-for-jaunty-and-intrepid/</id>
    <updated>2009-05-06T16:57:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>My Launchpad PPA now has updated packages for ejabberd fresh from the Subversion repository. These are now available for both Intrepid Ibex and Jaunty Jackalope. For those of you running Intrepid, I also recommend you upgrade Erlang to R12B5 which is also available in my PPA. Next up on my list...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;My &lt;a href="https://launchpad.net/~metajack/+archive/ppa"&gt;Launchpad PPA&lt;/a&gt; now
has updated packages for &lt;a href="http://www.ejabberd.im"&gt;ejabberd&lt;/a&gt; fresh from
the &lt;a href="http://svn.process-one.net/ejabberd/trunk"&gt;Subversion
repository&lt;/a&gt;.  These are now
available for both Intrepid Ibex and Jaunty Jackalope.&lt;/p&gt;

&lt;p&gt;For those of you running Intrepid, I also recommend you upgrade
&lt;a href="http://www.erlang.org"&gt;Erlang&lt;/a&gt; to R12B5 which is also available in my
PPA.&lt;/p&gt;

&lt;p&gt;Next up on my list of packaging tasks is to make Erlang R13B packages
for Jaunty and to update the Wokkel packages to a recent version.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/dVKomA9a-No" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/05/06/updated-ejabberdsnapshot-packages-for-jaunty-and-intrepid/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Tape Your Stuff to the Web</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/zgExCm3E_-w/" />
    <id>tag:metajack.im:/2009/04/07/tape-your-stuff-to-the-web/</id>
    <updated>2009-04-07T10:40:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>I work on a lot of JavaScript projects that make heavy use of AJAX. Most of these need no server infrastructure except reverse proxies (due to JavaScript's same origin policy). I got tired of setting up nginx configuration files, so I wrote a simple Web server that publishes the current directory...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;I work on a lot of JavaScript projects that make heavy use of AJAX.
Most of these need no server infrastructure except &lt;a href="http://en.wikipedia.org/wiki/Reverse_proxy"&gt;reverse
proxies&lt;/a&gt; (due to
JavaScript's &lt;a href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;same origin
policy&lt;/a&gt;).  I got
tired of setting up &lt;a href="http://nginx.net"&gt;nginx&lt;/a&gt; configuration files, so
I wrote a simple Web server that publishes the current directory to
the Web along with reverse proxies.  I call it
&lt;a href="http://github.com/metajack/tape/tree/master"&gt;Tape&lt;/a&gt; because I use it
to tape my stuff to the Web.&lt;/p&gt;

&lt;p&gt;Tape is extremely easy to use.  Just type &lt;code&gt;tape&lt;/code&gt;, and the current
directory is accessible via &lt;code&gt;http://localhost:8273&lt;/code&gt; (8273 for
t-a-p-e).  Want to proxy your local
&lt;a href="http://www.xmpp.org/tech/bosh.shtml"&gt;BOSH&lt;/a&gt; connection manager? Type
&lt;code&gt;tape -P /xmpp-httpbind=http://localhost:5280/xmpp-httpbind&lt;/code&gt; and go!
You can also drop a &lt;code&gt;.taperc&lt;/code&gt; file with proxy information into the
current directory and Tape will use that so you don't have to type
much.&lt;/p&gt;

&lt;p&gt;Tape is inspired by &lt;a href="http://www.sproutcore.com"&gt;SproutCore's&lt;/a&gt;
&lt;code&gt;sc-server&lt;/code&gt; command.  While reading the change logs for SproutCore, I
noticed that this command recently got reverse proxy support. That
seemed like it would be incredibly useful for me, and Tape was born.&lt;/p&gt;

&lt;p&gt;Tape is written in &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt; and makes use of
&lt;a href="http://www.twistedmatrix.com"&gt;Twisted's&lt;/a&gt; Web server features.  It
clocks in at a little over 150 lines of code.&lt;/p&gt;

&lt;p&gt;This is going to my make development work flow so much simpler.  I hope
it will help you as well.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/zgExCm3E_-w" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/04/07/tape-your-stuff-to-the-web/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>jQuery and Strophe: Made for Each Other</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/I1YgOxAplmM/" />
    <id>tag:metajack.im:/2009/03/13/jquery-and-strophe-made-for-each-other/</id>
    <updated>2009-03-13T15:50:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Strophe is a beautiful library for building XMPP applications in JavaScript. It has a lot of nice features to help you build stanzas and respond to various event stanzas. It is built on top of the DOM, and unfortunately, the DOM is not always fun to work with. Luckily, we have...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;&lt;a href="http://code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt; is a beautiful library for
building XMPP applications in JavaScript.  It has a lot of nice
features to help you build stanzas and respond to various event
stanzas.  It is built on top of the DOM, and unfortunately, the DOM is
not always fun to work with.  Luckily, we have an excellent DOM slicer
and dicer that we can use alongside Strophe, the
&lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; library.&lt;/p&gt;&lt;h2&gt;The Hard Way&lt;/h2&gt;

&lt;p&gt;Let's take a look at what the code looks like for the traditional DOM
method of manipulating incoming XMPP stanzas.&lt;/p&gt;

&lt;p&gt;Our first example stanza handler is for receiving service discovery
information, or in XMPP parlance, &lt;code&gt;disco#info&lt;/code&gt; stanzas.  Our code will
pull out the feature information from the stanza, and pass that along
to someone else.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
function onDiscoInfoResult(stanza)
{
    var result = []
    var features = stanza.getElementsByTagName("feature");
    for (var i = 0; i &lt; features.length; i++) {
       result.push(features[i].getAttribute("var"));
    }

    doSomethingWithFeatures(result);
}
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The disco code isn't too bad, but the DOM gets a lot worse the more
complicated the manipulations.&lt;/p&gt;

&lt;p&gt;Next, let's look at Strophe's &lt;a href="http://code.stanziq.com/cgit/strophe/strophejs/tree/examples/echobot.js"&gt;echobot
example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
function onMessage(msg) {
    var to = msg.getAttribute('to');
    var from = msg.getAttribute('from');
    var type = msg.getAttribute('type');
    var elems = msg.getElementsByTagName('body');

    if (type == "chat" &amp;&amp; elems.length &gt; 0) {
        var body = elems[0];

        log('ECHOBOT: I got a message from ' + from + ': ' + 
            Strophe.getText(body));

        var reply = $msg({to: from, from: to, type: 'chat'}).cnode(body);
        connection.send(reply.tree());

        log('ECHOBOT: I sent ' + from + ': ' + Strophe.getText(body));
    }

    // we must return true to keep the handler alive.  
    // returning false would remove it after it finishes.
    return true;
}
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This still isn't terrible, but we can see already that there are a lot
of calls to long functions and dealing with the results of
&lt;code&gt;getElementsByTagName&lt;/code&gt;.  Looping has to be done manually.  If we need
a specific element of the hierarchy, then digging it out of the DOM is
pretty painful.&lt;/p&gt;

&lt;h2&gt;The Easy Way&lt;/h2&gt;

&lt;p&gt;jQuery makes DOM manipulations really, really simple.  You can dig out
very precise pieces of the DOM, manipulate them in aggregate, and it
even takes care of much of the pain of looping for you.&lt;/p&gt;

&lt;p&gt;Here are the same two examples using jQuery.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
function onDiscoInfoResult(stanza)
{
    var result = $(stanza).find('feature').map(function () {
        return $(this).attr("var");
    }).get();

    doSomethingWithFeatures(result);
}
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the disco info example, jQuery's &lt;code&gt;map()&lt;/code&gt; function has made it really
easy to grab a bunch of things at once, do something to them (in this
case, pulling out a specific attribute value), and then throw the
results into an array.&lt;/p&gt;

&lt;p&gt;Notice that jQuery is happy to take our XML stanzas as input, just by
passing them into the &lt;code&gt;$()&lt;/code&gt; function.  It then works just as normal,
except with our single stanza as its document instead of the HTML
page.&lt;/p&gt;

&lt;p&gt;Here's the echobot example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;pre name='code' class='javascript'&gt;
function onMessage(msg) {
    $(msg).find("message[type='chat'][from]:has(body)")
        .each(function () {
            var body = $(this).find("body:first").text();
            var from = $(this).attr("from");

            log('ECHOBOT: I got a message from ' + from + ': ' + body);

            var reply = $msg({to: from, type: "chat"})
                .c("body")
                .t(body);
            connection.send(reply.tree());

            log('ECHOBOT: I sent ' + from + ': ' + body);
        });
}
&lt;/pre&gt;

&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The jQuery code is shorter and clearer because it doesn't have to do
any of the busy work of dealing with DOM.  Using jQuery's powerful
selectors, we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;picked the correct element out of the stanza&lt;/li&gt;
&lt;li&gt;checked that the stanza made sense&lt;/li&gt;
&lt;li&gt;done nothing when the stanza doesn't match&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This code is actually more robust than the other version because we
never bothered to make sure there was a &lt;code&gt;from&lt;/code&gt; attribute originally.&lt;/p&gt;

&lt;h2&gt;jQuery is not Just the Inspiration&lt;/h2&gt;

&lt;p&gt;jQuery's design has certainly influenced Strophe, most notably with
the builder syntax.  It is not just an inspiration, however, as its
powerful selectors and looping make it perfect for using to slice and
dice incoming XMPP stanzas.&lt;/p&gt;

&lt;p&gt;I'm sure it was never intended for such a purpose, but it is a
testament to jQuery's good design that it just works, even in domains
that are unexpected.&lt;/p&gt;

&lt;p&gt;I have to say that working with XMPP stanzas in JavaScript is by far
my preferred environment due to jQuery's powerful selectors and
Strophe's really convenient builders.  I hope that this will
eventually find its way into Python, Ruby, Erlang, and other languages
that do heavy XMPP lifting.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/I1YgOxAplmM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/03/13/jquery-and-strophe-made-for-each-other/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Strophe in Action: Drop.io's Awesome XMPP Powered App</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/VTFdzVI-4dM/" />
    <id>tag:metajack.im:/2009/03/12/awesome-demo-of-real-time-xmpp-powered-app/</id>
    <updated>2009-03-12T16:19:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Drop.io just announced that their collaboration service is now a real time Web application. I got word from them that this amazing new stuff is powered by XMPP via Strophe. They have certainly added a lot of elbow grease, passion, and magic on top to make this possible, but this is...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;&lt;a href="http://drop.io"&gt;Drop.io&lt;/a&gt; just
&lt;a href="http://drop.io/blog/asset/your-drops-are-now-alive-private-filesharing-and-collaboration-goes-truly-real-time"&gt;announced&lt;/a&gt;
that their collaboration service is now a real time Web application.
I got word from them that this amazing new stuff is powered by
&lt;a href="http://xmpp.org"&gt;XMPP&lt;/a&gt; via 
&lt;a href="http://code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt;.  They have certainly added
a lot of elbow grease, passion, and magic on top to make this
possible, but this is a terrific example of what I envision with XMPP
powered Web applications.&lt;/p&gt;

&lt;p&gt;To get the full effect, I highly recommend watching their &lt;a href="http://drop.io/file/streaming"&gt;real time
demo screencast&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;They have this to say about the technical details:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Using the Jabber (XMPP) protocol and through a chain of events mediated by JavaScript, BOSH and XMPP drops are now updated for all users viewing that drop in real-time. We are using ejabberd, which is known for its high level of compliance with XMPP. On the front end we use the Strophe javascript library, which uses  a technique called Bidirectional-streams Over Synchronous HTTP (BOSH) to connect to a Jabber server.&lt;/p&gt;
    
    &lt;p&gt;Each drop is assigned its very own chat room on our Jabber setup, and whenever a user views the drop, Strophe automatically logs the user into the drop’s chat room. Whenever an event such as a file creation occurs, drop.io's application servers send an XMPP message to the drop’s chat room describing the event.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not far off from the structure of
&lt;a href="http://www.chesspark.com"&gt;Chesspark&lt;/a&gt;, and shows just how powerful a
few XMPP technologies can be when combined well.  One neat side effect
of this is that they will have a public API for free that has robust
support in many languages already.  Maybe some day they will enable
Drop.io features in arbitrary chat rooms as well!&lt;/p&gt;

&lt;p&gt;Congratulations to the whole Drop.io team on a successful launch of a
very cool product!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/VTFdzVI-4dM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/03/12/awesome-demo-of-real-time-xmpp-powered-app/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Upcoming XMPP Talks and Events</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/gaeb5PU62hA/" />
    <id>tag:metajack.im:/2009/03/11/upcoming-xmpp-talks-and-events/</id>
    <updated>2009-03-11T13:48:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>There are a lot of XMPP events in the near future, and we'd love to see you at a few of them. The first XMPP Monthly Meeting (March 12) will be in the jdev@conference.jabber.org MUC room. Peter has posted more details here. The SXSW XMPP Meetup (March 17) will be in...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;There are a lot of XMPP events in the near future, and we'd love to
see you at a few of them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first XMPP Monthly Meeting (March 12) will be in the
jdev@conference.jabber.org MUC room.  &lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt; has
posted more details &lt;a href="https://stpeter.im/?p=2528"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The SXSW XMPP Meetup (March 17) will be in Austin, Texas.  Details can
be found on the &lt;a href="http://upcoming.yahoo.com/event/2122123/"&gt;meetup
page&lt;/a&gt;.  There are already
15 people going, and about the same amount marked as interested.
It's looking like it will be a great event.  Besides myself, there
will also be Julien from &lt;a href="http://notifixio.us"&gt;Notifixio.us&lt;/a&gt; and
Marcus from &lt;a href="http://minggl.com"&gt;Minggl&lt;/a&gt;.  I'm sure a lot of
interesting discussions will take place regarding XMPP and Web
applications.&lt;/li&gt;
&lt;li&gt;IETF 74 (March 22-27) will be in San Francisco, and two sessions
will have XMPP focused content, both on March 23rd.  The first is
the &lt;a href="http://www.ietf.org/proceedings/09mar/agenda/apparea.txt"&gt;App area open
meeting&lt;/a&gt;
in which we'll be talking about BOSH, WebSockets, and Bayeux.  The
second is the XMPP BOF session where various XMPP related topics
will be covered.  &lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt; and I will both be
there, and I believe some of the &lt;a href="http://www.isode.com"&gt;Isode&lt;/a&gt; guys
as well, one of whom is the first &lt;a href="http://xmpp.org"&gt;XSF&lt;/a&gt; member to
become an IETF Area Director.&lt;/li&gt;
&lt;li&gt;The all JavaScript &lt;a href="http://jsconf2009.com/"&gt;JSConf&lt;/a&gt; (April 24-25)
will be in Washington DC.  I'll be giving a presentation there on
building XMPP powered Web applications.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://gluecon.com"&gt;Glue conference&lt;/a&gt; (May 12-13) will be in
Denver.  XMPP makes for great glue, and accordingly,
&lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt; and I will be on a panel along with
others including &lt;a href="http://mojodna.net"&gt;Seth Fitzsimmons&lt;/a&gt; of Yahoo's
&lt;a href="http://fireeagle.yahoo.com"&gt;Fire Eagle&lt;/a&gt; team.  This conference
should be really great, and if you use the code "spkr09" to get a
$100 discount on the already cheap conference.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.oreilly.com/oscon2009"&gt;OSCON 2009&lt;/a&gt; (July 20-24) will be
in San Jose, CA this year instead of the usual Portland, OR
location.  The &lt;a href="http://xmpp.org"&gt;XSF&lt;/a&gt; is planning to have the 7th
XMPP Summit during the conference, and there are some &lt;a href="https://stpeter.im/?p=2532"&gt;XMPP related
talks&lt;/a&gt; shaping up.  It should be even
more fun than last year!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm sure this is not even a complete list; the number of events where
XMPP is popping up is growing every day.  Let me know if you've heard
of any that I've missed!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/gaeb5PU62hA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/03/11/upcoming-xmpp-talks-and-events/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>XMPP Complexity Versus Sophistication</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/37v96tIJQWI/" />
    <id>tag:metajack.im:/2009/03/09/xmpp-complexity-versus-sophistication/</id>
    <updated>2009-03-09T20:59:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Outside of the XMPP community a perception seems to exist that XMPP is too complex or too difficult, usually in reference to HTTP. I don't believe this is an accurate perception, and I've been wanting to address it here for some time. Of course, simpler systems can be built, but in...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;Outside of the XMPP community a perception seems to exist that XMPP is
too complex or too difficult, usually in reference to HTTP.  I don't
believe this is an accurate perception, and I've been wanting to
address it here for some time.  Of course, simpler systems can be
built, but in most cases, these simpler systems are missing critical
features such as security, extensibility, or maturity.  I think that
once these features are addressed, what you end up with will be
markedly similar to XMPP.&lt;/p&gt;&lt;h2&gt;Security&lt;/h2&gt;

&lt;p&gt;The original XMPP protocol was not nearly as secure, and because of this,
much simpler.  The &lt;a href="http://www.ietf.org"&gt;IETF&lt;/a&gt; required that we
address this issue when we went through the standardization process.
TLS, SASL, and other methods replaced ad-hoc SSL, plain text
authentication, and server dialback.  Any alternative protocol will
probably need to be similarly hardened.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://souja.net/"&gt;Jayson Vantuyl&lt;/a&gt; recently talked about this on the
&lt;a href="http://groups.google.com/group/cloudforum"&gt;CloudForum list&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;XMPP comes with a built-in, non-optional security mechanism.  This is
    really going to have to be a part of any Cloud.  Passing around
    authentication tokens is lovely and all, but having it at the
    transport level just makes a lot more sense.  After all, it's what
    HTTP does.  XMPP just makes it a bit easier to work with because it's
    not optional, not an afterthought, and uniformly accessible without
    regard to which server you're using (e.g. extending HTTP auth isn't
    realistic given all the servers out there).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Extensibility&lt;/h2&gt;

&lt;p&gt;I've seen several people mention recently that
&lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; might be a better encoding for something
like XMPP.  XML however, does offer several present day advantages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;XML tools and libraries are well deployed, well tested, and pretty
much ubiquitous.  JSON parsers are getting there, but still have a
ways to go.  Also, a JSON parser would need to accept streaming
data, and my guess is that few of them currently do, just as few XML
parsers used to deal with such data.&lt;/li&gt;
&lt;li&gt;XML namespacing provides the core of XMPP's extensibility.  This
does make the encoding more complex, but for good reason.  JSON
would have to develop something similar, but I think the XML
solution would look elegant in comparison.  It is easy to put new
elements and attributes in existing ones.  How does one do this in
a JSON array without breaking previous implementations?&lt;/li&gt;
&lt;li&gt;XML is human readable, making debugging easy.  This was a huge win
for HTTP.  Many times on the XMPP lists, developers can post short
snippets of wire traffic, and the problems are easily identified.
Here JSON is on the same page, but binary encodings are not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Maturity&lt;/h2&gt;

&lt;p&gt;It may seem strange at first to talk of XMPP's maturity, but the fact
is that many clever minds have been thinking and working on it for a
decade.  Each implementation comes with bugs, but these are rapidly
disappearing as well, just as they did for HTTP.&lt;/p&gt;

&lt;p&gt;A hypothetical new and simpler protocol would need to recreate a lot
of this work, especially in the area of publish-subscribe.  One thing
I've been very happy about with XMPP is that the hard work (designing
the protocol) has already been done.  I'm well equipped to create
plugins, fresh implementations, or bug fixes; protocols, on the other
hand, are quite hard to get right.&lt;/p&gt;

&lt;h2&gt;Design versus Implementation&lt;/h2&gt;

&lt;p&gt;I think people desire something simpler so that it is easier to
implement, but they don't always realize that the hard part is not the
implementation, but the protocol design.  It is an incorrect
optimization in many cases to design for ease of implementation by
subtracting robustness or sophistication.&lt;/p&gt;

&lt;h2&gt;XMPP is Beautiful and Getting Better&lt;/h2&gt;

&lt;p&gt;Once you get a connection established and authenticated, XMPP is
simple and beautiful.  With HTTP, getting to this point is fairly
trivial in 99% of cases, as authentication is usually ignored or that
sophistication is moved directly into the applications.&lt;/p&gt;

&lt;p&gt;I think what people are frustrated by is deploying XMPP and dealing
with the strict security requirements.  &lt;/p&gt;

&lt;p&gt;Deploying XMPP is getting better, just as HTTP did.  A decade ago,
getting Apache running was not huge fun.  Nowadays, almost everything
comes with a simple built in Web server.  It's not that HTTP is easy,
it's that the implementations and documentation for those
implementations improved dramatically.  XMPP is making huge strides on
these issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt;, in the same email thread as Jayson above,
offered this:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;If your complaint against XMPP technologies is that the
    existing software implementations can be difficult to deploy, then the
    solution is not to throw out all of the work that has been done over the
    last ten years to harden and secure XMPP's core layers and also develop
    numerous extensions to that core. Instead, the solution is to build a
    slimmed-down implementation in one of your preferred code languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People are starting to do just this.  We have
&lt;a href="http://wokkel.ik.nu"&gt;Wokkel&lt;/a&gt; (which will get folded into Twisted
Python), &lt;a href="http://prosody.im"&gt;Prosody&lt;/a&gt; (written in Lua), and
&lt;a href="http://synapse.malkier.net/"&gt;synapse&lt;/a&gt; (written in Ruby) already.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/37v96tIJQWI" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/03/09/xmpp-complexity-versus-sophistication/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>XMPP Meetup at SXSW 2009 in Austin</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/ed_y3OwARwg/" />
    <id>tag:metajack.im:/2009/03/06/xmpp-meetup-at-sxsw-2009-in-austin/</id>
    <updated>2009-03-06T10:10:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>If you're interested in XMPP and will be in Austin on March 17th, 2009, please join us at the XMPP meetup. Everyone is welcome, XMPP users, developers, and anyone who is interested in learning more. I've been trying to organize an XMPP meetup in Austin during SXSW, and thanks to the...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;If you're interested in &lt;a href="http://www.xmpp.org"&gt;XMPP&lt;/a&gt; and will be in
Austin on March 17th, 2009, please join us at the &lt;a href="http://upcoming.yahoo.com/event/2122123"&gt;XMPP
meetup&lt;/a&gt;.  Everyone is
welcome, XMPP users, developers, and anyone who is interested in
learning more.&lt;/p&gt;

&lt;p&gt;I've been trying to organize an XMPP meetup in Austin during SXSW, and
thanks to the efforts of Marcus Irven of &lt;a href="http://minggl.com"&gt;Minggl&lt;/a&gt;
and the &lt;a href="http://conjunctured.com/"&gt;Conjunctured co-working space&lt;/a&gt;, the
event is officially happening.&lt;/p&gt;

&lt;p&gt;I'll be there with a few coworkers from &lt;a href="http://stanziq.com"&gt;Stanziq&lt;/a&gt;
and &lt;a href="http://www.chesspark.com"&gt;Chesspark&lt;/a&gt; along with Marcus from
&lt;a href="http://minggl.com"&gt;Minggl&lt;/a&gt;, and I believe there will be a few current
and former Googlers there as well.  &lt;/p&gt;

&lt;p&gt;Please let me know if you'd like to do a small presentation on
something cool you are working on.  I hope to meet some new people and
have a great time talking about XMPP.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/ed_y3OwARwg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/03/06/xmpp-meetup-at-sxsw-2009-in-austin/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>An Octavo of Stanzas</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/q-bV51KEV9k/" />
    <id>tag:metajack.im:/2009/02/17/an-octavo-of-stanzas/</id>
    <updated>2009-02-17T23:00:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>While at FOSDEM, Peter suggested that XMPP needs a collective noun for stanzas. We have a pack of dogs, a herd of cattle, and (my favorite) a murder of crows. Two good ideas were suggested: an octavo of stanzas or a folio of stanzas See Wikipedia for the meanings of octavo...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;While at &lt;a href="http://www.fosdem.org"&gt;FOSDEM&lt;/a&gt;, &lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt;
suggested that XMPP needs a collective noun for stanzas.  We have a
pack of dogs, a herd of cattle, and (my favorite) a murder of crows.&lt;/p&gt;

&lt;p&gt;Two good ideas were suggested:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;an &lt;strong&gt;octavo&lt;/strong&gt; of stanzas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;a &lt;strong&gt;folio&lt;/strong&gt; of stanzas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;See &lt;a href="http://www.wikipedia.org"&gt;Wikipedia&lt;/a&gt; for the meanings of
&lt;a href="http://en.wikipedia.org/wiki/Octavo_(book)"&gt;octavo&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Folio"&gt;folio&lt;/a&gt;. Personally, I like the former.  What about you?&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/q-bV51KEV9k" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/02/17/an-octavo-of-stanzas/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Some Thoughts on Serialization</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/EmUcFQAGEe8/" />
    <id>tag:metajack.im:/2009/02/16/some-thoughts-on-serialization/</id>
    <updated>2009-02-16T20:00:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>I've written before that XML serialization tends to be the main bottleneck in XMPP apps. I haven't benchmarked other software stacks that involve serialization, but I'm guessing it's expensive everywhere. Here are some thoughts on serialization that I've had recently. Eliminating serialization is better than making it faster. This is an...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;I've &lt;a href="http://metajack.im/2009/01/18/speed-up-ejabberd/"&gt;written&lt;/a&gt;
&lt;a href="http://metajack.im/2009/01/26/make-your-twisted-xmpp-apps-scream/"&gt;before&lt;/a&gt;
that XML serialization tends to be the main bottleneck in XMPP apps.
I haven't benchmarked other software stacks that involve
serialization, but I'm guessing it's expensive everywhere.  Here are
some thoughts on serialization that I've had recently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Eliminating serialization is better than making it faster.  This is
an obvious statement, but getting rid of serialization is not always
easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The XMPP &lt;a href="http://xmpp.org/extensions/xep-0114.html"&gt;component
protocol&lt;/a&gt; adds two
serialization steps in most cases.  One serialization to send data
to the component over the socket and one for the components response
back to the server.  If you want to avoid this extra work, the
component logic should be implemented in a server native fashion
such as an &lt;a href="http://www.ejabberd.im"&gt;ejabberd&lt;/a&gt; module.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using XMPP over some other protocol stack will probably add
serialization costs.  For example, you might implement an XMPP
pubsub service on top of an &lt;a href="http://www.amqp.org"&gt;AMQP&lt;/a&gt; based
backend.  This means that you have an extra serialization cost of
converting to the other protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;As everyone optimizes their code, we'll see more and more native
serialization plugins, application code that speaks server native
data structures, and application code that passes around already
serialized chunks (the original data off the wire).
&lt;a href="http://code.stanziq.com/punjab"&gt;Punjab&lt;/a&gt; with
&lt;a href="http://github.com/metajack/cserialize/tree/master"&gt;cserialize&lt;/a&gt; is
an example of an application using a native serializer and passing
around already serialized chunks.&lt;/li&gt;
&lt;/ul&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/EmUcFQAGEe8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/02/16/some-thoughts-on-serialization/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Make Your Twisted XMPP Apps Scream</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/ti0Fd-u38q8/" />
    <id>tag:metajack.im:/2009/01/26/make-your-twisted-xmpp-apps-scream/</id>
    <updated>2009-01-26T23:50:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>XML serialization tends to be the most expensive part of many XMPP applications, and Twisted Python apps are no exception. Now you're Twisted apps can scream with a new C based XML serializer for Twisted. Note: To speed up ejabberd, please see Speed Up Ejabberd, which talks about a similar solution...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;XML serialization tends to be the most expensive part of many
&lt;a href="http://www.xmpp.org"&gt;XMPP&lt;/a&gt; applications, and &lt;a href="http://www.twistedmatrix.com"&gt;Twisted
Python&lt;/a&gt; apps are no exception.  Now
you're Twisted apps can scream with a new &lt;a href="http://github.com/metajack/cserialize"&gt;C based XML serializer for
Twisted&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; To speed up &lt;a href="http://www.ejabberd.im"&gt;ejabberd&lt;/a&gt;, please see
&lt;a href="http://metajack.im/2009/01/18/speed-up-ejabberd/"&gt;Speed Up Ejabberd&lt;/a&gt;,
which talks about a similar solution for &lt;a href="http://www.erlang.org"&gt;Erlang&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The standard serialization code in Twisted can process approximately
2,100 elements per second on my Macbook Pro.  It's not great, but it's
a reasonable start.&lt;/p&gt;

&lt;p&gt;A few years ago my team and I spent a few days improving this code.
The result was a &lt;a href="http://twistedmatrix.com/trac/ticket/2477"&gt;pair of
patches&lt;/a&gt; that traded off
memory for speed by caching serialized fragments.  This code can
process about 3,150 elements per second on the same machine.  This is
an improvement factor of 1.5.&lt;/p&gt;

&lt;p&gt;Last week, the Twisted team improved this work in preparation for
merging it into the code base.  They managed to achieve about 3,700
elements per second - an improvement factor of 1.75x over the original
code.&lt;/p&gt;

&lt;p&gt;While they were working on this, I realized that it would be fairly
easy to write a C module that could serialize the Twisted XML objects
directly.  It took a little longer than expected, but you can find
such a serializer at the &lt;a href="http://github.com/metajack/cserialize"&gt;cserialize GitHub
page&lt;/a&gt;.  This code achieves over
7,500 elements per second, which is a factor of 3.5x faster than the
original code.  &lt;/p&gt;

&lt;p&gt;I've yet to really optimize this code, so I think more
gains can be made.  I'm hopeful that I can make it about twice as fast
as it is now.  My original version, which was missing namespace
support, was about 15 times faster than the original Python code.  I'm
not quite sure where the slow down came from, but as soon as I figure
out how to profile Python C modules, I'll track it down.&lt;/p&gt;

&lt;p&gt;This code is fresh, but it passes almost all of the Twisted tests.
The few that don't pass appear to be legitimate bugs in the test
cases, not the serialization code.&lt;/p&gt;

&lt;p&gt;I've created &lt;a href="http://twistedmatrix.com/trac/ticket/3633"&gt;bug #3633&lt;/a&gt; to
try and get this integrated upstream.  In the meantime, we'll be
enjoying our faster games at &lt;a href="http://www.chesspark.com"&gt;Chesspark&lt;/a&gt; and
speedier searches at &lt;a href="http://www.stanziq.com"&gt;Stanziq&lt;/a&gt;.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/ti0Fd-u38q8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/01/26/make-your-twisted-xmpp-apps-scream/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>We Don't Need No Stinkin' Web Frameworks</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/ShgfcdY2b-M/" />
    <id>tag:metajack.im:/2009/01/25/we-dont-need-no-stinkin-web-frameworks/</id>
    <updated>2009-01-25T23:06:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>Web frameworks can be nice, but they can also get in your way. One of the pleasant side effects of implementing more and more functionality over XMPP is that we've eliminated the need for Web frameworks at Stanziq. This is extremely liberating. How do we survive without them? Here are some...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;Web frameworks can be nice, but they can also get in your way.  One of
the pleasant side effects of implementing more and more functionality
over XMPP is that we've eliminated the need for Web frameworks at
&lt;a href="http://www.stanziq.com"&gt;Stanziq&lt;/a&gt;.  This is extremely liberating.&lt;/p&gt;

&lt;p&gt;How do we survive without them?  Here are some of the ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web frameworks may offer a lot of functionality, but XMPP has a
excellent, diverse set of extensions that offer a higher layer to
application developers.  Web frameworks are still essentially stuck
on basic protocol plus ad-hoc commands.  XMPP provides pubsub,
presence, discovery, and much more.&lt;/li&gt;
&lt;li&gt;Communication is done via XMPP through
&lt;a href="http://code.stanziq.com/strophe"&gt;Strophe&lt;/a&gt; instead of polling
a database or using work queues.  This is a step up in efficiency.&lt;/li&gt;
&lt;li&gt;Configuration is stored in pubsub nodes instead of relational
databases.  One awesome consequence of this is that all subscribers
get instant notification of configuration changes, sort of like a
broadcast &lt;code&gt;SIGHUP&lt;/code&gt;.  &lt;/li&gt;
&lt;li&gt;Front end apps, administrative code, and internal utilities are all
just JavaScript.  This makes them trivial to develop and test
locally, and we don't need any special deployment code.&lt;/li&gt;
&lt;li&gt;The whole system is more decoupled because there is no middle
interfacing layer.  The backend speaks XMPP, the frontend speaks
XMPP, and they both use standard XMPP layer protocols to do work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, this isn't the right fit for every problem; Web frameworks
solve a lot of problem domains quite well.  For those areas where it
fails, it sure is nice to avoid the hassle and use an XMPP only stack.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/ShgfcdY2b-M" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/01/25/we-dont-need-no-stinkin-web-frameworks/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Some Thoughts on Logging</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/nfdSwluQ0dk/" />
    <id>tag:metajack.im:/2009/01/24/some-thoughts-on-logging/</id>
    <updated>2009-01-24T23:30:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>I'm not a huge fan of syslog. It works well enough for logging on the local host, but it has been extremely fragile for us when logging from several hosts. One thing we have been thinking about at Stanziq is trying to find a better solution. There are tools like Spread...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;I'm not a huge fan of syslog.  It works well enough for logging on the
local host, but it has been extremely fragile for us when logging from
several hosts.  One thing we have been thinking about at
&lt;a href="http://stanziq.com"&gt;Stanziq&lt;/a&gt; is trying to find a better solution.&lt;/p&gt;

&lt;p&gt;There are tools like &lt;a href="http://spread.org/"&gt;Spread&lt;/a&gt; or protocols like
&lt;a href="http://amqp.org"&gt;AMQP&lt;/a&gt;.  The basic idea behind these tools is
publish-subscribe, so it should be no surprise that
&lt;a href="http://www.xmpp.org"&gt;XMPP&lt;/a&gt; fits this problem domain well.  This idea
came from &lt;a href="http:/identi.ca/kshep"&gt;Ken&lt;/a&gt; during a conversation we had
about logging infrastructure; I was still looking at the list of
possible solutions when he made the obvious connection.&lt;/p&gt;

&lt;p&gt;XMPP offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;publish subscribe semantics&lt;/li&gt;
&lt;li&gt;reliable delivery&lt;/li&gt;
&lt;li&gt;baked in presence&lt;/li&gt;
&lt;li&gt;multiple server implementations and client libraries in every
language&lt;/li&gt;
&lt;li&gt;a whole suite of tools for managing commands, configuration, and
extensibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some people might argue that solutions like AMQP are better, and for
this, I think &lt;a href="http://stpeter.im"&gt;Peter&lt;/a&gt; has summed it up well in his
post on &lt;a href="https://stpeter.im/?p=2099"&gt;AMQP and XMPP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I look forward to playing with a new XMPP based logging system, and
I'm sure I'll post more about it as it starts to materialize.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/nfdSwluQ0dk" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/01/24/some-thoughts-on-logging/</feedburner:origLink></entry>
  
  
  
  <entry>
    <title>Blogging with Git, Emacs, and Jekyll</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/metajack/~3/6GoQShVkkiM/" />
    <id>tag:metajack.im:/2009/01/23/blogging-with-git-emacs-and-jekyll/</id>
    <updated>2009-01-23T22:22:00Z</updated>
    <updated />

    <author>
      <name>Jack Moffitt</name>
      <uri>http://metajack.im</uri>
      <email>jack@metajack.im</email>
    </author>

    <summary>A few months back I switched this blog to Jekyll. Jekyll is a static blog generator; it transforms a directory of input files into another directory of files suitable for a blog. The management of the blog is handled by standard, familiar tools like creating and renaming files, the text editor...</summary>
    <content type="html" xml:lang="en" xml:base="http://metajack.im/">
      &lt;p&gt;A few months back I switched this blog to
&lt;a href="http://github.com/mojombo/jekyll/tree/master"&gt;Jekyll&lt;/a&gt;.  Jekyll is a
static blog generator; it transforms a directory of input files into
another directory of files suitable for a blog.  The management of the
blog is handled by standard, familiar tools like creating and renaming
files, the text editor of your choice, and version control.  Jekyll
combined with Git and Emacs has made blogging feel very natural to me.&lt;/p&gt;

&lt;h2&gt;What is WordPress, Really?&lt;/h2&gt;

&lt;p&gt;WordPress and other blogging systems are simplified content management
systems.  Many of the features they provide relate to a blog's minimal
need for dynamic content.  The front page needs to change as new
things are added, and each post must change as comments, trackbacks,
and edits are made.&lt;/p&gt;

&lt;p&gt;Along they way they often made it harder to just write.  While they
keep providing more and more sophisticated text editing capabilities,
most of us who write or code are quite comfortable in our own
editors.  No matter how good the text editing widgets become, they are
not Emacs or vim or TextMate.&lt;/p&gt;

&lt;p&gt;Blogs have simple APIs for using external products, but even these
products are often not great text editors.  When the real text editors
have added the ability to speak these APIs, the functionality feels
bolted on and clunky.  The reason is that we are used to interacting
with documents in a file system, and the current blogging APIs are
much less elegant than the familiar, simple API of a file system.&lt;/p&gt;

&lt;p&gt;Managing documents is something nearly everyone using a computer has
gotten quite good at, and the tool support for this is immense.  We
have automatic indexing systems like Spotlight, powerful search tools
like &lt;code&gt;grep&lt;/code&gt;, and history tracking and analysis tools like
&lt;a href="http://git.or.cz"&gt;Git&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;WordPress and others would do well to concentrate on the areas where
blogging software is really needed and expose the document management
part via &lt;a href="http://www.webdav.org/"&gt;WebDAV&lt;/a&gt; or something similar.  In
the end, WordPress is a transformation layer to take some set of
documents and turn it into a blog as well as a system to provide
commenting, trackbacks, and search.&lt;/p&gt;

&lt;h2&gt;The Post-WordPress World&lt;/h2&gt;

&lt;p&gt;Let's look at the key areas where blogging software is necessary.  We
have transformation of content, interaction with content (commenting
and such features), and search.  In all these areas superior, domain
specific tools have emerged.&lt;/p&gt;

&lt;p&gt;Search is dominated by Google, but there are other services that can
also be used.  I have been really underwhelmed by the search
capabilities found in self-hosted blogs, but Google's site search is
really good.&lt;/p&gt;

&lt;p&gt;Interaction services started appearing as spam became a problem for
blog comments.  Now we have full featured services like
&lt;a href="http://intensedebate.com/"&gt;IntenseDebate&lt;/a&gt; and
&lt;a href="http://disqus.com/"&gt;Disqus&lt;/a&gt; which provide excellent interaction
features like email integration, comment aggregation, moderation and
filtering, and portable identity.&lt;/p&gt;

&lt;p&gt;Now we come to transformation of content, which turns out to be the
only missing piece that on really needs.&lt;/p&gt;

&lt;h2&gt;Jekyll Generates Blogs&lt;/h2&gt;

&lt;p&gt;Jekyll fills this last piece of the blogging feature puzzle.  It takes
a tree of documents and transforms that into a blog.&lt;/p&gt;

&lt;p&gt;At a basic level, Jekyll goes through the directory tree and
translates files from a variety of formats like
&lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; and
&lt;a href="http://www.textism.com/tools/textile/"&gt;Textile&lt;/a&gt; into HTML.  Each file
can contain a small &lt;a href="http://www.yaml.org"&gt;YAML&lt;/a&gt; header with metadata.
These metadata blocks tell Jekyll which template to use during
rendering and define the title and other properties of the document.&lt;/p&gt;

&lt;p&gt;A few directories in Jekyll are special.  &lt;code&gt;_posts&lt;/code&gt; contains all the
blog posts, with each post being named in a common format such as
&lt;code&gt;2009-01-14-blogging-with-git-emacs-and-jekyll.markdown&lt;/code&gt;.  &lt;code&gt;_drafts&lt;/code&gt;
contains documents that are ignored by Jekyll.  &lt;code&gt;_layouts&lt;/code&gt; contains
rendering templates that are used during the transformation process.&lt;/p&gt;

&lt;p&gt;My own templates use Disqus for comments and Google for search, but it
is easy to mix and match the services you want in your own templates.&lt;/p&gt;

&lt;p&gt;The resulting generated site has a standard URL structure of
&lt;code&gt;/2009/01/14/blogging-with-git-emacs-and-jekyll/&lt;/code&gt; and the front page
and RSS or Atom feeds are just simple templates that loop over the
latest group of posts.&lt;/p&gt;

&lt;h2&gt;Managing and Publishing with Jekyll&lt;/h2&gt;

&lt;p&gt;You can use Jekyll by hand, but it is meant to be used alongside a
version control system.  Whenever you commit or push to the
repository, it runs the &lt;code&gt;jekyll&lt;/code&gt; command to generate the blog from the
latest data.&lt;/p&gt;

&lt;p&gt;Git is a popular choice here, but
&lt;a href="http://subversion.tigris.org"&gt;Subversion&lt;/a&gt; or
&lt;a href="http://bazaar-vcs.org"&gt;Bazaar&lt;/a&gt; would also do a fine job.  One thing I
like about Git is that I can set up a remote on my main machine to my
Eee laptop, and a corresponding remote in the other direction.  Both
machines have the &lt;em&gt;origin&lt;/em&gt; remote set to my blog's server.  This means
I can easily push and pull the blog around between machines and I
always have access to the entire blog no matter what machine I'm on.&lt;/p&gt;

&lt;p&gt;I also wrote &lt;a href="http://metajack.im/2009/01/02/manage-jekyll-from-emacs/"&gt;some Emacs
glue&lt;/a&gt; to help
automate my own blogging workflow.  I start new drafts with &lt;code&gt;C-c b n&lt;/code&gt;
and then move drafts to the &lt;code&gt;_posts&lt;/code&gt; folder with &lt;code&gt;C-c b P&lt;/code&gt;.  I can
also easily access the list of drafts or posts when I'm searching for
something I've previously written.  This kind of glue is easy to write
in any language because it leverages the familiar platform of the file
system.&lt;/p&gt;

&lt;h2&gt;Why I Love This System&lt;/h2&gt;

&lt;p&gt;Now that I've been using this system for several weeks, I'm really
loving it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm using the same tools I always use for the rest of my work to
write and manage my writing.&lt;/li&gt;
&lt;li&gt;I always have access to my entire blog, which is awesome when I am
crafting posts on plane rides and need to reference some previous
content.&lt;/li&gt;
&lt;li&gt;If I find some manual thing in my workflow, I can use any number of
common tools to automate or customize it.  Everything is just text
and files.&lt;/li&gt;
&lt;li&gt;Comments are now just email threads to me, which means I don't have
to use some clunky interface.  Once again, I can use tools which are
already part of my daily work habits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've ever thought about blogging, or blogging more, but didn't
want to mess around with blogging clients, Web interfaces, or
installing or maintaining blogging software, you should give Jekyll a try.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/metajack/~4/6GoQShVkkiM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://metajack.im/2009/01/23/blogging-with-git-emacs-and-jekyll/</feedburner:origLink></entry>
  
</feed>
