<?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>dev.fuzzee.co.uk &#187; phpnw</title>
	<atom:link href="http://dev.fuzzee.co.uk/tag/phpnw/feed/" rel="self" type="application/rss+xml" />
	<link>http://dev.fuzzee.co.uk</link>
	<description>stuff that pops into my head ... technical stuff.</description>
	<lastBuildDate>Sun, 18 Apr 2010 13:39:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Quick guide to Linux daemons in PHP</title>
		<link>http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/</link>
		<comments>http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 21:26:04 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpnw]]></category>

		<guid isPermaLink="false">http://dev.fuzzee.co.uk/?p=39</guid>
		<description><![CDATA[This guide was originally written for a PHPNW meetup &#8211; more information on the group is available here
Whenever we want to carry out lengthy tasks or process large batches of data, we should consider executing that process in the background. The most typical way of doing this is through &#8220;cron jobs&#8221; &#8211; tasks which are [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This guide was originally written for a PHPNW meetup &#8211; more information on the group is available <a href="http://www.phpnw.org.uk">here</a></strong></p>
<p>Whenever we want to carry out lengthy tasks or process large batches of data, we should consider executing that process in the background. The most typical way of doing this is through &#8220;cron jobs&#8221; &#8211; tasks which are scheduled to be executed at regular intervals; every 2 minutes, or at 6am every Sunday. Alternatively, you can have the web browser instigate the task by using something like <code>shell_exec()</code>. This guide presents a third alternative, <strong>system level daemons</strong>.<br />
<span id="more-39"></span></p>
<div class="toc">
<ol>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-introduction">Introduction</a></p>
<ol>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-why-is-a-daemon-better-than-a-cron-job">Why is a daemon better than a cron job</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-why-is-a-daemon-better-than-shell_exec">Why is a daemon better than shell_exec()</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-single-background-process">Single background process</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-multiple-background-processes-managed-by-a-parent">Multiple background processes managed by a parent</a></li>
</ol>
</li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-sample-application">Sample Application</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-signal-handlers">Signal Handlers</a>
<ol>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-important-tip-for-signals">Important tip for signals</a></li>
</ol>
</li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-init-d-scripts">Init.d scripts</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-real-life-examples">Real Life Examples</a>
<ol>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-reporting-system">Reporting System</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-sms-processing">SMS Processing</a></li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-co-ordinating-remote-service-requests">Co-ordinating remote service requests</a></li>
</ol>
</li>
<li><a href="http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/#toc-things-to-watch-out-for">Things to watch out for</a></li>
</ol>
</div>
<h2 id="toc-introduction">Introduction</h2>
<p>Put simply, a daemon is a very long running process. Even when it has completed all its tasks, it stays resident, waiting for some work to do. They may spend a lot of their time sleeping, but if designed correctly, they spring to life when required. Of course, they may be constantly listening out for events (by reading a named pipe for example), rather than periodically checking to see if work is available.</p>
<h3 id="toc-why-is-a-daemon-better-than-a-cron-job">Why is a daemon better than a cron job</h3>
<p>For the same reason that web pages are not served by a cronjob running every minute. Daemons are designed to be much more responsive. Cron jobs are very reliable, but sometimes they are less &#8220;elegant&#8221;. </p>
<h3 id="toc-why-is-a-daemon-better-than-shell_exec">Why is a daemon better than shell_exec()</h3>
<p>Irrespective of whether your process is triggered by an HTTP request or some other event, it might not be appropriate to create one process per request. If your process requires considerable resources, then you may end up swamping the server.</p>
<p>Broadly speaking, daemons can come in two flavours:</p>
<ul>
<li>Single background process</li>
<li>Multiple background processes managed by a parent</li>
</ul>
<h3 id="toc-single-background-process">Single background process</h3>
<p>The parent creates a copy of itself (a process known as &#8220;forking&#8221;) and then dies. This leaves the single process running in the background. This type of daemon is very easy to manage and develop. </p>
<h3 id="toc-multiple-background-processes-managed-by-a-parent">Multiple background processes managed by a parent</h3>
<p>The parent creates a child, and then dies. That new child then creates multiple children. Each of these children is a &#8220;worker thread&#8221; and responsible for the heavy lifting. The parent of those children is responsible for distributing their workload amongst them. Apache HTTPd is a prime example of this &#8211; in the configuration you can choose how many children it can create, the minimum number of children to have available, etc.  </p>
<p>Daemons provide a nice balance between the managed rigidity of a cron job while still being responsive.</p>
<h2 id="toc-sample-application">Sample Application</h2>
<p>I have recently found a handy PEAR library for creating PHP daemons &#8211; <a href="http://pear.php.net/package/System_Daemon/">System_Daemon</a>. It greatly simplifies the task of creating a daemon, although the library only supports &#8220;Single background process&#8221; type daemons.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">&quot;System/Daemon.php&quot;</span><span style="color: #339933;">;</span>
System_Daemon<span style="color: #339933;">::</span><span style="color: #004000;">setOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;appName&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;myDaemon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
System_Daemon<span style="color: #339933;">::</span><span style="color: #004000;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #990000;">sleep</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// prevent CPU hogging</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// simulate a random event which requires handling</span>
      System_Daemon<span style="color: #339933;">::</span><span style="color: #990000;">log</span><span style="color: #009900;">&#40;</span>System_Daemon<span style="color: #339933;">::</span><span style="color: #004000;">LOG_INFO</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Doing something interesting...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This daemon does pretty much nothing, other than stay in the background, slowly adding to a log file. However, it demonstrates that you can have a very &#8220;lightweight&#8221; process listening for system events in only a few lines of code. It&#8217;s also important to have some element of a &#8220;forever&#8221; loop in there to keep the process going.</p>
<h2 id="toc-signal-handlers">Signal Handlers</h2>
<p>Signals are a very basic form of <b>Inter-process communication</b>. In its most common usage, you would send a <b>SIGTERM</b> signal to a process by using the <code>kill</code> command. We can trap <b>SIGTERM</b> signals explicitly and shutdown &#8220;nicely&#8221;. This means any work being carried out can be finished off cleanly, and then the process will terminate. We can trap many other signals, all of which can be sent via &#8220;kill&#8221; on the command line, or more interestingly, the PHP function <b>posix_signal()</b>.</p>
<h4 id="toc-important-tip-for-signals">Important tip for signals</h4>
<p>I discovered this recently : PHP&#8217;s <code>sleep()</code> method is interrupted by signal interrupts. This means you can have a fairly lazy daemon (e.g. sleeps for 5 seconds every interation) and when you want to wake it up, you send it a SIGTERM signal. When interrupted this way, <code>sleep()</code> returns how many seconds were left at the point of interruption.</p>
<p>System_Daemon wraps up <code>pcntl_signal()</code> for us into</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">System_Daemon<span style="color: #339933;">::</span><span style="color: #004000;">setSigHandler</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$signalConstant</span><span style="color: #339933;">,</span> <span style="color: #000088;">$handlerName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2 id="toc-init-d-scripts">Init.d scripts</h2>
<p>The <b>System_Daemon</b> library can generate init.d scripts for us, which means (for me at least) I can and stop/start a daemon with:</p>
<pre>
/sbin/service myDaemon restart
</pre>
<p>Because we studiously assigned a SIGTERM handler, when we ask the daemon to stop using our init.d script, it will shutdown cleanly. </p>
<h2 id="toc-real-life-examples">Real Life Examples</h2>
<h4 id="toc-reporting-system">Reporting System</h4>
<p>Reports can take anywhere between 10 seconds and 3 hours to generate. Requests for report generation were stored in a database and the Reporting Daemon picked them up and processed them. The report was written to disk and made available in a reports area. The system remained responsive irrespective of how many reports were requested. </p>
<h4 id="toc-sms-processing">SMS Processing</h4>
<p>A large, multinational mobile promotions company received hundreds of SMSes a second. In order to be an effective product, the SMS request must have a response as quickly as possible. During promotional periods SMS traffic would sky rocket. Each inbound SMS was written to a database and then awaited processing by the daemon. A similar system was written for outbound SMS messages. The entire SMS platform used about 5 PHP Daemons and was the bread-and-butter of a £40m+ company.</p>
<h4 id="toc-co-ordinating-remote-service-requests">Co-ordinating remote service requests</h4>
<p>On a much smaller scale than the previous two examples, I wrote a simple caching daemon. The daemon would listen out for SIGINT signals (sent by a web page using <code>posix_signal()</code>)  During quiet periods, the daemon would forward requests to the remote service as they came in. During busy periods, the daemon would batch them together. Because the daemon acted as a centralised point for communications, it was the best place to judge work load. For those interested, the web page communicated with the daemon using <b>System V queues</b>, with more information <a href="http://uk.php.net/manual/en/book.sem.php">here</a>.</p>
<h2 id="toc-things-to-watch-out-for">Things to watch out for</h2>
<ul>
<li>The PCNTL library (required for this excercise) is only available when running PHP on the command line (cli mode)</li>
<li>You will soon notice that calls to <code>echo</code> or <code>print</code> are quite distracting when the daemon is running.</li>
<li>Going from personal experience, fatal errors can be hard to track down. Sometimes the process will die with nothing having been written to <code>/var/log/php_error</code>.</li>
<li>Any resources opened before forking, may not be available after the fork (e.g file pointers, db connections). Because pcntl_fork() creates a copy of the current process, when the parent is killed off, all resources are closed. The child, now holding a reference to a closed resource, will trigger an error when that resource is accessed.</li>
<li>Certain resources close after a period of inactivity (I&#8217;m looking at you, MySQL) &#8211; check that your resources are available before using them.</li>
<li>Because the script never shuts down (or shuts down rarely) memory leaks can be problematic.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dev.fuzzee.co.uk/2009/07/quick-guide-to-linux-daemons-in-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
