<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>david rasch -- technology. business. life. &#187; cli</title>
	<atom:link href="http://www.davidrasch.com/tag/cli/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidrasch.com</link>
	<description></description>
	<lastBuildDate>Fri, 21 May 2010 02:58:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>MogileFS and race condition</title>
		<link>http://www.davidrasch.com/2008/01/29/mogilefs-and-race-condition/</link>
		<comments>http://www.davidrasch.com/2008/01/29/mogilefs-and-race-condition/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 02:14:47 +0000</pubDate>
		<dc:creator>drasch</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[iContact]]></category>
		<category><![CDATA[mogilefs]]></category>
		<category><![CDATA[race condition]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.davidrasch.com/2008/01/29/mogilefs-and-race-condition/</guid>
		<description><![CDATA[<p>As any readers of the iContact blog may have learned, MogileFS has become an integral part of our infrastructure at iContact.  Rather than store the bodies of messages in our database, we moved them to a quick&#038;dirty storage method in our infrastructure long ago.  This method was essentially a cheap WebDAV server and on <span style="color:#777"> . . . &#8594; Read More: <a href="http://www.davidrasch.com/2008/01/29/mogilefs-and-race-condition/">MogileFS and race condition</a></span>]]></description>
			<content:encoded><![CDATA[<p>As any readers of the iContact blog may have learned, <a href="http://www.danga.com/mogilefs/">MogileFS</a> has become an integral part of our infrastructure at iContact.  Rather than store the bodies of messages in our database, we moved them to a quick&#038;dirty storage method in our infrastructure long ago.  This method was essentially a cheap WebDAV server and on each STORE command it would write to two backend servers and issue a GET from only one.  About a month ago, we migrated most of our messages away from this older, less scalable method to our newer MogileFS backend.  </p>
<p>Our MogileFS setup allows the disk space on each web server (normally unutilized) to form a cheap storage node, and make use of space that would otherwise go entirely unused.  </p>
<p>On Monday 1/21 the database servers behind MogileFS paged with too many connections, which leads to Mogile going very slowly for a while, and sometimes requiring a restart of some of the nodes.  </p>
<p>This database issue cascaded into us asking our Mogile client for item A, but receiving item B in response&#8230;<br />
<span id="more-72"></span><br />
The problem turned out to be at the lowest level, that of the socket communication with Mogile.  The request chain asked for item A, but since the database was responding very slowly, the &#8220;fread&#8221; waiting for the response timed out.  Unfortunately, the timeout simply passes back up the chain as a &#8220;not found&#8221;.  In the background, the data for the response to the request was buffered by TCP.  We handled the error, told our daemon to check later for that item, and proceeded to ask for item B.  When doing another &#8220;fread&#8221; for the response, we received the data from the original request.  Since all was well, we continued requesting items and receiving a non-matching item in response.  </p>
<p>In order to fix this on our end, we simply made the connection terminate when any of these timeouts occurs.  Additionally, we&#8217;ll be adding application-level matching for these requests and responses (the data we store in Mogile will likely include the key so when we pull it back out, it can be check-summed against the requested key).</p>
<p>However, I wonder if it&#8217;d make sense for the MogileFS protocol itself to support this matching.  It seems key that this type of problem not affect others, so I encourage you to check your client for such a problem, and I plan to file bugs against those who have the bug we found.  We were using an old PEAR module as we sought a client with a non-GPL license for inclusion in our codebase.  However, a cursory examination of the <a href="http://www.capoune.net/mogilefs/">PHP extension </a> we were coveting seems it might be subject to the same problem.  </p>
<p>Other than this issue (and the large headache it caused), which mostly lies on the client side (unless I get any pickup on the protocol-level support above), MogileFS has proved to be a great asset to our infrastructure and I look forward to seeing it scale to much more data.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidrasch.com/2008/01/29/mogilefs-and-race-condition/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP on the Backend (part 2)</title>
		<link>http://www.davidrasch.com/2007/05/08/php-on-the-backend-part-2/</link>
		<comments>http://www.davidrasch.com/2007/05/08/php-on-the-backend-part-2/#comments</comments>
		<pubDate>Tue, 08 May 2007 23:34:02 +0000</pubDate>
		<dc:creator>drasch</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[daemon]]></category>

		<guid isPermaLink="false">http://www.davidrasch.com/2007/05/08/php-on-the-backend-part-2/</guid>
		<description><![CDATA[<p>To run the class I posted yesterday, I typically use a class called DaemonRunner.  This class sets up for proper signal handling, and &#8216;executes&#8217; the class extended from Daemon.</p>

declare(ticks=1);

class DaemonRunner {
    public static function exec($className) {
        $argv = $_SERVER['argv'];
       <span style="color:#777"> . . . &#8594; Read More: <a href="http://www.davidrasch.com/2007/05/08/php-on-the-backend-part-2/">PHP on the Backend (part 2)</a></span>]]></description>
			<content:encoded><![CDATA[<p>To run the class I <a href="http://www.davidrasch.com/2007/05/07/php-on-the-backend/">posted yesterday</a>, I typically use a class called <em>DaemonRunner</em>.  This class sets up for proper signal handling, and &#8216;executes&#8217; the class extended from Daemon.</p>
<pre>
declare(ticks=1);

class DaemonRunner {
    public static function exec($className) {
        $argv = $_SERVER['argv'];
        $daemon = new $className($argv);
        $daemon->init();
        while (!$daemon->isDone()) {
            $daemon->run();
        }
        $daemon->shutdown();
    }
}
</pre>
<p>The first statement is a PHPism.  This allows PHP to check for signals every 1 <em>tick</em>.  A tick is simply a low-level PHP interpreter step.  The way I&#8217;ve setup my daemon and signal handling by default, the PHP will finish its current iteration and then quit when receiving a signal.  This ensures that the database, and whatever background stuff aren&#8217;t left in inconsistent states.  As with anything, you&#8217;re free to modify, extend, or otherwise alter this behavior.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidrasch.com/2007/05/08/php-on-the-backend-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP on the Backend</title>
		<link>http://www.davidrasch.com/2007/05/07/php-on-the-backend/</link>
		<comments>http://www.davidrasch.com/2007/05/07/php-on-the-backend/#comments</comments>
		<pubDate>Tue, 08 May 2007 00:55:39 +0000</pubDate>
		<dc:creator>drasch</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[cli]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[daemon]]></category>

		<guid isPermaLink="false">http://www.davidrasch.com/2007/05/07/php-on-the-backend/</guid>
		<description><![CDATA[<p>PHP (or any language for that matter) can just as easily be used as a daemon as on the web.  This can be especially useful when solving problems that can&#8217;t &#8220;complete&#8221; in less than 500 ms which one shoots for on the web.   As you write an application to handle things such as <span style="color:#777"> . . . &#8594; Read More: <a href="http://www.davidrasch.com/2007/05/07/php-on-the-backend/">PHP on the Backend</a></span>]]></description>
			<content:encoded><![CDATA[<p>PHP (or any language for that matter) can just as easily be used as a daemon as on the web.  This can be especially useful when solving problems that can&#8217;t &#8220;complete&#8221; in less than 500 ms which one shoots for on the web.   As you write an application to handle things such as those mentioned below, be sensitive to the processing, disk space, and time needed to process these requests in planning how to handle these.  As an example jobs of a small size might be handled inline by the code that handles the form submission, but for larger jobs it queues them for background processing.  </p>
<p>great for background/async processing of:</p>
<ul>
<li>photos</li>
<li>movies</li>
<li>reports</li>
<li>imports of data</li>
</ul>
<p>advantages: </p>
<ul>
<li>use the same codebase as your app</li>
<li>use the same expertise on your team of programmers</li>
</ul>
<p>challenges:</p>
<ul>
<li>signals</li>
<li>one thread</li>
<li>memory (this will have to be a whole separate article)</li>
<li>starting and stopping</li>
</ul>
<p>A typical Daemon class I use:</p>
<pre>
abstract class Daemon {
    protected $done = false;

    public function __construct($argv) {
    }
    public function init() {
        pnctl_signal(SIGTERM, array($this, "onSignal"));
        pnctl_signal(SIGINT, array($this, "onSignal"));

    }
    abstract public function run();
    public function shutdown() {}
    public function isDone() {
        return $this->done;
    }
    public onSignal($signal){
        switch ($signal) {
             case SIGTERM:
             case SIGINT:
                $this->done = true;
                 break;
             default:
                 // handle all other signals
        }
    }
}</pre>
<p>As you can see, we&#8217;ve started to tackle some of the challenges here.  The idea is to handle signals, specifically I usually care about SIGTERM (default when using &#8216;kill&#8217; on *nix) and SIGINT (from pressing Ctrl-C).  Both will cause the program to exit gracefully.</p>
<p>I&#8217;ll be posting the class I use to run Daemon&#8217;s tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidrasch.com/2007/05/07/php-on-the-backend/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
