<?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>Dan Cryer - Leeds Web Developer &#187; php</title>
	<atom:link href="http://www.dancryer.com/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dancryer.com</link>
	<description>Dan Cryer - Leeds Web Developer</description>
	<lastBuildDate>Mon, 06 Sep 2010 22:05:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>VPS.NET Auto Recovery Monitor</title>
		<link>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor</link>
		<comments>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor#comments</comments>
		<pubDate>Tue, 29 Jun 2010 18:26:47 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Other Things]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[vps.net]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=539</guid>
		<description><![CDATA[I&#8217;ve been using VPS.NET for months now, both for myself and for Media Wow. Whilst their platform is incredibly stable, and their automated failover is great, there are still occasionally times when a server will go down and not come back up by itself. The nicely integrated Server Density monitoring does a great job of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using VPS.NET for months now, both for myself and for Media Wow. Whilst their platform is incredibly stable, and their automated failover is great, there are still occasionally times when a server will go down and not come back up by itself. </p>
<p>The nicely integrated Server Density monitoring does a great job of informing you if a server is down, but it can&#8217;t do anything about it. So I&#8217;ve created a script that I run on an external server to check all of the servers are up (via HTTP) and reboot those that are not. It&#8217;s fairly simple, the process is as follows:</p>
<ul>
<li>Get a list of VMs from VPS.NET.</li>
<li>For each VM, send a GET request to http://{hostname}.{domainname}/ and give it (by default) 5 seconds to respond.</li>
<li>If the server does not respond, it will check if it is marked as &#8220;running&#8221; on VPS.NET &#8211; by default it will then assume that there is simply a routing issue.</li>
<li>If it is not, it will check if the server is already in a power change state (i.e. startup, reboot).</li>
<li>Finally, if neither of the above are true, it will send a power on request to VPS.NET.</li>
<li>After all of that, it&#8217;ll (optionally) send you an email to let you know.</li>
</ul>
<p>The code is below. You can also <a href="/files/monitor.php.zip">download it here</a>. Let me know if you find it useful!</p>
<p><strong>Notes:</strong></p>
<ul>
<li>This script needs setting up as a cron job, on an off-site server / computer. I recommend running it every 5 minutes or so.</li>
<li>I don&#8217;t use the VPS.NET API PHP classes because they seem to be out of date.</li>
<li>This script *will* spam you to oblivion if there is a cloud issue and you set it up to email in all cases.</li>
</ul>
<div style="height: 300px; width: 100%; overflow: auto;">
<pre class="php" name="code">< ?php

//----
// Set up the monitoring script:
//----

define('MONITOR_MAIL_TO', '');     // Email address to send alerts to.
define('MONITOR_API_EMAIL', ''); // Email address associated with VPS.NET API account.
define('MONITOR_API_KEY', '');     // VPS.NET API key.
define('MONITOR_SEND_EMAILS', true);               // Whether or not to send emails if a server is flagged as down.
define('MONITOR_SEND_EMAILS_ON_NO_ACTION', true);  // Whether or not to send emails if no action is taken.
define('MONITOR_REBOOT_IF_RUNNING', true);         // If HTTP check fails, but VPS.NET says the server is up, reboot?
define('MONITOR_HTTP_TIMEOUT', 5);                 // Number of seconds to allow for a server response. 

//----
// Initialise API Class and get VMs:
//----
$api = new SimpleVpsApi();
$api->setApiEmail(MONITOR_API_EMAIL);
$api->setApiKey(MONITOR_API_KEY);
$vms = $api->getVMs();

//----
// Loop through all the VMs and check their status:
//----
$out     = '';
foreach($vms as $vm)
{
	$server = $vm['virtual_machine']['hostname'] . '.' . $vm['virtual_machine']['domain_name'];
	$id     = $vm['virtual_machine']['id'];

	$get = false;
	$get = @file_get_contents('http://'.$server.'/', false, stream_context_create(array('http' => array('timeout' => MONITOR_HTTP_TIMEOUT))));

	if(!$get)
	{
		$_out .= 'Server ' . $server . ' appears to be DOWN!'.PHP_EOL;

		$vm = $api->getVM($id);

		if($vm['power_action_pending'])
		{
			$_out .= '- VPS.NET is reporting that the server is rebooting already. Taking no action.'.PHP_EOL;

			if(!MONITOR_SEND_EMAILS_ON_NO_ACTION)
			{
				$_out = '';
			}
		}
		elseif($vm['running'] &#038;&#038; !MONITOR_REBOOT_IF_RUNNING)
		{
			$_out .= '- VPS.NET is reporting the server as running. Taking no action.'.PHP_EOL;

			if(!MONITOR_SEND_EMAILS_ON_NO_ACTION)
			{
				$_out = '';
			}
		}
		elseif($vm['running'] &#038;&#038; MONITOR_REBOOT_IF_RUNNING)
		{
			$api->rebootVM($id);
			$_out .= '- VPS.NET is reporting the server as running. Rebooting.'.PHP_EOL;
		}
		else
		{
			$api->bootVM($id);
			$_out .= '- Submitted an automated power on request to VPS.NET.'.PHP_EOL;
		}

		// If we've logged anything for this VM, append it to the log:
		if($_out)
		{
			if($out != '')
			{
				$out .= PHP_EOL;
			}

			$out .= $_out;
			$_out = '';
		}
	}
}

//----
// Emailing functionality, for notification of server downtime:
//----

$email = '<html>
	<body>
<div style="background: #ddd; font-family: arial, verdana, sans-serif; font-size: 13px; padding: 15px;">
		<strong style="font-size: 20px; margin-bottom: 15px">Server Monitoring Notice</strong>
<div style="background: #fff; border: 1px solid #ccc; color: #333; margin: 15px 0; padding: 15px">
			<!--content-->
		</div>
</div>

	</body>
</html>';

if($out != '' &#038;&#038; MONITOR_SEND_EMAILS)
{
	$email = str_replace('<!--content-->', nl2br($out), $email);
	mail(MONITOR_MAIL_TO, 'Server Monitoring Notice', $email, 'Content-Type: text/html'."\r\n");
}

//----
// Custom class for interacting with the VPS.NET API:
//----

class SimpleVpsApi
{
	const TYPE_GET  = 1;
	const TYPE_POST = 2;

	protected $apiUrl   = 'api.vps.net/';
	protected $apiEmail = null;
	protected $apiKey   = null;

	/**
	* Set the email address to use in requests:
	*/
	public function setApiEmail($email)
	{
		$this->apiEmail = $email;
	}

	/**
	* Set the API key to use in requests:
	*/
	public function setApiKey($key)
	{
		$this->apiKey = $key;
	}

	/**
	* Get a list of all VMs:
	*/
	public function getVMs()
	{
		$vm = $this->sendApiRequest('virtual_machines', 'GET');

		if($vm)
		{
			return $vm;
		}
		else
		{
			return array();
		}
	}

	/**
	* Sends a request to VPS.NET to load details about a VM:
	*/
	public function getVM($id)
	{
		$vm = $this->sendApiRequest('virtual_machines/'.$id, 'GET');

		if($vm)
		{
			return $vm['virtual_machine'];
		}
		else
		{
			return null;
		}
	}

	/**
	* Sends a request to VPS.NET to reboot a VM:
	*/
	public function rebootVM($id)
	{
		return $this->sendApiRequest('virtual_machines/'.$id.'/reboot', 'POST');
	}

	/**
	* Sends a request to VPS.NET to boot a VM:
	*/
	public function bootVM($id)
	{
		return $this->sendApiRequest('virtual_machines/'.$id.'/power_on', 'POST');
	}

	/**
	* Send an API request to VPS.NET
	*/
	protected function sendApiRequest($uri, $type = 'GET')
	{
		if(!$this->apiEmail || !$this->apiKey)
		{
			throw new Exception('You must set an API key and email address first.');
		}

		$opts = array(
		  'http'=>array(
		    'method'  => $type,
		    'header'  => 'Accept: application/json' . "\r\n" .
		                 'Content-Type: application/json' . "\r\n" .
						 'Authorization: Basic ' . base64_encode($this->apiEmail.':'.$this->apiKey) . "\r\n",

			'timeout' => 3,
		  )
		);

		$url      = 'https://'.$this->apiUrl.$uri.'.api10json';
		$context  = stream_context_create($opts);
		$response = @file_get_contents($url, false, $context);
		return json_decode($response, true);
	}
}</pre>
</div>
<p> edc17388fb0743a4910e77ba4c1b8171</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP UK Conference 2010</title>
		<link>http://www.dancryer.com/2010/02/php-uk-conference-2010</link>
		<comments>http://www.dancryer.com/2010/02/php-uk-conference-2010#comments</comments>
		<pubDate>Thu, 11 Feb 2010 19:13:44 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=465</guid>
		<description><![CDATA[I&#8217;ve been meaning to post about this for weeks now, but haven&#8217;t got around to it. The PHP UK Conference is coming up on the 26th of February in London and my boss, Remo Biagioni, is one of the speakers. Here&#8217;s some information about Remo and the talk from the official site: Remo&#8217;s Bio: Remo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dancryer.com/wp/wp-content/uploads/2010/02/php-logo.gif"><img class="alignright size-full wp-image-443" title="PHP Logo" src="http://www.dancryer.com/wp/wp-content/uploads/2010/02/php-logo.gif" alt="PHP Logo" width="200" height="160" /></a>I&#8217;ve been meaning to post about this for weeks now, but haven&#8217;t got around to it. The <a rel="nofollow" href="http://www.phpconference.co.uk/">PHP UK Conference</a> is coming up on the 26th of February in London and my boss, Remo Biagioni, is one of the speakers. Here&#8217;s some information about Remo and the talk from the official site:</p>
<p><strong>Remo&#8217;s Bio:</strong></p>
<blockquote><p>Remo is Head of Research &amp; Development at Stickyeyes, a search marketing agency based in Leeds. The R&amp;D team works on a mixture of client site builds, internal reporting tools and Market Defender a search marketing intelligence tool. His team works mainly with PHP, MySQL and Apache. Remo graduated with an MSc in pure mathematics having covered programming in Fortran, Pascal, Lisp &amp; C; he joined BT&#8217;s R&amp;D Labs at Martlesham Heath working on large scale systems (a dozen mainframes, a few hundred Unix servers&#8230;) before getting an MBA and leaving to set up his own web development business. Remo sold the business in 2008 and joined Stickyeyes. Remo is passionate about object-orientated coding and can talk for hours about the Liskov Subsitution Principle, test driven development and solid software engineering.</p></blockquote>
<p><strong>The Talk &#8211; Database Optimisation:</strong></p>
<blockquote><p>A real life example getting more throughput with fewer queries.</p>
<p>Over the last year we&#8217;ve grown a database from a few hundred megabytes to just over one terabyte. The database is reported on and populated by a network of servers using PHP. As the database has grown we&#8217;ve had to look again our initial assumptions and ways of working. One table has over 2billion rows; 2.5 million rows every day are added to another table. This talk will cover how we use explain, foreign keys, normalising data without sacrificing performance, queuing and using memcache. And, how we&#8217;ve made the system run faster now than it did with a much smaller database.</p></blockquote>
<p>Without going into too much detail, the talk basically centres around the work that myself, Wade and the rest of our team have been doing over the course of the last year and a half.</p>
<p>Much of the content will be familiar to those who read my blog. It&#8217;s about scaling MySQL from a couple of hundred megabyte data store in our office, to a two server set up holding over a terabyte of data, fed by tens of servers, all the whileincreasing the speed at which we could store and retrieve data. It&#8217;ll cover how we implemented beanstalkd and memcached to lessen database load, and I&#8217;d imagine it will also touch on our ongoing implementation of HAProxy load balancing.</p>
<p>If you&#8217;re attending the conference and this sounds interesting to you, make sure you get to the talk. Wade and I will be around as well, to answer any questions that might come up throughout the day. As always, you can also ask the questions here, and if the answer is interesting enough, it might make it into the talk (though no promises!)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/02/php-uk-conference-2010/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HipHop for PHP, The PHP Compiler by Facebook</title>
		<link>http://www.dancryer.com/2010/02/hiphop-the-facebook-php-compiler</link>
		<comments>http://www.dancryer.com/2010/02/hiphop-the-facebook-php-compiler#comments</comments>
		<pubDate>Tue, 02 Feb 2010 17:35:18 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[hiphop]]></category>
		<category><![CDATA[hyper php]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=442</guid>
		<description><![CDATA[Facebook have just announced the release of their new PHP compiler, HipHop for PHP. News of the compiler was leaked in an interview on The Rumpus in mid january, and expanded upon by Read Write Web earlier this week. That, combined with members of the PHP core development team being invited to the Facebook headquarters yesterday, this [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dancryer.com/wp/wp-content/uploads/2010/02/php-logo.gif"><img class="alignright size-full wp-image-443" title="PHP Logo" src="http://www.dancryer.com/wp/wp-content/uploads/2010/02/php-logo.gif" alt="PHP Logo" width="200" height="160" /></a>Facebook have just announced the release of their new PHP compiler, <strong>HipHop for PHP</strong>. News of the compiler was leaked in an <a rel="nofollow" href="http://therumpus.net/2010/01/conversations-about-the-internet-5-anonymous-facebook-employee/?full=yes">interview on The Rumpus</a> in mid january, and <a href="http://www.readwriteweb.com/archives/facebook_gets_faster_debuts_homegrown_php_compiler.php">expanded upon by Read Write Web</a> earlier this week. That, combined with members of the PHP core development team being invited to the Facebook headquarters yesterday, this announcement comes as very little surprise.</p>
<p>The announcement states that running HipHop has reduced the CPU footprint of the Facebook code base by 50%, over using the standard PHP runtime. Whilst those improvements may not be reflected by all PHP applications, due to the special nature of the Facebook codebase, it represents an undeniably vast improvement to what was previously an engine known for being somewhat hacked together.</p>
<p>As the improved engine is seemingly so much more efficient, I assume a significant portion of the PHP developer community will now start tinkering with <strong>HipHop for PHP </strong>and the crazier amongst us will start making the switch over on our personal sites and projects. This is going to have a huge impact on the PHP community, web hosting industry and those who work in either. I can only assume that some hosts are already receiving their first &#8220;When will we get <strong>HipHop for PHP</strong>?&#8221; emails.</p>
<p>I&#8217;m going to set it up on a sub-domain of this site when it&#8217;s released this evening, assuming it can run under Apache at the moment, and see how much it affects performance running simple web sites powered by software like WordPress and IP.Board. If it is compatible and makes much of a performance difference, I&#8217;ll switch the whole server over here, and start looking at it more seriously for our systems at work.</p>
<p>For more information, see the <a href="http://developers.facebook.com/news.php?blog=1&amp;story=358" rel="nofollow">official announcement by Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/02/hiphop-the-facebook-php-compiler/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Free VPS.NET Server Setup</title>
		<link>http://www.dancryer.com/2010/01/free-vps-net-server-setup</link>
		<comments>http://www.dancryer.com/2010/01/free-vps-net-server-setup#comments</comments>
		<pubDate>Mon, 18 Jan 2010 17:40:31 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[vps.net]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=372</guid>
		<description><![CDATA[I&#8217;ve been getting a lot of traffic lately from people looking for information about VPS.NET and it&#8217;s cloud platform, and I get the impression that people might think it&#8217;s difficult to get started. It&#8217;s not. As such, I&#8217;ve decided to make an offer to people wanting to use it for their web sites. I&#8217;ll set [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting a lot of traffic lately from people looking for information about VPS.NET and it&#8217;s cloud platform, and I get the impression that people might think it&#8217;s difficult to get started. It&#8217;s not. As such, I&#8217;ve decided to make an offer to people wanting to use it for their web sites.</p>
<p>I&#8217;ll set your web server up for you, for free, after you sign up to VPS.NET. I&#8217;ll get it up and running with Ubuntu Linux, Apache 2.2, PHP 5.2 and MySQL 5.1. I&#8217;ll also set up FTP (if desired) and create up to five user accounts and Apache virtual hosts for domains you already have.</p>
<p>All you have to do to take advantage of this is the following:</p>
<ol>
<li>Sign up to VPS.NET using <a rel="nofollow" href="http://manage.aff.biz/z/155/CD2815/">this link</a> (see note 1) - but don&#8217;t create a VPS</li>
<li>Forward the account details link you get from VPS.NET (including your account username and password) to <a href="mailto:vps@dancryer.com">vps@dancryer.com</a></li>
<li>In the email, include the number of VPS.NET &#8220;nodes&#8221; you want me to allocate to your VPS, a list of up to five domains you would like to be set up, the server name you want to use (if you have a preference), and whether or not you would like to be able to access it via FTP.</li>
</ol>
<p>I&#8217;ll set up the server as soon as I can and email you back with a list of Ubuntu user names and passwords, MySQL usernames and passwords, and various other server details.</p>
<div style="font-size: 0.9em;">
<p><strong>Notes:</strong></p>
<ol>
<li>In order to qualify for the free set up, you must use the link I provided to sign up. VPS.NET offers a generous affiliate program that covers the cost for my time to set up the server, which allows me to offer it to you for no cost.</li>
<li>If demand is high, I cannot guarantee to be able to set your server up for you. I&#8217;ll email you back at the earliest possible time to let you know.</li>
<li>Your account details will be deleted from my email account as soon as the work is completed, you are of course welcome to change all passwords after completion of the work.</li>
<li>I cannot offer ongoing server support for free, such requests will be met with a request for payment.</li>
<li>I will not install any web applications as part of this offer, nor migrate data from existing hosting accounts, simply install the server software itself, further configuration is up to you.</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/free-vps-net-server-setup/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Page Profiler: Update</title>
		<link>http://www.dancryer.com/2009/12/page-profiler-update</link>
		<comments>http://www.dancryer.com/2009/12/page-profiler-update#comments</comments>
		<pubDate>Wed, 09 Dec 2009 23:01:22 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[domains]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Search Engine Optimisation]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=323</guid>
		<description><![CDATA[I&#8217;ve just finished an update to the Site Profiler tool I wrote a couple of months ago. I&#8217;ve made some pretty big changes, and I think it&#8217;s a lot more useful now. I&#8217;m not sure if anyone actually uses it, but here&#8217;s what&#8217;s changed: Renamed to Page Profiler &#8211; makes more sense, as it only [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just finished an update to the <a href="/2009/10/site-profiler-domain-link-information">Site Profiler tool I wrote a couple of months ago</a>. I&#8217;ve made some pretty big changes, and I think it&#8217;s a lot more useful now. I&#8217;m not sure if anyone actually uses it, but here&#8217;s what&#8217;s changed:</p>
<ul>
<li>Renamed to <a href="/page-profiler/">Page Profiler</a> &#8211; makes more sense, as it only checks individual pages</li>
<li>Speed improved, also no longer an AJAX loaded page (result pages can also be linked to)</li>
<li>Presentation improved</li>
<li>Added data size (Plus GZIP compression checking and GZIP data size)</li>
<li>Added HTTP response header</li>
<li>Added title and meta description</li>
<li>Added internal link reporting</li>
<li>Added number of redirects encountered when loading URL</li>
<li>Added request time</li>
<li>Improved whois checking</li>
<li>Added warnings for key <a rel="nofollow" href="http://www.seomoz.org/blog/the-web-developers-seo-cheat-sheet">SEOMoz Web Developer SEO Cheat Sheet Recommendations</a>.</li>
</ul>
<p>The user agent you may see in your access logs for this tool is now:<br />
<code>Mozilla/5.0 (compatible; PageProfiler/2.0; +http://www.dancryer.com/page-profiler)</code></p>
<p>If you&#8217;re using the tool, or have any suggestions for improvements, please let me know in the comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/12/page-profiler-update/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freelance IP.Board (IPB) modification developers</title>
		<link>http://www.dancryer.com/2009/12/freelance-ip-board-ipb-modification-developers</link>
		<comments>http://www.dancryer.com/2009/12/freelance-ip-board-ipb-modification-developers#comments</comments>
		<pubDate>Thu, 03 Dec 2009 22:06:49 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[freelance]]></category>
		<category><![CDATA[ip.board]]></category>
		<category><![CDATA[ipb]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=297</guid>
		<description><![CDATA[I&#8217;m currently looking for one or more IP.Board modification developers, or PHP developers with knowledge of IP.Board, to take on a number of freelance projects for me. These are for client web sites who have asked me for modifications to be built, you&#8217;ll be given the opportunity to price the individual projects yourself. I&#8217;ll deal [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently looking for one or more <a rel="nofollow" href="http://www.invisionpower.com/#a_aid=4b025b1b2f796">IP.Board</a> modification developers, or PHP developers with knowledge of IP.Board, to take on a number of freelance projects for me. These are for client web sites who have asked me for modifications to be built, you&#8217;ll be given the opportunity to price the individual projects yourself. I&#8217;ll deal with the client for you, provide feedback, quality check the work and pay you via PayPal on project completion.</p>
<p>I&#8217;m offering out these projects as I do not have the time to complete them myself at the moment. They are projects of vastly varying types, scale and complexity.</p>
<p>If you are interested in taking on some of this work, please email me at <a href="mailto:dan.cryer@veris.co.uk">dan.cryer@veris.co.uk</a>. If you know anyone else who may be interested, please encourage them to read this post and email me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/12/freelance-ip-board-ipb-modification-developers/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Site Profiler &#8211; Domain and Link Information Tool</title>
		<link>http://www.dancryer.com/2009/10/site-profiler-domain-link-information</link>
		<comments>http://www.dancryer.com/2009/10/site-profiler-domain-link-information#comments</comments>
		<pubDate>Fri, 09 Oct 2009 23:26:51 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[domains]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Search Engine Optimisation]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=221</guid>
		<description><![CDATA[I spent a couple of hours tonight putting together a simple web site profiling tool. It allows you to see some useful information about a page, including it&#8217;s server IP address and location, the domain name contact, and some of the outgoing links from that site. It&#8217;s worth noting that the tool crawls roughly five [...]]]></description>
			<content:encoded><![CDATA[<p>I spent a couple of hours tonight putting together a simple <a href="/site-profiler/">web site profiling tool</a>. It allows you to see some useful information about a page, including it&#8217;s server IP address and location, the domain name contact, and some of the outgoing links from that site. </p>
<p>It&#8217;s worth noting that the tool crawls roughly five pages on the target site each time it is run, so you may notice the following user agent in server logs:</p>
<p><code>Mozilla/5.0 (compatible; SiteProfiler/1.0; +http://www.dancryer.com/site-profiler)</code></p>
<p>I thought I&#8217;d make it available on this site, so others can use it. If you like it, or you&#8217;ve got any feedback, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/10/site-profiler-domain-link-information/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHPNW09 Conference</title>
		<link>http://www.dancryer.com/2009/10/php-north-west-2009-conference</link>
		<comments>http://www.dancryer.com/2009/10/php-north-west-2009-conference#comments</comments>
		<pubDate>Fri, 09 Oct 2009 18:22:36 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[leeds]]></category>
		<category><![CDATA[manchester]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpnw09]]></category>
		<category><![CDATA[wade]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=214</guid>
		<description><![CDATA[Just wanted to post a quick note to say that Wade, Asim and I are going to be at the PHP North West conference in Manchester tomorrow. If anyone reading this is coming, drop me a note and we&#8217;ll look out for you at the conference, especially if you&#8217;re currently looking for a developer job [...]]]></description>
			<content:encoded><![CDATA[<p>Just wanted to post a quick note to say that <a href="http://www.xcitestudios.com/blog/" rel="nofollow">Wade</a>, Asim and I are going to be at the <a href="http://conference.phpnw.org.uk/phpnw09/" rel="nofollow">PHP North West conference</a> in Manchester tomorrow. </p>
<p>If anyone reading this is coming, drop me a note and we&#8217;ll look out for you at the conference, especially if you&#8217;re currently looking for a developer job in Leeds! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/10/php-north-west-2009-conference/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking forward: Crawler version 2.0 and 3.0</title>
		<link>http://www.dancryer.com/2009/09/looking-forward-crawler-2-and-3</link>
		<comments>http://www.dancryer.com/2009/09/looking-forward-crawler-2-and-3#comments</comments>
		<pubDate>Thu, 17 Sep 2009 17:30:09 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[beanstalkd]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[hbase]]></category>
		<category><![CDATA[hdfs]]></category>
		<category><![CDATA[mapreduce]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=178</guid>
		<description><![CDATA[Alongside my work on our current crawler, Wade has been rewriting the system to make better use of what we&#8217;ve learned so far, and make a number of changes: The current codebase is a mess, many cron jobs running terribly written classes, across two separate crawler systems. The new system is neatly organised with models [...]]]></description>
			<content:encoded><![CDATA[<p>Alongside my work on our current crawler, <a rel="nofollow" href="http://www.xcitestudios.com/blog/">Wade</a> has been rewriting the system to make better use of what we&#8217;ve learned so far, and make a number of changes:</p>
<ul>
<li>The current codebase is a mess, many cron jobs running terribly written classes, across two separate crawler systems. The new system is neatly organised with models and controllers, and all run through one central job manager.</li>
<li>Our MySQL-based job queueing system is being replaced with <a rel="nofollow" href="http://xph.us/software/beanstalkd/">beanstalkd</a>.</li>
<li>We&#8217;re dropping all auto_increment primary keys in the database, replacing them with pre-calculated binary hashes, a BINARY(16) column with the UNHEX() value of an MD5.</li>
<li>Doing the above allows us to drop most of the SELECT queries we do, as we don&#8217;t need to know if we&#8217;ve already got a reference to that page/url/backlink, we can INSERT IGNORE new ones, and it&#8217;ll simply skip over it on those we already have. All references to that data will also use the binary hash.</li>
<li>Our crawler will make all requests under the user agent MarketDefenderBot/2.0 (some of our requests currently use MarketDefenderBot/1.0, but not all), and will respect robots.txt properly.</li>
<li>We&#8217;re putting indexes on what we need and use, and dropping ones we don&#8217;t&#8230; Crazy, I know.</li>
</ul>
<p>However, due to the rate at which we&#8217;re growing, I&#8217;m already beginning to investigate where we can go next. We&#8217;re beginning to push some of MySQL&#8217;s limits, and we don&#8217;t want to simply migrate wholesale to another RDBMS. We&#8217;ve got a few options, obviously, including moving specific problems out of MySQL and into other solutions, as we&#8217;ve done with beanstalkd for queueing&#8230; but my preference is headed rapidly towards migrating to a <a rel="nofollow" href="http://hadoop.apache.org/">Hadoop</a> cluster, along with <a rel="nofollow" href="http://hadoop.apache.org/hdfs/">HDFS</a>, <a rel="nofollow" href="http://hadoop.apache.org/mapreduce/">MapReduce</a> and <a rel="nofollow" href="http://hadoop.apache.org/hbase/">HBase</a>.</p>
<p>I know it may seem like simply jumping on the <a rel="nofollow" href="http://en.wikipedia.org/wiki/Nosql">NoSQL</a> bandwagon, but actually, I think that for something of the type and scale we&#8217;re working towards, it&#8217;s the only option. I realise that there are organisations with much larger datasets running on relational databases, but a consideration a lot of people miss when they make these comparisons, is the use cases.  We&#8217;re constantly querying across our entire dataset in a variety of different ways, many of which can&#8217;t be optimised with simple indexes.</p>
<p>I&#8217;ve also just discovered that Hadoop&#8217;s MapReduce can run any application for both the Map and Reduce tasks, meaning we can continue to use PHP until we absolutely have to switch to another language for performance, at which point, we can do it on a task by task basis.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/09/looking-forward-crawler-2-and-3/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP/MySQL Scaling Followup</title>
		<link>http://www.dancryer.com/2009/09/php-mysql-scaling-followup</link>
		<comments>http://www.dancryer.com/2009/09/php-mysql-scaling-followup#comments</comments>
		<pubDate>Mon, 14 Sep 2009 20:16:48 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Other Things]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=141</guid>
		<description><![CDATA[I posted last week about our work on scaling our crawler application and it&#8217;s corresponding MySQL database, but left it with very little conclusion, apart from that Memcached is good. I wanted to follow up with some of the changes we made on Thursday and Friday. Having run the code with the changes we made [...]]]></description>
			<content:encoded><![CDATA[<p>I posted last week about our work on <a href="http://www.dancryer.com/2009/09/when-scaling-for-speed-slows-you-down">scaling our crawler application</a> and it&#8217;s corresponding MySQL database, but left it with very little conclusion, apart from that <a href="http://www.dancryer.com/2009/09/memcached">Memcached is good</a>. I wanted to follow up with some of the changes we made on Thursday and Friday.</p>
<p>Having run the code with the changes we made previously for a day or so, in order to give it a fair trial, it was obvious it wasn&#8217;t going to work. We were still doing an average of 5,000 pages an hour, way below the original code and even further below the targets we&#8217;d set ourselves.</p>
<p>The first change we made was to move the queue table back to InnoDB from MEMORY. The memory engine wasn&#8217;t providing the benefits we&#8217;d hoped, and it was using far more RAM than it was worth. It was also locking, a lot. I have to admit, it was probably unwise to assume that we could expect memory tables to perform any better, when working with over a gigabyte of data. Next, we turned our attention to what had become an obvious bottleneck: statement based binary logging. We&#8217;d made this choice early on, based on reasons unbeknownst to me. After much research and a little panic, we flipped the switch and turned our crawlers back on, seeing an immediate and significant performance improvement.</p>
<p>We&#8217;d finally done it, we were now running an average of 25,000 pages an hour, peaking at 45,000. We&#8217;re still working on it, of course, as we&#8217;d like to hit 100,000 pages an hour, but we&#8217;re very happy to have finally gotten past the bottlenecks.</p>
<p>As an additional interesting tidbit, I re-ran the graphs for our Memcache utilisation. This time over the period 12:00pm Thursday to 12:00pm Monday. As you can see, the hits to misses ratio is starting to level out over time, averaging around 70% hits, 30% misses. Here&#8217;s the charts:</p>
<p><img class="alignnone size-full wp-image-146" title="Memcache usage in real numbers under load" src="http://www.dancryer.com/wp/wp-content/uploads/2009/09/memcacheusagereal.png" alt="Memcache usage in real numbers under load" width="386" height="233" /></p>
<p><img class="alignnone size-full wp-image-144" title="Memcached usage under load" src="http://www.dancryer.com/wp/wp-content/uploads/2009/09/memcachedusage.png" alt="Memcached usage under load" width="386" height="233" /></p>
<p>As usual, please let me know if you&#8217;ve got any questions or comments, I (and I&#8217;m sure the others on my team) would be happy to help if I can.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/09/php-mysql-scaling-followup/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mmm Memcached</title>
		<link>http://www.dancryer.com/2009/09/memcached</link>
		<comments>http://www.dancryer.com/2009/09/memcached#comments</comments>
		<pubDate>Thu, 10 Sep 2009 14:36:53 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=125</guid>
		<description><![CDATA[If you read my previous post about our scaling issues, you&#8217;ll know that I was planning on trying out a number of other ideas to see if we could improve the performance of our system. Well, one of the things I tried was to test out Memcached. I set up a six node VPS (2.4 [...]]]></description>
			<content:encoded><![CDATA[<p>If you read my previous post about our <a href="http://www.dancryer.com/2009/09/when-scaling-for-speed-slows-you-down">scaling issues</a>, you&#8217;ll know that I was planning on trying out a number of other ideas to see if we could improve the performance of our system. Well, one of the things I tried was to test out <a rel="nofollow" href="http://www.danga.com/memcached/">Memcached</a>. I set up a <a rel="nofollow" href="http://manage.aff.biz/z/146/CD2815/">six node VPS</a> (2.4 ghz, 1.5gb ram, 1500gb bandwidth) and installed Memcached on it. Setting it up was pretty spectacularly simple, &#8220;apt-get install memcached&#8221;, followed by changing two variables in its config file.</p>
<p>I modified our applications to start checking Memcached first, using the PECL &#8216;Memcache&#8217; extension, and if no results were found, access the database, get the data and put it into Memcached. Below are a couple of graphs of the first hour of our rollout:</p>
<p><img class="alignnone size-full wp-image-128" title="Actual numbers of get requests, hits and misses over the hour." src="http://www.dancryer.com/wp/wp-content/uploads/2009/09/getshitsmisses.png" alt="Actual numbers of get requests, hits and misses over the hour." width="386" height="233" /></p>
<p><img class="alignnone size-full wp-image-129" title="Percentage of cache hits vs. misses over the hour." src="http://www.dancryer.com/wp/wp-content/uploads/2009/09/hitsvsmisses.png" alt="Percentage of cache hits vs. misses over the hour." width="386" height="233" /></p>
<p>As you can see, the number of requests started out pretty low, as the number of application instances ramped up&#8230; This caused a massive spike in misses whilst the cache warmed up. However, as soon as the number of requests started to rise, the balance shifted, and since the rollout, the ratio has remained a fairly stable 60/40 split in favour of hits.</p>
<p>As you may also be able to tell from the graphs, this means that of the 2.5 million hits an hour, we&#8217;re managing to catch 1.5 million before they ever make it to the database. This is a huge saving for us, and we&#8217;re now looking at where else we can roll this out with similar effect.</p>
<p>On the note of our scaling issues, I&#8217;ll be writing up some more of what we&#8217;ve done with the databases later. We&#8217;re at a point now where the improvements are actually starting to make a difference!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/09/memcached/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP5 Database Model Generator</title>
		<link>http://www.dancryer.com/2009/09/php5-database-model-generator</link>
		<comments>http://www.dancryer.com/2009/09/php5-database-model-generator#comments</comments>
		<pubDate>Wed, 09 Sep 2009 18:22:19 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[model generator]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=119</guid>
		<description><![CDATA[Over the past few days, I&#8217;ve been working on a little experiment, and now that it actually does something, I think it&#8217;s about time I got some feedback. It&#8217;s a PHP database model generator, it connects to a given MySQL database, and generates a two model files for each table in it. The first file [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few days, I&#8217;ve been working on a little experiment, and now that it actually does something, I think it&#8217;s about time I got some feedback. It&#8217;s a PHP database model generator, it connects to a given MySQL database, and generates a two model files for each table in it.</p>
<p>The first file it generates is a very simple, empty, model class in ./app/model/. This is where you&#8217;d put your custom methods, such as hashing for passwords, etc. By default, this file will only be generated the first time you run generate models script.</p>
<p>The second file it generates is the database model itself. This will contain, as properties, all of the columns in your database table. For each of those properties, you&#8217;ll also get a nicely formatted getter and setter method. Optionally, the generator will also write you some code to validate input in the setters by their null/not null status, column type and length.</p>
<p>Finally, for now, the generator will optionally generate you a static getter (with SQL) for your primary key, allowing you to do, for example: Model_Whatever::getByID(234);</p>
<p>Usage for the script is as follows:</p>
<blockquote><p><strong> ./generate-models -s=myhost.com [-u=user] [-p=password] -d=database</strong></p>
<p>ADDITIONAL PARAMETERS:<br />
-<strong>p</strong> MySQL Port. Default: 3306<br />
-<strong>sockets</strong> Use MySQL Sockets? Default: off, values: on | off<br />
-<strong>validation</strong> Generate validation code for basic SQL types. Default: on, values: on | off<br />
-<strong>exceptions</strong> Generate exceptions in validation code. Default: on, values: on | off<br />
-<strong>sql</strong> Generate basic SQL in database models. Default: on, values: on | off<br />
-<strong>prefix</strong> Prefix models with Model_. Default: on, values: on | off<br />
-<strong>idcase</strong> getId() becomes getID(). Default: on, values: on | off<br />
-<strong>tables</strong> Tables are a multiple of their columns, e.g. reviews.review_id. Default: on, values: on | off<br />
-<strong>overwrite</strong> Overwrite existing model files (database model files are automatically overwritten). Default: off, values: on | off</p>
<p>EXPERIMENTAL FEATURES:<br />
-<strong>php53</strong> Generate PHP 5.3 code (use namespaces). Default: off, values: on | off</p></blockquote>
<p>It&#8217;s worth noting that this does come with some caveats:</p>
<ul>
<li>Assumes that table names are in either format: user or users (will make Model_User, Model_Users, respectively)</li>
<li>Assumes that column names are in the format: user_id  (will make getID() in the User[s] model)</li>
<li>If you use -sql, assumes you have a class named Database that gives back instances of PDO. An example class is bundled.</li>
</ul>
<p>Over time, I plan to add much more to this. Next on the list are a static create() method, and a save() method on instances, when running with the -sql parameter on.</p>
<p>One last note: At present, this code is not open source, nor public domain. You&#8217;re free to use it however you wish, but please don&#8217;t redistribute. I do plan to open source this when I&#8217;m happy with it, but it&#8217;s just not quite ready for that yet.</p>
<p>And finally, here&#8217;s the code: <a href="/files/generate-models.zip">Download</a>. Please let me know what you think, if you&#8217;re using it, if you think it&#8217;s useful, or even if you think it&#8217;s rubbish.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/09/php5-database-model-generator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When scaling for speed slows you down&#8230;</title>
		<link>http://www.dancryer.com/2009/09/when-scaling-for-speed-slows-you-down</link>
		<comments>http://www.dancryer.com/2009/09/when-scaling-for-speed-slows-you-down#comments</comments>
		<pubDate>Fri, 04 Sep 2009 20:05:24 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Search Engine Optimisation]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=113</guid>
		<description><![CDATA[At work, the past few days, I&#8217;ve been working on the scalability of one of our systems and, hopefully, we&#8217;re almost closing on the finishing line. For some context, the system I&#8217;m talking about is effectively a web crawler. It (all too slowly) works through a queue of URLs, downloading the pages and parsing them [...]]]></description>
			<content:encoded><![CDATA[<p>At work, the past few days, I&#8217;ve been working on the scalability of one of our systems and, hopefully, we&#8217;re almost closing on the finishing line. For some context, the system I&#8217;m talking about is effectively a web crawler. It (all too slowly) works through a queue of URLs, downloading the pages and parsing them for various information, including backlinks. As it inserts data into a MySQL database, primarily made up of innodb tables. </p>
<p>This all started on Wednesday, we&#8217;d been looking at the queue and decided that it was far too large. We&#8217;d hit 12.5M pages waiting to be checked, and were processing about 200,000 a day, tops. The initial reaction, as this is a distributed system, was to scale it horizontally. We rented six more <a href="http://manage.aff.biz/z/146/CD2815/" rel="nofollow">VPSs</a> (to add to the existing 5) and planned to run them at capacity until the queue was empty. After setting all the boxes up, we left them over night, in hope of completing 750,000 or more pages. Boy, were we wrong. On Thursday morning, we came in to discover it was running at a peak of 5,000 pages an hour (144,000 a day). We&#8217;d slowed it down, and not only that, we&#8217;d slowed everything else down too.</p>
<p>This is when the optimisation work started. We looked at the queries we were running, and noticed that an obvious bottleneck appeared to be the queue itself. Each VPS ran 15 instances of our application at any given time, and each one did a query for 250 pages to check when it was starting up, updated them as in progress, and deleting each from the queue on completion. The first change we made was to change the indexing on the table, which merely served to slow us down further. The second, more interesting change, was to change the entire table from innodb to the memory/heap table engine. This meant changing both max_heap_table_size and tmp_table_size to over 2.5GB to accomodate the 1GB table at the same time as allowing temporary tables to be created. Getting this change replicated onto our two slaves was a delight. </p>
<p>The memory table &#8220;solution&#8221; worked well after turning all of our VPSs back on, for about 10 minutes. At which point, they were up to capacity and the queue table started locking, a lot. As did all of the other tables, inexplicably. In addition to inducing panic, this highlighted to us that another table was starting to cause problems, our anchor text table. This is responsible for storing only the words that are used to link from one site to another. This table was seeing anything up to 2 million inserts an hour, and the same number of selects. After several failed attempts to remedy this, we finally settled on selecting all of the anchor texts we&#8217;d just collected, any that came back from the database were then dropped from our insert, thus only inserting those that were not present. Those inserts were done with batches of 10 per query. This cut the number of queries down significantly. Whilst this has improved the locking situation, it has, unfortunately, led to hanging selects. These selects are using potentially gigantic &#8216;IN(one, two, three)&#8217; conditions, and are taking anything from 0.01 to 120 seconds to complete.  Completely unpredictably.</p>
<p>Next priority was fixing the table locking on our queue. We&#8217;ve done this by marking all deletes from the queue as LOW_PRIORITY. In doing that, we&#8217;re allowing MySQL to queue those deletes for when no other clients are accessing the table, preventing unnecessary locking. </p>
<p>At the time of this writing, 113 instances of our application are running without significant conflicts on either of the tables we&#8217;ve optimised. However, we&#8217;re still processing just 5,000 pages an hour. I&#8217;m sure I&#8217;ll be working on this problem again on Monday, and will update here with anything we do discover. </p>
<p>So to summarise this somewhat rambley and unhelpful post a little, don&#8217;t assume that because you&#8217;ve built your system to run across multiple servers, that it can infact run across multiple servers. Ours scaled up to 4, and then the scaling started working against us. If you found it interesting, have any MySQL questions, want to offer advice, or are doing similar work yourself&#8230; drop me a comment below. I&#8217;d love to know that people are reading this!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2009/09/when-scaling-for-speed-slows-you-down/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ineo &#8211; Interface Changes</title>
		<link>http://www.dancryer.com/2006/09/ineo-interface-changes</link>
		<comments>http://www.dancryer.com/2006/09/ineo-interface-changes#comments</comments>
		<pubDate>Tue, 19 Sep 2006 16:00:32 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Other Things]]></category>
		<category><![CDATA[dancryer.net]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[ineo]]></category>
		<category><![CDATA[ipb]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[veriea]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=52</guid>
		<description><![CDATA[This is the first of a few blog posts I want to make about the upcoming &#8220;Ineo 1.1&#8243; release. We&#8217;re hoping that version 1.1 will really bring the product into its own and really make it a much more solid and flexible system. I&#8217;ve been wanting to change the Ineo interface, to generally improve and [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first of a few blog posts I want to make about the upcoming &#8220;Ineo 1.1&#8243; release. We&#8217;re hoping that version 1.1 will really bring the product into its own and really make it a much more solid and flexible system.</p>
<p>I&#8217;ve been wanting to change the Ineo interface, to generally improve and streamline what we&#8217;ve got. IPB 2.2 gave me a perfect excuse to do so.</p>
<p>The first target was the &#8216;overview&#8217; page. This has been totally revamped and is now powered entirely by plugins, which can be displayed alone, or as tabs at the top of the page. The tabs take on styles used in areas of IPB 2.2.</p>
<p>The second target was the sidebar. Previously, this used three separate template bits, one for the menu, one for &#8216;blocks&#8217; and one for &#8216;items&#8217;. The majority of the menu-building was done in code, which, as I found out when trying to skin it, is not good. This has been reworked to use one template bit, and the entire menu is generated in-templates. The menu has also been redesigned to use new IPB styles and also to integrate the quick-search results area.</p>
<p>Finally, quite possibly the most unpopular part of the whole Ineo interface, <span style="font-weight: bold">ratings!</span> They&#8217;ve been completely redone. No more numbers, no more &#8220;x ( x total votes )&#8221;. I think you&#8217;ll be pleasantly surprised.</p>
<p>This wouldn&#8217;t be an interface entry without an accompanying set of screenshots, or a video. So here you are:</p>
<p><em>Video used to be linked here.</em></p>
<p>Any feedback you have would be greatly appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2006/09/ineo-interface-changes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back from the&#8230; not&#8230; dead.</title>
		<link>http://www.dancryer.com/2006/07/back-from-the-not-dead</link>
		<comments>http://www.dancryer.com/2006/07/back-from-the-not-dead#comments</comments>
		<pubDate>Sat, 22 Jul 2006 16:00:39 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Other Things]]></category>
		<category><![CDATA[dancryer.net]]></category>
		<category><![CDATA[e29]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=49</guid>
		<description><![CDATA[Well, after an extended absence, I decided it was high time for an update. I&#8217;ve yet to think of anything interesting for the update to cover, however. The biggest change I&#8217;ve made recently is that I have stopped doing temporary work for Adecco, at least for now. I&#8217;m going to try and make a go [...]]]></description>
			<content:encoded><![CDATA[<p>Well, after an extended absence, I decided it was high time for an update. I&#8217;ve yet to think of anything interesting for the update to cover, however.</p>
<p>The biggest change I&#8217;ve made recently is that I have stopped doing temporary work for Adecco, at least for now. I&#8217;m going to try and make a go of the freelance design and development thing. On that note, I recently finished my latest project, which I am pretty proud of. The site is <a rel="nofollow" href='http://www.e29inc.com/'>E29 Incorporated</a>, which is <a href='http://www.kinderism.net' rel='nofollow'>Adam Kinder&#8217;s</a> new venture. Between us, we&#8217;ve got some pretty exciting things going on, but I have to keep those quiet for now. </p>
<p>I&#8217;ve also been loving the heat these past couple of weeks. Spending a lot of time away from the computer,  in my garden and in the pool has been great, it&#8217;s one of the many reasons I love working for myself. Hopefully some day, it&#8217;ll be one of the many reasons other people love working for me, too.</p>
<p>That&#8217;s about all i&#8217;ve got, sorry. I guess I need to think of something new to cover on this site. In the meantime, if any of you want any custom work doing&#8230; Drop me a line.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2006/07/back-from-the-not-dead/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
