<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Guillermo Roditi</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/guillermo_roditi1/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/guillermo_roditi1//130</id>
    <updated>2010-04-24T03:09:59Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>The people that make the perl community great</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/04/the-people-that-make-the-perl-community-great.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.500</id>

    <published>2010-04-24T01:17:30Z</published>
    <updated>2010-04-24T03:09:59Z</updated>

    <summary>Today, I ventured into #dbix-class inquiring about some performance problems I was having. I wasn&#8217;t complaining about the speed of DBIC, I was looking for ways to trim out work that I was doing that I could avoid doing. The...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="classaccessorgrouped" label="Class::Accessor::Grouped" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="community" label="community" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="dbixclass" label="DBIx::Class" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="optimizing" label="optimizing" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="oss" label="oss" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="performance" label="performance" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="profiling" label="profiling" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sqlabstract" label="SQL::Abstract" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Today, I ventured into <strong>#dbix-class</strong> inquiring about some performance problems I was having. I wasn&#8217;t complaining about the speed of DBIC, I was looking for ways to trim out work that I was doing that I could avoid doing. The script I was running (file parser + insert into DB) was taking a little more than an hour to run. I was musing whether to drop DBIC, parallelize the job or just deal with the slowness when<em>* ribasushi</em>* (<a href="http://search.cpan.org/~ribasushi/">Peter Rabbitson</a>) came to the rescue. After sharing with him a copy of NYTProf&#8217;s output, he quickly identified some hot-spots in <a href="http://search.cpan.org/perldoc?SQL::Abstract">SQL::Abstract</a> that could be worked on. Soon enough, <strong>Caelum</strong> <a href="http://search.cpan.org/~rkitover/">(Rafael Kitover</a>) chipped in and we had improvements (some XS code wasn&#8217;t being used) in <a href="http://search.cpan.org/perldoc?Class::Accessor::Grouped">Class::Accessor::Grouped</a> coming. Within an hour I was upgrading CAG, SQLA, DBIC and installing Class::XSAccessors  and profiling the code again.</p>

<p><strong>Total improvement:</strong> time spent inside CAG dropped by 57% and 44% in SQLA
<strong>Total time elapsed:</strong> ~2 hours.</p>

<p>If this is not a sign of what makes the perl community great, I don&#8217;t know what is.</p>

<p>The code is not flying any any means, but the total runtime was reduced by 34%, which is not bad for an evening&#8217;s work. </p>

<p><a href="http://dev.catalystframework.org/svnweb/bast/revision?rev=9201">SQL::Abstract Changes</a>
<a href="http://dev.catalystframework.org/svnweb/bast/revision?rev=9203#diff__DBIx-Class_0.08_trunk_lib_DBIx_Class_SQLAHacks.pm">DBIx::Class Changes</a></p>

<p>(read on for comparison of the top 15 subs)</p>
]]>
        <![CDATA[<p><strong>BEFORE:</strong></p>

<p>Profile of test.pl for 5246s, executing 533397042 statements and 183082682 subroutine calls in 342 source files and 80491 string evals.</p>

<table  border="1" cellpadding="0">
<caption>Top 15 Subroutines &#8212; ordered by exclusive time</caption>
<thead>
<tr>
        <th>Calls</th>
        <th><span title="Number of Places sub is called from">P</span></th>
        <th><span title="Number of Files sub is called from">F</span></th>
        <th>Exclusive<br>Time</th>

        <th>Inclusive<br>Time</th>
        <th>Subroutine</th>
        </tr>
        </thead>
    <tbody>
<tr><td >118331</td><td >1</td><td >2</td><td ><span title="10.9%">573s</span></td><td ><span title="10.9%">573s</span></td><td >                       DBI::st::execute&nbsp;(xsub)</td></tr>

<tr><td >18740893</td><td >5</td><td >1</td><td ><span title="3.8%">200s</span></td><td ><span title="5.3%">280s</span></td><td >    DBIx::Class::ResultSource::_columns</td></tr>
<tr><td >8119393</td><td >93</td><td >93</td><td ><span title="3.8%">198s</span></td><td ><span title="4.7%">247s</span></td><td >      Class::Accessor::Grouped::get_inherited</td></tr>

<tr><td >3250960</td><td >1</td><td >1</td><td ><span title="3.0%">158s</span></td><td ><span title="7.3%">380s</span></td><td >                 SQL::Abstract::_quote</td></tr>
<tr><td >28352404</td><td >27</td><td >27</td><td ><span title="2.4%">126s</span></td><td ><span title="2.4%">126s</span></td><td >      Class::Accessor::Grouped::get_simple</td></tr>

<tr><td >5354668</td><td >4</td><td >1</td><td ><span title="2.3%">121s</span></td><td ><span title="7.7%">404s</span></td><td >                SQL::Abstract::_SWITCH_refkind</td></tr>
<tr><td >4637845</td><td >6</td><td >4</td><td ><span title="2.2%">113s</span></td><td ><span title="6.1%">318s</span></td><td >    DBIx::Class::ResultSource::column_info</td></tr>

<tr><td >111161</td><td >1</td><td >1</td><td ><span title="2.1%">112s</span></td><td ><span title="5.6%">296s</span></td><td >               SQL::Abstract::_insert_values</td></tr>
<tr><td >5487339</td><td >1</td><td >1</td><td ><span title="2.0%">107s</span></td><td ><span title="2.4%">124s</span></td><td >             SQL::Abstract::_refkind</td></tr>

<tr><td >5487339</td><td >2</td><td >1</td><td ><span title="1.8%">94.7s</span></td><td ><span title="4.2%">219s</span></td><td >                SQL::Abstract::_try_refkind</td></tr>
<tr><td >4827092</td><td >8</td><td >5</td><td ><span title="1.4%">71.8s</span></td><td ><span title="7.5%">395s</span></td><td >DBIx::Class::ResultSourceProxy::has_column</td></tr>

<tr><td >3250960</td><td >6</td><td >3</td><td ><span title="1.3%">66.1s</span></td><td ><span title="8.5%">447s</span></td><td >       DBIx::Class::SQLAHacks::_quote</td></tr>
<tr><td >118331</td><td >2</td><td >1</td><td ><span title="1.1%">57.3s</span></td><td ><span title="5.5%">287s</span></td><td >    DBIx::Class::Storage::DBI::source_bind_attributes</td></tr>

<tr><td >4827274</td><td >3</td><td >2</td><td ><span title="1.1%">55.4s</span></td><td ><span title="2.5%">131s</span></td><td >     DBIx::Class::ResultSource::has_column</td></tr>
<tr><td >133641</td><td >1</td><td >1</td><td ><span title="1.0%">52.2s</span></td><td ><span title="10.7%">561s</span></td><td >              DBIx::Class::Row::new</td></tr>

        </tbody>
</table>

<p><strong>AFTER:</strong></p>

<p>Profile of test.pl for 3466s, executing 328628699 statements and 133802224 subroutine calls in 345 source files and 80406 string evals.</p>

<table border="1" cellpadding="0">
<caption>Top 15 Subroutines &#8212; ordered by exclusive time</caption>
        <thead>
        <tr>
        <th>Calls</th>
        <th><span title="Number of Places sub is called from">P</span></th>
        <th><span title="Number of Files sub is called from">F</span></th>
        <th>Exclusive<br>Time</th>

        <th>Inclusive<br>Time</th>
        <th>Subroutine</th>
        </tr>
        </thead>
    <tbody>
<tr><td >118331</td><td >1</td><td >2</td><td ><span title="8.8%">304s</span></td><td ><span title="8.8%">304s</span></td><td >                       DBI::st::<a>execute</a>&nbsp;(xsub)</td></tr>

<tr><td >8119393</td><td >93</td><td >93</td><td ><span title="5.7%">198s</span></td><td ><span title="7.1%">246s</span></td><td >      Class::Accessor::Grouped::get_inherited</td></tr>
<tr><td >111161</td><td >1</td><td >1</td><td ><span title="3.2%">111s</span></td><td ><span title="7.8%">270s</span></td><td >                 SQL::Abstract::_insert_values</td></tr>

<tr><td >4637845</td><td >6</td><td >4</td><td ><span title="3.0%">103s</span></td><td ><span title="3.9%">134s</span></td><td >     DBIx::Class::ResultSource::column_info</td></tr>
<tr><td >3250960</td><td >6</td><td >3</td><td ><span title="2.3%">78.1s</span></td><td ><span title="2.4%">82.1s</span></td><td >                 SQL::Abstract::_quote</td></tr>

<tr><td >4827092</td><td >8</td><td >5</td><td ><span title="2.1%">72.0s</span></td><td ><span title="9.5%">330s</span></td><td >DBIx::Class::ResultSourceProxy::has_column</td></tr>
<tr><td >118331</td><td >2</td><td >1</td><td ><span title="1.6%">55.9s</span></td><td ><span title="4.6%">160s</span></td><td >     DBIx::Class::Storage::DBI::source_bind_attributes</td></tr>

<tr><td >4827274</td><td >3</td><td >2</td><td ><span title="1.6%">54.1s</span></td><td ><span title="1.9%">66.4s</span></td><td >     DBIx::Class::ResultSource::has_column</td></tr>
<tr><td >118331</td><td >1</td><td >1</td><td ><span title="1.5%">51.1s</span></td><td ><span title="24.4%">846s</span></td><td >     DBIx::Class::Storage::DBI::_dbh_execute</td></tr>

<tr><td >133641</td><td >1</td><td >1</td><td ><span title="1.5%">51.1s</span></td><td ><span title="13.5%">470s</span></td><td >              DBIx::Class::Row::new</td></tr>
<tr><td >2103708</td><td >3</td><td >1</td><td ><span title="1.5%">50.9s</span></td><td ><span title="4.6%">160s</span></td><td >                 SQL::Abstract::_SWITCH_refkind</td></tr>

<tr><td >18740893</td><td >5</td><td >2</td><td ><span title="1.3%">43.7s</span></td><td ><span title="1.3%">43.7s</span></td><td >     DBIx::Class::ResultSource::_columns&nbsp;(xsub)</td></tr>
<tr><td >2374996</td><td >4</td><td >1</td><td ><span title="1.1%">39.3s</span></td><td ><span title="6.2%">213s</span></td><td >              DBIx::Class::Row::store_column</td></tr>

<tr><td >2236379</td><td >2</td><td >1</td><td ><span title="1.0%">36.2s</span></td><td ><span title="1.8%">64.0s</span></td><td >                 SQL::Abstract::_try_refkind</td></tr>
<tr><td >9791840</td><td >39</td><td >30</td><td ><span title="0.9%">31.7s</span></td><td ><span title="0.9%">31.7s</span></td><td >                  Scalar::Util::blessed&nbsp;(xsub)</td></tr>

        </tbody>
</table>

<p>Pretty good!</p>
]]>
    </content>
</entry>

<entry>
    <title>&quot;Professional-looking project websites&quot; Whatever...</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/03/professional-looking-project-websites-whatever.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.395</id>

    <published>2010-03-23T02:12:51Z</published>
    <updated>2010-03-23T02:26:06Z</updated>

    <summary>SawyerX, in his ongoing stream of posts regarding marketing Perl, recently blogged about project websites and suggested we all start hiring, and paying for out of our own pockets, designers to market our free offerings. I kinda wanted to smack...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cpan" label="CPAN" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="documentation" label="documentation" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="marketing" label="marketing" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="marketroids" label="marketroids" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="response" label="response" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p><a href="http://search.cpan.org/~xsawyerx/">SawyerX</a>, in his ongoing stream of posts regarding marketing Perl, recently <a href="http://blogs.perl.org/users/sawyer_x/2010/03/projects-that-should-have-websites.html">blogged about project websites</a> and suggested we all start hiring, and paying for out of our own pockets, designers to market our free offerings. I kinda wanted to smack him after reading that. I try not to comment on marketing or advocacy, etc. because I really just don&#8217;t care. I don&#8217;t care if new people use perl or what they think of it. I know it&#8217;s good and I know it works. I like my hammer, I think it&#8217;s a great hammer, and if you judge by the projects I produce, you would find that to be obvious. However, I will say that  even though I consider all this marketing talk to be annoying at best, he does have a point: Our OSS code is our resume. When applying to new jobs, it is easy to list things we did on a resume, but often times we are unable to provide cold hard code to employers because our previous employer owns the rights to it or we are bound by NDAs etc. This puts us in the situation where we often find ourselves saying, &#8220;Hey Guy, you should give me a job. I&#8217;m a great architect, I&#8217;ve built some awesome buildings, many of which you have seen. I just can&#8217;t show you them, but trust me, I&#8217;m good.&#8221; That obviously sucks.</p>

<p>So, while I disagree with the need to throw money at designers to make pretty websites for libraries whose target audience is Perl developers who already know how to work CPAN and probably know how the rest of us roll, it&#8217;s be nice to have websites for <strong>end-user applications</strong>. You know, the kind of stuff people who don&#8217;t give a damn about the API use, whether it be from the web or the command line. Those are the people that might not know to look in CPAN / perldoc. Those  are the people who don&#8217;t care about our API docs, they just want interface docs and frequent use cases illustrated. In this case, it makes <em>perfect sense</em> to have pretty, user-friendly websites published. IMHO, you should also have a PDF manual. But for libraries? give me a break guy. We got better things to do.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>A gripe about blogs.perl.org</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/03/a-gripe-about-blogsperlorg.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.386</id>

    <published>2010-03-20T19:00:25Z</published>
    <updated>2010-03-20T19:02:34Z</updated>

    <summary>Is it just me who has to re-authenticate on every single page load, or is this a known issue? It&apos;s really annoying? I seem to keep my session fine on the front page, but the MT interface asks me to...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="blogsperlorg" label="blogs.perl.org" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="complaints" label="complaints" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="meta" label="meta" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sessions" label="sessions" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="websucks" label="web sucks" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Is it just me who has to re-authenticate on every single page load, or is this a known issue? It's <em>really</em> annoying? I seem to keep my session fine on the front page, but the MT interface asks me to authenticate every. single. time. I change pages, whether through a GET or POST request.</p>]]>
        
    </content>
</entry>

<entry>
    <title></title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/03/today-ovid-blogged-about-long-running.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.385</id>

    <published>2010-03-20T18:49:39Z</published>
    <updated>2010-03-20T18:59:52Z</updated>

    <summary>Today, Ovid blogged about long-running test-suites and how to optimize them. Yesterday, I was thinking about this same exact thing. I have a project where the compile-time hit of the collective libraries that make up the application is a little...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="aggregatingtests" label="aggregating tests" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="comiletimecosts" label="comile-time costs" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cow" label="COW" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="optimization" label="optimization" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sideeffects" label="side-effects" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tests" label="tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Today, <a href="http://blogs.perl.org/users/ovid/2010/03/aggressive-database-optimisation.html">Ovid blogged about long-running test-suites</a> and how to optimize them.</p>

<p>Yesterday, I was thinking about this same exact thing. I have a project where the compile-time hit of the collective libraries that make up the application is a little on the heavy side. I thought to myself that it would be good use something like <a href="http://search.cpan.org/perldoc?Test::Aggregate">Test::Aggregate</a>, but I wondered if that could mean that some of my tests could be affected by a downstream dependency where the state could be changing at the class level. I don&#8217;t think it&#8217;s very probable, but it could happen and it would be a real pain to debug.</p>
]]>
        <![CDATA[<p>This is where I came up with the idea that maybe it would be best to load all common libraries in an initial process and then run the actual tests in a fork to benefit from COW to maintain a single compilation phase but still keep run-time data separate. While the approach has it&#8217;s own issues, mainly that running the tests in parallel could be a bit of a PITA, I think the idea is worth exploring.</p>

<p>Another thing that I&#8217;ve been thinking about lately, is structuring some of my tests as Moose classes and making liberal of use of exception handling to prevent tests from out-right dying and making my BUILD method responsible for making sure any data that the tests require is in good order and making DEMOLISH method responsible for cleaning up after this particular test. The idea here is to keep all the logic related to testing something and then restoring the previous state in the same place.</p>

<p>Again, I haven&#8217;t really given extensive thought to this, but I suspect that as some projects grow to a sufficient size, the ideas will resurface.</p>
]]>
    </content>
</entry>

<entry>
    <title>New functionality in Cantella::Worker</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/03/new-functionality-in-cantellaworker.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.344</id>

    <published>2010-03-09T02:33:41Z</published>
    <updated>2010-03-09T03:22:47Z</updated>

    <summary>I just released a new version of Cantella::Worker and I&apos;m really happy with the improvements. I updated Cantella::Worker::Manager::Prefork and added a couple of options to add a little more fine-grained controls to the worker processes, such as whether the workers...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cantellaworker" label="Cantella::Worker" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ipc" label="ipc" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="processmanagement" label="process management" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>I just released a new version of <a href="http://github.com/groditi/Cantella-Worker">Cantella::Worker</a> and I'm really happy with the improvements. I updated <a href="http://search.cpan.org/perldoc?Cantella::Worker::Manager::Prefork">Cantella::Worker::Manager::Prefork</a> and added a couple of options to add a little more fine-grained controls to the worker processes, such as whether the workers should detach from the manager's session or not and a way to adjust the priority of worker processes. More importantly, I added the "program name" attribute and functionality and I made children automatically shut down if their manager dies, so that you never have an unsupervised worker pool. Special thanks to <a href="http://search.cpan.org/~rcaputo/">Rocco Caputo</a> for his help. So, here's an example so you can see the progress made:</p>]]>
        <![CDATA[<p>Here is the script we will be running:<br />
<script src="http://gist.github.com/326100.js?file=manager-assassinated.pl"></script></p>

<p>Now, Here is how we interact with it:<br />
<script src="http://gist.github.com/326100.js?file=interacting+with+manager-assassinated.pl"></script></p>

<p>And Finally, this is the log of events:<br />
<script src="http://gist.github.com/326100.js?file=evidence.log"></script></p>

<p>neat huh?</p>]]>
    </content>
</entry>

<entry>
    <title>Introducing Cantella::Worker / Cantella::Worker::Role::Beanstalk</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/03/introducing-cantellaworker-cantellaworkerrolebeanstalk.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.320</id>

    <published>2010-03-03T21:39:10Z</published>
    <updated>2010-03-03T22:01:14Z</updated>

    <summary>Yesterday and today I released to CPAN Cantella::Worker and Cantella::Worker::Role::Beanstalk. I am very happy with these two packages. They are the culmination of about a month of on-and-off playing around with different approaches to having distributed event-driven worker processes. As...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="beanstalk" label="beanstalk" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantella" label="Cantella" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantellaworker" label="Cantella::Worker" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jobqueue" label="job queue" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="poe" label="Poe" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Yesterday and today I released to <a href="http://search.cpan.org/~groditi/">CPAN</a> <a href="http://github.com/groditi/Cantella-Worker">Cantella::Worker</a> and <a href="http://github.com/groditi/Cantella-Worker-Role-Beanstalk">Cantella::Worker::Role::Beanstalk</a>. I am very happy with these two packages. They are the culmination of about a month of on-and-off playing around with different approaches to having distributed event-driven worker processes. As an added benefit, I can also run a pool of <a href="http://kr.github.com/beanstalkd/">beanstalkd</a> servers in case I need to bring one down for maintenance or I have some unexpected downtime.</p>

<p>I am aware of the existence of <a href="http://search.cpan.org/dist/MooseX-Workers/">MooseX-Workers</a>, but it didn&#8217;t &#8216;feel&#8217; right for the job. Additionally, the MooseX-Workers approach of running jobs in a separate process via <a href="http://search.cpan.org/perldoc?POE::Wheel::Run">POE::Wheel::Run</a> didn&#8217;t work very well for my approach. You see, in order to reserve a job from beanstalk, a connection must be open with the server. During a fork, I could either fork and keep file handles open, making sure the file-handle survived, or lose my connection and my reserved job. Additionally, the constant forking was a little too much over-head for the very simple jobs I do. </p>

<p>Instead of trying to make MooseX-Workers do what it wasn&#8217;t designed to, I decided to go with a <a href="http://search.cpan.org/perldoc?Cantella::Worker::Manager::Prefork">preforking approach</a> and roll my own approach. I have a manager process and <em>n</em> children processes. Children processes are free to work by themselves and block if they want to. Communications between the manager and worker processes happens via POSIX signals. Right now 3 commands are supported, pause (USR1), resume (USR2), shutdown (TERM &amp; INT). </p>

<p>So far, the preforking manager is pretty basic, but I look forward to adding the following in the future:</p>

<ul>
<li>Detaching children that terminate themselves if the parent dies</li>
<li>User, group, priority adjustments in the child process</li>
<li>More real world examples.</li>
</ul>
]]>
        

    </content>
</entry>

<entry>
    <title>Cantella::Store::UUID - 0.002000</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/01/cantellastoreuuid---0002000.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.183</id>

    <published>2010-01-12T03:11:39Z</published>
    <updated>2010-01-12T03:31:06Z</updated>

    <summary>I&apos;ve released a new version of Cantella::Store::UUID. (git) It features one incompatible change, but I figured it was OK since I&apos;m pretty sure nobody is using it and it is reasonably new. I just couldn&apos;t live with having one lone...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cantella" label="Cantella" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantellastoreuuid" label="Cantella::Store::UUID" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="storage" label="storage" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="uuid" label="UUID" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>I've released a new version of <a href="http://search.cpan.org/dist/Cantella-Store-UUID/">Cantella::Store::UUID</a>. (<a href="http://github.com/groditi/Cantella-Store-UUID/tree/0.002000">git</a>) It features one incompatible change, but I figured it was OK since I'm pretty sure nobody is using it and it is reasonably new. I just couldn't live with having one lone method named so awkwardly. The POD was all updated and improved and two new methods were added, which allow the user to search for files in the storage directory and perform some action on these files. I don't really intend for these methods to be used a lot, since they will take minutes to run on most systems and be incredibly IO-intensive (depth-first search of the entire storage tree, which could be hundreds of thousands of nodes). I use them mainly for maintenance operations and you should probably too.</p>

<p>These methods existed in the internal version this library was based on, but due to a bug in <a href="http://search.cpan.org/perldoc?Path::Class::Dir">Path::Class::Dir</a>, I was unable to add these features until Path::Class 0.18 was released with <a href="http://rt.cpan.org/Public/Bug/Display.html?id=48612">the fix</a>. As of now, this module can be considered stable. I promise to add no code without extensive tests and change no APIs unless it's really, really necessary. Even then, there will be a long deprecation cycle and a back-compat layer. </p>

<p>If you haven't already seen it, I recommend you take a look at Cantella::Store::UUID. I use it to store many, many files in the file system without concentrating too many files in any one directory. Accessing files is quick because their location is deterministic (based on their UUID) and you can split the hierarchy into different physical devices to improve performance or add capacity. It's not very high-tech, but it works surprisingly well if you have huge numbers of files to store. Another nice thing is that you can mirror it with r-sync or create incremental back-ups using <a href="http://rdiff-backup.nongnu.org/">rdiff-backup</a>.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>MooseX::TypeMap</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/01/moosextypemap.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.171</id>

    <published>2010-01-07T01:44:46Z</published>
    <updated>2010-01-07T02:04:44Z</updated>

    <summary>Two ago I began writing the beginnings of what was to be the first Cantella::Data::Tabular renderer class. The idea was to render a Cantella::Data::Tabular::Table object into a plain text table. I failed miserably. Within 5 seconds I got wrapped up...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cantella" label="Cantella" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantelladatatabular" label="Cantella::Data::Tabular" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="moose" label="Moose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="moosextypemap" label="MooseX::TypeMap" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="typeconstraints" label="type-constraints" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Two ago I began writing the beginnings of what was to be the first <a href="http://github.com/groditi/Cantella-Data-Tabular">Cantella::Data::Tabular</a> renderer class. The idea was to render a Cantella::Data::Tabular::Table object into a plain text table. I failed miserably. Within 5 seconds I got wrapped up on issues of formatting and how to render data  and data-types. Eventually I resorted to #moose for ideas and <a href="http://perldition.org/">rafl</a> pointed me towards some code of his. We agreed that it would be mutually beneficial to use if I got to use his code as long as I separated it from its original package, and packaged it separately so it could stand alone. </p>

<p>The idea behind MooseX::TypeMap is simple: it holds a series of "Entry" objects which have <strong>type_constraint</strong> and <strong>data</strong> attributes. You can then give MooseX::TypeMap an instance of a <a href="http://search.cpan.org/perldoc?Moose::Meta::TypeConstraint">Moose::Meta::TypeConstraint</a> and it will give you back the <strong>data</strong> associated with that type-constraint or, optionally, it's closest super-type that TypeMap knows. That's it. It's simple and it's short and it's hardly very exciting, but it will make my life easier.</p>

<p>Take, for example, a Cantella::Data::Tabular renderer, which needs to render different cells based on their associated type-constraint. Different people may want to have different rendering rules, and a good way to implement the conversion would be using MooseX::TypeMap to automatically fetch a closure or printf format based on the cell's type. A sane default could be shipped with the formatter and the user could either modify it or replace it to match his/her needs in only a couple of lines of code.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Tabular Data, spreadsheets and cell references</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2010/01/tabular-data-spreadsheets-and-cell-references.html" />
    <id>tag:blogs.perl.org,2010:/users/guillermo_roditi1//130.160</id>

    <published>2010-01-04T00:10:09Z</published>
    <updated>2010-01-07T01:48:25Z</updated>

    <summary>Since Cantella::JobQueue has been put on hold after the discovery of Beanstalkd, I&apos;ve moved on to other projects. The first on my list was to add some new views to a Reaction-based application. Specifically, I needed a couple of ways...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cantella" label="cantella" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantelladatatabular" label="Cantella::Data::Tabular" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="excel" label="excel" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="oss" label="oss" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="spreadsheet" label="spreadsheet" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tabular" label="tabular" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Since Cantella::JobQueue has been put on hold after the discovery of Beanstalkd, I've moved on to other projects. The first on my list was to add some new views to a Reaction-based application. Specifically, I needed a couple of ways to export tabular data. I needed to display it as inline XHTML tables, export it as PDF sheets and allow for spreadsheet downloads. Because none of the current offerings gave me the flexibility I wanted, I decided to write my own.</p>

<p><a href="http://github.com/groditi/Cantella-Data-Tabular">Cantella::Data::Tabular</a> is a library for working with (surprise, surprise) tabular data. It contains three main objects, so far. Cells, rows and tables. A table has zero or more rows, and row has zero or more cells and a cell has zero or one value. Additionally, cells will be able to store certain meta-data to facilitate round-trip conversions from certain formats like ".xls". One of the decisions I made from the start was to disallow cells with 'undef' as a value. Cells can either have a value, which must be defined, or have no value. Additionally, I decided that I wanted different rows to be able to have a different number of columns. Lastly, I decided that the whole library should be completely unaware of what cell values mean. That means no references, no functions and no ranges. Values are simply values and it should be up to a higher-level library to decipher exactly what those values mean or don't mean. I did, however, build in cell-level type-constraints.</p>

<p>The library may seem limited, and may not grow to be expanded beyond the most basic needs, but that's the way I want it. Exporters and importers that write or read from Excel / CSV / HTML / PDF files will be made available separately as they become necessary. What I don't want to end up with is a spreadsheet library. I wouldn't mind building another library on top of C::D::T that is able to perform basic spreadsheet functions, but it's a slippery slope to go down.</p>

<p>As of right now, the library has basic tests and is almost fully documented. It hasn't been released to CPAN yet, but it will as soon as it does something useful. I just wanted to let people know this thing exists and invite any comments, suggestions, feature requests or  criticisms you might have. </p>
]]>
        

    </content>
</entry>

<entry>
    <title>Reaction and CRUD implemented in Roles</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2009/12/reaction-and-crud-implemented-in-roles.html" />
    <id>tag:blogs.perl.org,2009:/users/guillermo_roditi1//130.114</id>

    <published>2009-12-15T23:28:29Z</published>
    <updated>2009-12-16T00:06:56Z</updated>

    <summary>Ever since Moose::Role came to life, I have been dying to refactor the default CRUD implementation in Reaction to use Roles. Over the last couple of months I slowly did that work as I had tuits, and today, after months...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="crud" label="CRUD" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mooserole" label="Moose::Role" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="reaction" label="Reaction" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="roles" label="roles" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="web" label="web" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>Ever since <a href="http://search.cpan.org/perldoc?Moose::Role">Moose::Role</a> came to life, I have been dying to refactor the default CRUD implementation in <a href="http://search.cpan.org/dist/Reaction/">Reaction</a> to use Roles. Over the last couple of months I slowly did that work as I had tuits, and today, after months of being finished, I finally got the chance to merge and push back the branch to trunk. As of today, all of the CRUD functionality in Reaction is supplied by independent roles. Which means one can do something like the following:</p>

<script src="http://gist.github.com/257427.js"></script>

<p>Which all-in-all is a pretty easy way to create Create / View / List functionality for one of the Collections in your Model. Look for more actions to be added in the near future.</p>

<p>At present, the web interface to the Reaction repo is undergoing maintenance and possibly migration, so I don't have a better link for you, but I hopefully will soon.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Lock me away</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/guillermo_roditi1/2009/12/lock-me-away.html" />
    <id>tag:blogs.perl.org,2009:/users/guillermo_roditi1//130.89</id>

    <published>2009-12-10T20:12:27Z</published>
    <updated>2009-12-10T21:27:35Z</updated>

    <summary>I am in the process of writing Yet Another Job Queue, Cantella::JobQueue. I decided from the beginning that I wanted a well-defined API for the storage layer, so that as different back ends would be easy to write and swap...</summary>
    <author>
        <name>Guillermo Roditi</name>
        <uri>http://search.cpan.org/~groditi</uri>
    </author>
    
    <category term="cantella" label="cantella" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="cantellajobqueue" label="Cantella::JobQueue" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jobqueue" label="job queue" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="lock" label="lock" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="oss" label="oss" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="projects" label="projects" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="queueing" label="queueing" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/guillermo_roditi1/">
        <![CDATA[<p>I am in the process of writing <a href="http://search.cpan.org/dist/TheSchwartz/">Yet</a> <a href="http://search.cpan.org/dist/Gearman/">Another</a> <a href="http://search.cpan.org/dist/Swarmage/">Job</a> <a href="http://search.cpan.org/dist/POE-Component-JobQueue/">Queue</a>, <a href="http://github.com/groditi/Cantella-JobQueue">Cantella::JobQueue</a>. </p>

<p>I decided from the beginning that I wanted a well-defined API for the storage layer, so that as different back ends would be easy to write and swap around. While writing the tests for the first one, I encountered a problem that&#8217;s been haunting me since: how to deal with locks.</p>

<p>Originally, I imagined a job would either be locked, or not locked and manager processes would be in charge of releasing locks if workers died / failed. Then I started thinking, what if a manager process dies? Who releases the locks? So I decided to add time-based automatic lock expiration. This introduced a new problem, a possible race condition. What if a job takes so long that it&#8217;s lock times out before the job is done? What do I do then?</p>

<p>A possibility is to have a manager process / thread that monitors its workers and updates the lock-expiry time, which is the route I am likely to take. I don&#8217;t particularly like it, but I can&#8217;t come up with anything better right now. </p>

<p>I&#8217;d love to hear from anyone that has any experience with this kind of problem.</p>
]]>
        

    </content>
</entry>

</feed>
