<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Cold Hard Code, Purveyors of Fine Internet Properties</title>
        <link>http://www.coldhardcode.com/blog/</link>
        <description></description>
        <language>en-us</language>
        <copyright>Copyright 2012</copyright>
        <lastBuildDate>Wed, 09 Feb 2011 10:30:58 -0800</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>On Languages and Beasts</title>
            <description><![CDATA[<p>When talking about programming languages it is very easy to ignite an ignoble fire. Zealots abound, haters hate and misinformation is rampant. It's just the way it works. Programming languages have cult like followings. That's why it's unusual to see small shops spreading out over multiple languages. This is unfortunate, because by simply knowing more languages the toolchain is larger and the way problems are thought of and solved changes.</p><p>
Now, it's no secret that we are predominately Perl developers.  We go to Perl conferences and have fun there.  However we also use a lot of other languages, most commonly Scala. In our applications we expect to see Java and Perl happily coexisting.  While we're not as active in the non-Perl communities we try to keep informed.</p><p>
With Jarvis, our <a href="http://jarvisapp.com">asset tracking application</a>, the core feature is it's ability to have completely arbitrary but well-defined and typed documents. It was tough to decide if the foundation model was going to be Scala or Perl based.  With previous work we had done in Perl on this subject Perl did come up as the default choice. We were able to leverage the power of Moose and the core Perl 5.x object model. We decided it was easier, and we are opinionated. We do not write Perl that doesn't use Moose and standard tools. It saves us a lot of <a href="http://ben.stupidfool.org/typepad/2011/02/perl-best-practices-and-language-design.html">frustration</a>.
</p><p>
Here's the features that Perl, with Moose, delivered that allowed us to build this thing out successfully:
</p><dl>
<dt>Mature MOP API, via Class::MOP</dt>
<dd>Jarvis uses anonymous classes to define document types, compiled and built at startup.  This means that every document type has its own class with full introspection and verification.  It's ended up with a nearly recursive like structure.</dd>
<dt>The best data verification utilities we've found (and made)</dt>
<dd>Moose delivers a type system into Perl that previously wasn't there.  We've combined that to create Data::Verifier, which allows constrained type verification with post checks and dependencies.  When you combine this with the class introspection discussed above, we get very solid data verification. It also serializes well, so we can store this data.</dd>
<dt>Well-supported storage APIs</dt>
<dd>Outside of serialization, we need to store things. The MongoDB Perl API is actively worked on and works very well (thanks 10gen!), and DBD::mysql is rock solid. We're also using DBIx::Class as an ORM to simplify the queries and decorate the RDBMS result sets to have a more similar API to the MongoDB-backed storage entities.</dd>
</dl>
<p></p><p>
But Perl isn't all there is. For the scheduled tasks and complex event processing we're entrenched in Scala.  We're using <a href="http://www.quartz-scheduler.org/">Quartz for the job scheduling</a> and distributed Scala jobs to inspect the data and emit messaging.  The messages are stored and transmitted between the Scala side and the Perl frontend without any issue.
</p><p>
With everything serialized into a common format that is easily processed and parsed we don't have any barriers.
</p><p>
The important thing is making sure that what gets into the system is of the highest quality possible.  Ultimately, this is why we insisted on Perl as the language of choice for handling user-input and user-interaction. The strengths of being able to have a flexible object oriented model along with tight type-based extensible data validation made it an easy choice.  One we're very happy with as well, as it's proven very effective.
The Scala jobs generally just access the data structure in a more raw form, but this is fine because everything is highly testable. It doesn't require the same level of attention as anything user-facing does. This also means that the Scala jobs are simpler and easier to work with.</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/02/on-languages.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/02/on-languages.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Jarvis</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Software Design</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">programming</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">programming languages</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">scala</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software</category>
            
            <pubDate>Wed, 09 Feb 2011 10:30:58 -0800</pubDate>
        </item>
        
        <item>
            <title>No One Trick Ponies - N(ot)O(nly)SQL</title>
            <description><![CDATA[<p>When any new fancy technology comes into existence, there is a desire to jump on it and use it to its fullest potential. Document databases are now reaching a level of maturity that any ol' developer can set them up, use them and have success. This is a good thing.</p>
<p>What isn't good is when that becomes the <em>only</em> tool you are using. All too often developers decide that any given new tool is exactly the only tool they need and proceed accordingly. NoSQL is another example of this.</p>
<p>When we built <a href="http://jarvisapp.com">Jarvis, our new asset manager</a>, we had already built <a href="http://codepeek.com">other products</a> to test some various ideas surrounding document-databases and implementation details. The real result is that we figured out that it's really quite trivial and still efficient to split between a traditional RDBMS and a Document database. In Jarvis, we do this by taking all the relational data out and storing it in the RDBMS (MySQL, in this case).</p>
<p>As we touched on briefly in <a href="http://www.coldhardcode.com/blog/2011/01/jarvis-technical-notes.html">our technical notes</a>, we store the User and Organization relationship information in MySQL. The Organization itself is a document and is stored in Mongo.</p>
<p>The Organization table in MySQL is simply a record that tells us what to look at and has some other denormalized data that we use to keep things a bit faster. This data is highly relational, because there are full permission sets both on the role of a person in the organization and the person's individual permissions (so we have two levels).</p>
<p>This is good because we can traverse the relationships from any permission and see what people directly and roles, then people have that. Doing something like this in a document database is certainly possible but it just doesn't make sense. This is relational data at the core, so we're using a relational storage.</p>
<p>Through a more sensible model class design (instead of just assuming that whatever <a href="http://www.catalystframework.og" target="_blank">web framework</a> we use is a good enough API) we have a standalone, useful API that can seamlessly cross between Mongo and MySQL without the application developer having to think much about it.</p>
<p>There are still some idioms based on what storage mechanism is in scope, but by and large it works very well.</p>
<p>This hybrid approach makes a lot of sense and the end result is very nice code, that's easy to follow and extend. &nbsp;I think we have done a very good job of minimizing any technical debt on a project in its very first stages.</p>
<p><em>(hat tip to <a href="http://bradfordw.posterous.com/a-kinder-more-functional-nashville">Bradford W.</a> on the title for NoSQL)</em></p>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/02/no-one-trick-ponies---notonlys.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/02/no-one-trick-ponies---notonlys.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">architecture</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">mysql</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nosql</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">programming</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">rdbm</category>
            
            <pubDate>Mon, 07 Feb 2011 06:23:37 -0800</pubDate>
        </item>
        
        <item>
            <title>Jarvis Development Process</title>
            <description><![CDATA[<p>We have a very simple method for quality control and deployment that is working well with us and scaling nicely.  We're using this with Jarvis, our new <a href="https://jarvisapp.com">asset management</a> service. Here is a brief overview of how we do it, with a pretty picture to illustrate the general flow.</p>

<img alt="Jarvis Development Overview" src="http://www.coldhardcode.com/uploads/JarvisDevelopment.png" width="395" height="340" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" />

<p>We work in topic branches, when ready for testing merge into a qa branch. After QA is complete, it gets merged into master.</p>

<p>We have git hooks in place that every commit to qa then relays and pushes to a series of configured hosts. Each host has a git repository configured to do what it should (update Solr configuration, restart the web application, etc.)  This system has worked very well for us, and we just setup per-branch rules on what hosts to push to.  This leverages the decentralization that git gives us and the ability to quickly rollback by just moving qa/master to a previous tag.</p>
 
<p>On that note, it's important to note that we use tags at all the appropriate points in this. We also are evaluating several continuous integration tools which will ultimately be the gatekeeper for what goes out the door.</p>

<p>This will just be an intermediary step where pushing into the master branch will fire off a CI process, and on successful build will release.</p>

<p>We will also have CI on the QA branch, which leads me into...</p>

<h3>The Problem</h3>
<p>One of our issues is we don't have a long-running development branch and waiting until we get changes into QA for CI to take hold defeats the entire purpose.  We're trying to figure out how any topic branch can have CI automatically apply.</p>
<p>
The easy and poor solution is having a post-update hook on the branches just set it up and auto-vivify the configuration. We'd like something just a little more formal and easier to track. Still evaluating options, but that's a sticking point we're trying to sort out now.
</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/01/jarvis-development-process.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/01/jarvis-development-process.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">deployment</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">git</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">jarvis</category>
            
            <pubDate>Tue, 25 Jan 2011 09:27:44 -0800</pubDate>
        </item>
        
        <item>
            <title>Jarvis Technical Notes</title>
            <description><![CDATA[<p>We've had some questions about how Jarvis is setup.  We're happy to talk a bit about that, especially since we've leveraged so many open source projects.</p>
<p>First I'd like to point out that we proudly detail all the bits we use on Jarvis' <a href="https://www.jarvisapp.com/about">About page</a>.  We'll do our best to keep that up to date as out technology and infrastructure grow.</p>
<p>Let's start off with a diagram:</p>
<img class="art-art" src="http://www.coldhardcode.com/static/images/jarvis/system-diag.png">
<p><a href="http://nginx.org/">nginx</a> starts things off.  It talks to Jarvis::Web, our <a href="http://www.catalystframework.org/">Catalyst</a> application.  We use <a href="http://mschilli.github.com/log4perl/">Log4perl</a> to direct logging to a few different log files. Early on we decided to log lots of user activity so that we could analyze it later and learn how our customers are using the site.</p>
<p>We chose a hybrid approach for data.  We store user and organization data in <a href="http://www.mysql.com/">MySQL</a> but asset information is in <a href="http://www.mongodb.org/">MongoDB</a>.  This lets us have a traditional schema for organizations having many users and users that have many organizations.  We chose a <a href="http://en.wikipedia.org/wiki/Document-oriented_database">document database</a> for our asset information because the "schema" we had in mind would be a hot mess in a relational database.  The freedom of a Mongo enables some really great features which we'll be unveiling over time.</p>
<p>One of those features is the ability to add sub-types to an asset.  You can choose Leased or Purchased and add more data.  We've used <a href="http://www.iinteractive.com/moose/">Moose</a> and some of it's extensions &mdash; roles and serialization &mdash; to create a powerful system for customizing your assets.</p>
<p>Lastly we come to <a href="http://lucene.apache.org/solr/">Solr</a>. It gives us amazing search capabilities that power our datatables in addition to the conventional search.  Let's not forget faceting, sorting and filtering!</p>
<p>Jarvis is built from components with a very strong pedigree.  We've leveraged dozens of open source projects, multiple programming languages and a vast array of technologies.  We look forward to adding more and making Jarvis even more awesome every week!</p>
<div id="product-footer">
 <h4>Jarvis: Stop Reacting and Start Planning</h4>
 <p>Jarvis is an asset management application with a big brain!  You should sign up and put in your assets.  We'll make it worth your while!</p>
 <a href="https://www.jarvisapp.com/register" class="submit_button blue">Sign Up For Jarvis</a>
</div>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/01/jarvis-technical-notes.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/01/jarvis-technical-notes.html</guid>
            
            
            <pubDate>Mon, 24 Jan 2011 19:50:20 -0800</pubDate>
        </item>
        
        <item>
            <title>Simple and useful YUI3: Checkbox Toggling</title>
            <description><![CDATA[<p>I had to write a simple checkbox toggle mechanism, which is a very common pattern in a datatable. You have one checkbox, and all other checkboxes in the same pattern should be selected (or deselected) with it. &nbsp;Nothing magic, there.</p>
<p>With YUI3's event delegation and Node API, I think this is the simplest mechanism I've built (and it only looks at elements in the containing form).</p>
<div><script src="https://gist.github.com/793558.js?file=checkbox-toggle.js"></script>
</div>
<p>Thanks <a href="http://yuilibrary.com">for an awesome JS lib</a>, Yahoo!.</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/01/simple-and-useful-yui3-checkbo.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/01/simple-and-useful-yui3-checkbo.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">events</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">html</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">javascript</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">programming</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">yui</category>
            
            <pubDate>Mon, 24 Jan 2011 09:20:51 -0800</pubDate>
        </item>
        
        <item>
            <title>Jarvis: Stop Reacting and Start Planning</title>
            <description><![CDATA[<p>Jarvis is an asset management application. Asset management is a
system for keeping track of the things you own, rent or lease. The
current focus of Jarvis is management of servers, but we've got much
bigger plans in mind. More on that later...</p>
<p>Today you can enter all your servers &mdash; along with a lot of data
&mdash; into Jarvis. Got a lot of them? No problem! You can use our
awesome search feature to find whatever you need. There is even a
sidebar of search facets to further refine your search to get exactly
what you want.</p>
<p>If you lease your servers we have some extra features. You can enter
the dates and prices to stay on top of that as well!</p>
<p>I mentioned we had bigger plans. I can't reveal them all yet, but
Jarvis will get smarter and smarter. Jarvis will ultimately be able to
help you plan for the future rather than reacting. How about a heads
up on an expiring lease, a notification of a system update or a hint
about a new line of servers?</p>
<p><a href="https://www.jarvisapp.com/register">Sign up</a> for Jarvis today and start entering your servers. <a href="http://coldhardcode.us1.list-manage.com/subscribe?u=d1748a57055b1cc77f7ef1551&id=d4c9fe3370">Sign up
for our newsletter</a> so we can let you know about the new features
we'll be adding every week. If you feel something is missing or have
some ideas then <a href="https://www.jarvisapp.com/support?type=Feedback">give us some feedback</a>.</p>
<p>We'll be writing more about Jarvis and pushing out new features as often as we can.  Thanks!</p>

<div id="product-footer">
 <h4>Jarvis: Stop Reacting and Start Planning</h4>
 <p>Jarvis is an asset management application with a big brain!  You should sign up and put in your assets.  We'll make it worth your while!</p>
 <a href="https://www.jarvisapp.com/register" class="submit_button blue">Sign Up For Jarvis</a>
</div>]]></description>
            <link>http://www.coldhardcode.com/blog/2011/01/jarvis-stop-reacting-and-start.html</link>
            <guid>http://www.coldhardcode.com/blog/2011/01/jarvis-stop-reacting-and-start.html</guid>
            
            
            <pubDate>Sun, 23 Jan 2011 08:43:34 -0800</pubDate>
        </item>
        
        <item>
            <title>My thoughts on the iPad</title>
            <description><![CDATA[<p>I've been a dedicated Mac user for about 2 years now. I purchased a MacBook Pro 3 years ago, and used it just for traveling. The turning point for me was struggling for about 20 minutes to connect to an Airport WiFi network, and while I was sitting there 3 different people with Macs sat down and immediately loaded webpages. That made me envious.</p><p>The other part is that I saw how quickly the Apple laptops wake up (and sleep). That also made me envious. I've happily trusted Apple to make a device that I want to use to accomplish the task they built the device for. This is an important distinguishing factor, because trying to use an Apple device for a use not intended is very frustrating. This is why I still use Linux servers, and can't imagine ever switching.</p><p>With this all in mind, when I looked at the iPad there was a moment of confusion. What is this device? What are the competitors? The UMPC segment isn't there, and the iPad is different than tablets. I honestly don't think there are competitors on the market now (JooJoo doesn't count), but there certainly will be (the HP tablet, etc).</p><p>The iPad is the natural evolution of the iPod. The very first generation iPod hit the market with an MSRP of $399. Not very far off of the $499 for the iPad, released 9 years later.</p><p>The iPad is pushing the limits of current technology, much like the iPod did back then (for those people questioning this statement, I dare you to look at iPod competitors back then.)</p><p>With technology at the point it is now, the current crop of personal media devices is going to be the future. Apple did not do this abruptly, they have been slowly removing and testing the waters. The AppleTV was the first device for media consumption, and it largely failed. The iMac and Mini were full computer that was largely non-servicable by the end-user. The MacBook Air was the closest shot, a closed device without a lot of ports. This was the perfect litmus test to see if people in general were willing to start giving up on things they didn't use.</p><p>This is where we are at. We have purpose-built devices that excel at what they're built at doing. In the case of the iPad, it's exactly that: a pad. Much like a pad of paper, this is the new generation. It isn't a computing device, nor should it ever attempt to be one. It will fail at that, just as much as the current "Tablets" fail at being competitors to the iPad.</p><p>You don't want background tasks on this. It's a single-task type of device. Push notifications and perhaps event loops are important, but on the iPad (or any other Pad device) you should be focusing on a single task. This is the expectation the device has of its user.</p><p>The technology is to be able to quickly flip between tasks. This is where Apple has a leg up on competitors and I am not sure if the competitors are going to truly understand that the quick-task switching is the killer feature. One which Apple does well with, but I still think they could do better.</p><p>So after sitting with my iPad for a couple days, both using it as a productivity enhancer and just a media consumption device, I still think they have a hit. it's exactly what it should be. It isn't perfect, but none of the first generation of devices are. I'll be buying the next generation when it comes out, and be very happy.</p><p></p>
<h3 id="ipad-pros">Pros:</h3>
<ol>
 <li>Vivid screen. Very impressive, readable and perfect.</li>
 <li>Orientation Lock is fantastic.</li>
 <li>It works exactly as you would expect.</li>
</ol>
<h3 id="ipad-cons">Cons</h3>
<ol>
<li>It's heavy.  I'll build up forearm strength simply reading in bed (a pro?)</li>
<li>There is disparity between applications on which way is down.  The case should resolve this.  Certain applications have fixed orientation (usually games) and that "Down" direction may be counter to what is natural to you, and it doesn't rotate.  As an example, Harbor Master's "Down" is contrary to the case.</li>
<li>Apps are expensive.  More screen real estate does not automatically make something worth more.  The app itself needs to be more.  There isn't the "14 Day Free Trial" editions on the iPad, and because of that it precludes me from buying a lot of applications I'd like.</li>
<li>The App Store.  It has too many limitations.  No free trials, the iPad/iPhone split isn't clean enough.</li>
</ol>
<p>Now, each and every one of those cons is temporary and I'm certain will be resolved within the next couple of years.  I'll be on my 3rd iPad and probably my 5th iPhone by then, and enjoying every one.</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/04/my-thoughts-on-the-ipad.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/04/my-thoughts-on-the-ipad.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">devices</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">gadgets</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ipad</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
            <pubDate>Sat, 03 Apr 2010 12:47:21 -0800</pubDate>
        </item>
        
        <item>
            <title>An early project migration, from MogileFS to MongoDB</title>
            <description><![CDATA[<p>As vaguely announced, a few days ago we launched a new project called <a href="http://codepeek.com">CodePeek</a>. &nbsp;While we have our own reasons for this particular project, it was really just a very quickly done project that, by default, was built using the tools that we had available to us and experience with. &nbsp;One of those tools we picked simply because of familiarity was MogileFS.
</p><p>
MogileFS has always been my default choice whenever I needed to store a lot of data <em>somewhere</em>, without any relational context to that data. &nbsp;It handles replication, and for the most part just works. &nbsp;For things like pastes, with the support for images and other media types, it was a reasonable choice.
</p><p>
Except it is just a bit fragile and lacks certain features that we really wanted to have available to us. &nbsp;I don't want this to be interpreted as being critical of MogileFS because I think it's good software. &nbsp;However, I do think that it is software that requires more attention than what we wanted to give it and also is not an exact fit for our purposes.
</p><p>
This discussion was happening while we are also exploring various document-based storage engines (commonly referred to as "<a href="http://en.wikipedia.org/wiki/NoSQL">NoSQL</a>"). &nbsp;This movement has produced CouchDB and, of course, MongoDB (as well as many others). &nbsp;For us, MongoDB looked like the obvious solution because it supports replication, has an incredibly easy API and was very fast in our tests.
</p><p>
After about an hour of hacking and debugging last night, I had everything working. &nbsp;I spent 20 minutes this morning writing a migration script and everything has just simply worked.
</p><p>With a total investment of about 2 hours &mdash; including setup, "apt-get install mongodb" wasn't much trouble &mdash; we have replicated MongoDB storage (across 2 Linodes), and new storage code. &nbsp;I'm pretty impressed with the agility in which we can move to replace a storage backend, and believe it is a testament to the quality inherently available when using superior tools, like <a href="http://moose.perl.org/">Moose</a>, <a href="http://www.catalystframework.org/">Catalyst</a> and <a href="http://search.cpan.org/dist/DBIx-Class/">DBIx::Class</a>.
</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/03/an-early-project-migration-fro.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/03/an-early-project-migration-fro.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Codepeek</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">codepeek</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">development</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">mongodb</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
            <pubDate>Wed, 24 Mar 2010 07:36:19 -0800</pubDate>
        </item>
        
        <item>
            <title>Designing Codepeek: The Logo</title>
            <description><![CDATA[<p>Much of my work to date with Cold Hard Code has been for relatively large applications. &nbsp;These big, complex applications can quickly overwhelm so a lot of time is spent keeping things simple. &nbsp;Our most recent project, <a href="http://codepeek.com" class="">Codepeek</a>, gave me a chance to make something less intense.
</p><p>
The logo came together very fast. &nbsp;Hoefler &amp; Frere-Jone's <a href="http://www.typography.com/fonts/font_overview.php?productLineID=100035" class="">Tungsten</a> is CHC's corporate font so it's use was predetermined. &nbsp;I had it in my head to create something playful, classy and more pop than my usual work.
</p><p>
From jump I knew that I wanted to set the text on an arc. After a few attempts I finally found what I wanted with a negative leading. This gave it a presence that reminded me of an announcer crowing to the crowd: Codepeek has arrived!
</p><p>
The two-tone effect is intentional, providing some clarification for the words. &nbsp;The name is inspired by the concept of "peeking at code". &nbsp;My original idea was "peekcode" but the k and c felt like a linguistic train wreck that refused to roll off the tongue. &nbsp;Codepeek worked much better but was backward from my original concept. &nbsp;Placing "peek" front and center in bright white balanced the message I was trying to send. &nbsp;Careful not to forget the "code" I added a strong gradient and some subtle dots that are intended to look like bubbles rising in the code. &nbsp;Those embellishments can be easily removed and the logo reduced to <a href="http://codepeek.com/paste/muliedfsqkmwcao" class="">two colors</a> very easily, fulfilling one of the rules of logo design.
</p><p>
The small leaves set behind the name are decorative fleurons that provide some distinction for an otherwise wordy logo. &nbsp;It's a purely subjective decoration that I have an odd affinity for.
</p><p>
<a href="http://codepeek.com" class="">Codepeek</a> was a great project that Jay and I took from concept to production in just over a week. &nbsp;It gave me an opportunity to create a light, playful identity that I'm very proud of.</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/03/designing-codepeek-the-logo.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/03/designing-codepeek-the-logo.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Codepeek</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">design</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">design logo codepeek</category>
            
            <pubDate>Sat, 20 Mar 2010 06:10:43 -0800</pubDate>
        </item>
        
        <item>
            <title>CPAN Improvements, Take 2</title>
            <description><![CDATA[I'm now revisiting my CPAN post from before. &nbsp;The illustrious charsbar commented about CPAN options that certainly do a good job hiding the things you don't need to see, except for when you need to see them.<br><br>I thought I'd give some examples to show how these options are not good enough, and not really what I'm after.<br><br>First, imagine the case of local::lib being setup. &nbsp;Then you run CPAN (1.9402) after local::lib aliases are setup; As expected, right after 'cpan', you are met with a configuration prompt. &nbsp;It tells you that you have no access to write to /root/.cpan. &nbsp;Of course, because we're good developers and use local::lib. &nbsp;This works well, the user configuration is created but then there is a problem:<br>
<code><pre>nolock_cpan[1]&gt; o conf halt_on_failure yes                             
 halt_on_failure [yes]
Catching error: "/etc/perl/CPAN/Config.pm is not writable at /usr/local/share/perl/5.10.0/CPAN/HandleConfig.pm line 286\cJ\cICPAN::HandleConfig::commit('CPAN::HandleConfig') called at /usr/local/share/perl/5.10.0/CPAN/HandleConfig.pm line 213\cJ\cICPAN::HandleConfig::edit('CPAN::HandleConfig', 'halt_on_failure', 'yes') called at /usr/local/share/perl/5.10.0/CPAN/Shell.pm line 393\cJ\cICPAN::Shell::o('CPAN::Shell', 'conf', 'halt_on_failure', 'yes') called at /usr/local/share/perl/5.10.0/CPAN.pm line 375\cJ\cIeval {...} called at /usr/local/share/perl/5.10.0/CPAN.pm line 372\cJ\cICPAN::shell() called at /usr/local/bin/cpan line 198\cJ" at /usr/local/share/perl/5.10.0/CPAN.pm line 391
	CPAN::shell() called at /usr/local/bin/cpan line 198
</pre></code>
That wasn't what we wanted, right? &nbsp;Here's another point, and an easy bug. &nbsp;If CPAN knows it created a user configuration, automatically reload it. &nbsp;Minor nit. &nbsp;CPAN.pm has a plethora of open bugs, it's daunting to just file a bug because you don't want to file a dupe. &nbsp;After I write this post, I'll see about that.<br><br>So, you exit cpan and restart, it says the other process isn't responding. &nbsp;Overwrite it? &nbsp;Sure! &nbsp;Now we're in business. &nbsp;This is not a good user experience. &nbsp;So far it looks like everything is broken, and there isn't anything shown to the user that CPAN is ready to do what it is supposed to do.<br><br>Now that we're here, setting the various options charsbar pointed out works. As expected, now just the "perl Makefile.PL" is loud and the installation prompts fill the backlog. &nbsp;It is much improved, as the more important details are present. &nbsp;The screen is still filled with all sorts of information that I don't need, or even want. &nbsp;Test passes, etc. &nbsp;The verbosity options merely affect CPAN.pm operations, and not the actual building. &nbsp;I want a very nice filter. &nbsp;<br><br>When things fail, the situation is no different regardless of the CPAN options. &nbsp;I have pages and pages of text to deal with, the only benefit is that now I aborted on a failure. &nbsp;I have no way to jump in and attempt to resume after fixing this error.<br><br>Here's the output of the first test failure (namespace::clean) that just stops the install in its tracks:<br><code><pre>t/07-debugger.t .......... 
Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(t/07-debugger.t:26):	    package Foo;
Unknown error
Compilation failed in require at /home/ems/perl5/lib/perl5/Term/ReadLine/Perl.pm line 63.
 at /home/ems/perl5/lib/perl5/Term/ReadLine/Perl.pm line 63
	Term::ReadLine::Perl::new('Term::ReadLine', 'perldb', 'GLOB(0x8465e28)', 'GLOB(0x83ba9e8)') called at /usr/share/perl/5.10/perl5db.pl line 6073
	DB::setterm called at /usr/share/perl/5.10/perl5db.pl line 2237
	DB::DB called at t/07-debugger.t line 26
Test::Builder::CODE(0x8429fc8)(/home/ems/perl5/lib/perl5/Test/Builder.pm:2426):
2426:	    $Test-&gt;_ending if defined $Test;
Attempt to reload Term/ReadLine/readline.pm aborted.
Compilation failed in require at /home/ems/perl5/lib/perl5/Term/ReadLine/Perl.pm line 63.
END failed--call queue aborted at t/07-debugger.t line 63.
 at t/07-debugger.t line 63
Attempt to reload Term/ReadLine/readline.pm aborted.
Compilation failed in require at /home/ems/perl5/lib/perl5/Term/ReadLine/Perl.pm line 63.
END failed--call queue aborted at t/07-debugger.t line 63.
 at t/07-debugger.t line 63
Test::Builder::DESTROY(/home/ems/perl5/lib/perl5/Test/Builder.pm:317):
317:	    my $self = shift;
t/07-debugger.t .......... Dubious, test returned 9 (wstat 2304, 0x900)
No subtests run 
t/08-const-sub.t ......... ok   

Test Summary Report
-------------------
t/07-debugger.t        (Wstat: 2304 Tests: 0 Failed: 0)
  Non-zero exit status: 9
  Parse errors: No plan found in TAP output
Files=9, Tests=73,  0 wallclock secs ( 0.02 usr  0.03 sys +  0.42 cusr  0.07 csys =  0.54 CPU)
Result: FAIL
Failed 1/9 test programs. 0/73 subtests failed.
make: *** [test_dynamic] Error 255
  FLORA/namespace-clean-0.13.tar.gz
  /usr/bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
  reports FLORA/namespace-clean-0.13.tar.gz
Running make install
  make test had returned bad status, won't install without force
Stopping: 'install' failed for 'F/FL/FLORA/namespace-clean-0.13.tar.gz'.
Failed during this command:
 FLORA/namespace-clean-0.13.tar.gz            : make_test NO

</pre></code>We're still not in any position to help the user. &nbsp;What do to from here? &nbsp;Well, the only thing is to see cpan-testers results. &nbsp;This doesn't help anybody succeed.<br><br>So, even with the verbosity options set to the quietest setting, it does nothing for the output of the various Makefile.PL/Build.PL outputs. &nbsp;There isn't any assistance offered, or even help for the user to plug into a google search.<br><br>If these modules are on the CPAN, it is reasonable to assume a standard of behavior. &nbsp;Such that my desired output is feasible:<br><br><code><pre> * Fetching {module name}...  ok
 * Unpacking {module name}...  ok
 * Following dependencies...  ok
 * Testing {module name}...   ok
</pre></code><br>The other thing would be to have a full dependency list calculated at the start, so it can be determined what packages need to be installed and in what order, just to suppress the enter-mashing problem.<br><br>I suppose that a lot of this could simply be an output processor for the make/install loop, and then other CPAN loops.<br><br>If the Perl community wants to tout "the CPAN" as the killer feature, then CPAN.pm needs to be a killer feature.<br><br>I'm hoping the next version of a CPAN shell keeps this in mind, and it ultimately boils down to these priorities:<ol><li>Don't inundate the screen with useless messages on success.<br></li><li>Don't be terse and not include messages on failure.<br></li><li>Help the user.<br></li></ol><div>On a related note, I came across an article titled&nbsp;<a></a><a>Marketing the Entire Box (including the wrapper)</a> while writing this. &nbsp;It's a good read which I highly recommend.<br><br>Developers may find marketing to be slimey and sleazy, but understand that having a tool that insults and frustrates the user is just as much marketing as having a beautiful website with quality typography and information architecture.</div><div><a></a></div><div><a></a></div><div><a></a></div><div><br>I'll get off my soapbox now.</div>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/02/cpan-improvements-take-2.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/02/cpan-improvements-take-2.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">cpan</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">development</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software development</category>
            
            <pubDate>Tue, 02 Feb 2010 05:54:32 -0800</pubDate>
        </item>
        
        <item>
            <title>Improving CPAN, make money and help Perl</title>
            <description><![CDATA[I have a new server to setup, which will be a staging and development environment. &nbsp;This means I'll be installing much more than is typical, and I figured it is a good chance to test the legs of Task::Kensho.<br><br>The first line summary is that I'm slightly disappointed, because there were failures in mid-stream and while it continued, it wasn't exactly intuitive as to the failure. &nbsp;One of my biggest complaints about working in any programming language is when you get ambiguous failure messages. &nbsp;Failures with messages "Can't locate namespace/clean.pm in..." followed by a tremendous deluge of test failure messages counts there. &nbsp;Especially when namespace::clean should have been installed.<br><br><i><b>Update:</b></i> The bounty and details are at the bottom, but <a>sartak</a> is also throwing in $100.&nbsp; $200 to make a CPAN client that doesn't scare people.&nbsp; Lets do it, people.<br><br>And here is the long version. &nbsp;I setup a Linode 360, deployed Debian 5.0 on it. &nbsp;After it booted, I added my user account and setup sudo. &nbsp;Then proceeded down the path of having a working development environment:<blockquote><code>sudo apt-get install perl mysql-server libdbd-mysql-perl lib-dbd-sqlite3-perl build-essential unzip</code></blockquote><br>If you don't install unzip, CPAN can't find it and will error when it encounters a package that is zipped. &nbsp;Why people upload packages to the CPAN as a zip I'll never know, but that's their (silly) choice.<br><br>After this, (as root) I install local::lib<blockquote><code>sudo su -<br>cpan local::lib</code></blockquote><br>On Debian 5.0, CPAN has the capability of automatically configuring itself. &nbsp;This is nice, and just works. &nbsp;So far so good.<br><br>Now, under my user account:<br><br><blockquote><code>perl -Mlocal::lib &gt;&gt; .profile<br>. .profile<br></code></blockquote><br>At this point, I can use CPAN as my user and install into my perl lib directory and not deal with anything on the system level. &nbsp;No more sudoing, so enter <a title="" target="" href="http://search.cpan.org/dist/Task-Kensho/lib/Task/Kensho.pm">Task::Kensho</a>.<blockquote><code>cpan Task::Kensho</code></blockquote><br>Here you have a lot choices, but fortunately they are easy to understand. &nbsp;Since I'm working with DBIC and Catalyst, with lots of Moose, those were the choices I made - as well as selecting the various command-line options and other utilities for developing.<br><br>Unfortunately, the Moose section failed. &nbsp;Sub::Identity failed to download, thus blocking namespace::clean from installing, subsequently failing MooseX::Types and then I had a little storm of failure. &nbsp;This is quite frustrating, but I just ran "cpan namespace::clean" in another session and was able to install it properly the second time.<br><br>Now to be safe I installed MooseX::Types and MooseX::Types::Path::Class, since that was the point that it failed.<br><br>Here's an important bit. &nbsp;If I wasn't paying attention I would have no idea what failed, or why it failed. &nbsp;CPAN silently continued on to the next module and I had to scroll up to see the failures and only my experience with Perl and CPAN was able to allow me to continue.<br><br>Also, there is a lot of enter pushing. &nbsp;There are options to automatically follow, but because of failures like above I didn't set that. &nbsp;Good thing, or I wouldn't have everything installed.<br><br>I had the same issues with several other modules, mostly in the Task::Moose bundle. &nbsp;Each one, while installing separately, was successful; only when part of Task::Kensho did these fail. I don't mean this as a criticism of Task::Kensho, instead it is about the CPAN client.<br><br>It has messages that are quite specific:<br><div class="yui-wk-div"><blockquote><code>Warning: Prerequisite 'Parse::Method::Signatures =&gt; 1.003012' for 'A/AS/ASH/TryCatch-1.002000.tar.gz' failed when processing 'F/FL/FLORA/Parse-Method-Signatures-1.003013.tar.gz' with 'make_test =&gt; NO'. Continuing, but chances to succeed are limited.</code></blockquote><div class="yui-wk-div"><br>Too specific, CPAN knows it is going to fail and instead of stopping to ask the user for help or doing something that will be useful, it continues on and buries the failures amidst dozens of lines of meaningless test failures.<br><br>It's not a terrible experience, but it is extremely verbose and the most important messages are hidden. &nbsp;You have to either decide between hitting enter constantly at each dependency step, and catching when things fail, or simply hope that things will succeed. &nbsp;In my experience, they won't succeed and as such I'm forced to press enter a lot and keep another session open so that I may install modules that fail by hand.<br><br>This is not an experience that a user who is new to Perl should endure.<br><br>In an effort to be constructive, here is how I envision a much better process.<br><br>CPAN has a default output mode that is not so verbose. &nbsp;I don't need to see the result of unpacking a module, the prerequisites that aren't found and the requirement list. &nbsp;I should instead see something like this:<br><br><blockquote><code>&nbsp;* Fetching {module name}... ok<br>&nbsp;* Unpacking {module name}... ok<br>&nbsp;* Following dependencies...</code></blockquote><br>In the case of a failure, or an attempt to fetch a dependency that has failed to install, CPAN should immediately pause and ask the user what to do. &nbsp;The reasonable choices are: Attempt to refetch/install, Show Details or Abort. &nbsp;If you show details, it should show the entire log from the Unpack to the Failure.<br><br>I'm not familiar with CPAN internals, and don't really care to be. &nbsp;So, here's my offer to solve this problem.<br><br>$100 in cash, check or paypal, to anybody who gets a mode of CPAN working as described. &nbsp;The money is just a token, and I have no idea how long it will take to do this. &nbsp;It doesn't seem complex to simply reduce output and change that "Prerequisite failed when processing" message I listed above to something helpful. &nbsp;Maybe $100 is too little, but the point is you're helping the Perl community by making our most valuable tool more functional. &nbsp;Comments welcome to flesh this out, maybe other people are interested in matching additional funds to whoever can make CPAN not so daunting to new users.<br><br>I will test it in the same fashion as above, starting with a fresh debian 5.0 install and local::lib and whatever CPAN modules need to be installed for this to work. &nbsp;I will then fire off installing Task::Kensho.<br><br><br></div></div>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/01/improving-cpan-make-money-and.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/01/improving-cpan-make-money-and.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">better</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cpan</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">improving cpan</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">improving perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
            <pubDate>Fri, 22 Jan 2010 09:46:28 -0800</pubDate>
        </item>
        
        <item>
            <title>Using lazy_build for maximum effect</title>
            <description><![CDATA[Rather abruptly I just came to a conclusion that I could remove a swath of code if I just had called a clearer method, and used a lazy_build to populate an accessor.<br><br>I have a list of items that is persistent, but I perform various calculations that are costly and prefer to only do them on demand. &nbsp;In other words, lazily. &nbsp;To avoid any unnecessary recalculation I also want to preserve the returned value. &nbsp;The conditions that cause the result to be stale are very well defined.<br><br>So, the simple solution was to rename my calculation method to _build_expensive_thing, create an attribute with lazy_build and in my method that invalidates, clear all those.<br><br>In simpler and more exact terms, this:<br><script src="http://gist.github.com/267283.js?file=lazybuildftw.pl"></script><br>]]></description>
            <link>http://www.coldhardcode.com/blog/2010/01/using-lazy-build-for-maximum-e.html</link>
            <guid>http://www.coldhardcode.com/blog/2010/01/using-lazy-build-for-maximum-e.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">less is more</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Moose</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
            <pubDate>Fri, 01 Jan 2010 14:11:43 -0800</pubDate>
        </item>
        
        <item>
            <title>My favorite feeds</title>
            <description><![CDATA[Continuing my entry from yesterday, I'd like to just list some of my favorite feeds at the moment. &nbsp;These are just the various blogs that I'm particularly enjoying at the moment, and I decided to limit it to only 3.<br><br>
<dl>
<dt><a href="http://blog.woobling.org" class="">nothingmuch's blog at http://blog.woobling.org/</a></dt>
<dd>It's hard to find someone who knows so many languages and can communicate the knowledge in such a thorough and easy to understand way.&nbsp; His blog is simply a glimpse into his capabilities, but mostly he provides recipes for simply doing things better. &nbsp;He has a knack for simplifying common tasks (with the usual side effect of added robustness).</dd>
<dt><a href="http://mt.endeworks.jp/d-6/" class="">lestrrat (Daisuke Maki) at http://mt.endeworks.jp/d-6/</a></dt>
<dd>I like Maki-san for a variety of reasons. &nbsp;He's probably one of the most entertaining Perl hackers to be around at a conference. He has a really phenomenal view of Perl and programming in general, because he's making a living running a consultancy in Shibuya (Tokyo) and also running the Japanese Perl Association. &nbsp;When he writes it's interesting to read his perspective, since I think he offers a fairly unique perspective.<br>The downside of his blog is that many entries are in Japanese.</dd>
<dt><a href="http://stevan-little.blogspot.com" class="">Stevan Little at http://stevan-little.blogspot.com/</a></dt>
<dd>Stevan is the attentive care giver of Moose (founder, guider?) and all around encyclopedia of programming knowledge. &nbsp;He offers a perspective that is fairly unique, because of his very deep understanding of what seems to be all programming languages. &nbsp;Oh, and of his crazy involvement in Moose. &nbsp;It's pretty amazing what he manages to accomplish.</dd>
</dl>
<p>There are many more blogs I read, but lately these have been the most interesting.  As my interests or the content shifts, I'll post updates to my favorites (and try to limit to just 3 people in each post).</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2009/12/my-favorite-feeds.html</link>
            <guid>http://www.coldhardcode.com/blog/2009/12/my-favorite-feeds.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">blogs</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">circlejerk</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software development</category>
            
            <pubDate>Wed, 09 Dec 2009 12:14:04 -0800</pubDate>
        </item>
        
        <item>
            <title>Being in Open Source</title>
            <description><![CDATA[<p>My wife and I have been together for over 7 years. In that time, she has watched me go from a developer to an Open Source contributor.  The latter transformation is largely due to the <a href="http://www.catalystframework.org">Catalyst framework</a>, and in particular mst encouraging me to actually contribute.</p>

<p>I don't think she understands why, and I'm not sure if I did either.  To be very clear, I'm not a contributor in the truly giving sense of a word.  To be fully honest, I contribute in a way that benefits myself.  I have learned more from the core hackers than in any job, course or conference.  This is my ultimate motivator to stay involved in the community.</p>

<p>The main take away from participating in the Perl community is my own personal and professional development.  I learn.  I learn quickly and discover many great things I wouldn't discover on my own.  There is an additional benefit of finding a way to work on some <a href="http://plackperl.org">very fun things</a>.</p>

<p>It saves me time and troubles doing what pays me, so my job gets easier and better as time goes on.</p>

<p>I try to make a difference, but I know that my contributions are nothing remarkable.  Anything that I've done that was remarkable was simply because I happened to arrive at a point first.</p>

<p>Even though my contributions are functionally marginal, I feel incredibly gifted and thankful to be accepted in a community as great as the <a href="http://www.enlightenedperl.org">modern Perl hackers</a>.</p>

<p>These inventors of great things spontaneously evolve an idea into a functional product in amazingly short time. To witness these moments is something you cannot get in any office, Internship or academic setting.</p>

<p>I'm involved in Open Source because I've never found a more efficient and thorough vessel of learning.  The skills I've developed while simply <em>being around</em> these giants are, at least for me, unattainable anywhere else.</p>

<p>Out of the various Open Source projects I've participated in, none have been as influential as the Perl community.  In particular, the <a href="http://moose.perl.org">Moose</a> and Catalyst sub-communities.</p>

<p>Thank you all who have made this community what it is.</p>]]></description>
            <link>http://www.coldhardcode.com/blog/2009/12/being-in-open-source.html</link>
            <guid>http://www.coldhardcode.com/blog/2009/12/being-in-open-source.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Software Design</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">code</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">community</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">contribute</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">foss</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">open source</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">software development</category>
            
            <pubDate>Wed, 09 Dec 2009 12:06:00 -0800</pubDate>
        </item>
        
        <item>
            <title>Plack and the Perl WSGI (PSGI)</title>
            <description><![CDATA[<p>For those not familiar in what's happened since Rails has taken off, and Django has become a very robust and popular framework, there has been a movement towards something coined <a class="" href="http://wsgi.org">WSGI</a>, Web Server Gateway Interface.  This is a specification that is very prevalent in the Python community, and is generally accepted as a Good Idea. In a nutshell, it tries to normalize and enhance communication from an application to the frontend webserver (so that lighttpd, apache and nginx differences are nullfied)</p>

<p>Ruby has a reference implementation called <a class="" href="http://rack.rubyforge.org/">Rack</a>, which takes and shares many ideas of WSGI, but makes it Ruby-ish.</p>

<p>Perl now has <a class="" href="http://plackperl.org">Plack</a>, an astounding effort by <a class="" href="http://bulknews.typepad.com">Tatsuhiko Miyagawa</a>.  Plack has been awarded the "<a class="" title="" target="" href="http://bulknews.typepad.com/blog/2009/12/plack---lpw-2009.html">Module of the Year</a>" award at London Perl Workshop, and in my opinion is very well deserved.</p>

<p>Within Plack, you can write very lightweight applications just using what Plack offers.  You can also use Plack to handle deployment of several other frameworks, including <a class="" href="http://www.catalystframework.org">Catalyst</a> (via <a class="" href="http://search.cpan.org/dist/Catalyst-Engine-PSGI/">Catalyst::Engine::PSGI</a>).</p>

<p>As an example of what can be done, I first saw Tatsumaki.  Tatsumaki is an event-driven HTTP server that handles streaming (as well as long-poll comet services).</p>

<p>I built an application using <a class="" href="http://github.com/miyagawa/Tatsumaki">Tatsumaki</a> to handle streaming live race results to people who couldn't make it to the track.</p>

<p>It worked out very well, except for a small memory leak (that has been fixed).  I had, at peak, 615 concurrent clients with an average of about 380 concurrent clients.</p>

<p>I was using the Plack server directly (Tatsumaki::Server), and having clients connect directly to it. I had a peak throughput of 10Mbps, with an average of 1.6Mbps of data going through Tatsumaki.</p>

<p>I call that a fantastic success, and thank Miyagawa-san for his hard work in getting this software to where it is.  Without Tatsumaki, and Plack, I would have been doing a hacky long-poll solution that would have been much slower and less featured.</p>

<p>I also built a YUI3 based Multipart XmlHttpRequest library so that I can stream using YUI3 (I prefer this over jQuery) but IE failed to work, so I had to fall back to long-poll clients which worked more similarly across all browsers.</p>

]]></description>
            <link>http://www.coldhardcode.com/blog/2009/12/plack-and-the-perl-wsgi-psgi.html</link>
            <guid>http://www.coldhardcode.com/blog/2009/12/plack-and-the-perl-wsgi-psgi.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">catalyst</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">code</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">catalyst</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">frameworks</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">perl</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">plack</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">psgi</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">web</category>
            
            <pubDate>Tue, 08 Dec 2009 08:13:12 -0800</pubDate>
        </item>
        
    </channel>
</rss>

