<?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>Michael Hradek.com</title>
	<atom:link href="http://michaelhradek.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://michaelhradek.com/blog</link>
	<description>Michael Hradek is a senior web and mobile developer who lives in the Seattle area.</description>
	<lastBuildDate>Thu, 14 Jul 2011 23:15:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Technical in Nature</title>
		<link>http://michaelhradek.com/blog/2011/07/14/technical-in-nature/</link>
		<comments>http://michaelhradek.com/blog/2011/07/14/technical-in-nature/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 20:31:50 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[announcement]]></category>

		<guid isPermaLink="false">http://michaelhradek.com/blog/?p=6</guid>
		<description><![CDATA[It has been a challenge to keep my personal blog from becoming inundated with the rants and ravings of my technical and professional experiences so I have therefor decided to start a blog on my resume site. I have imported &#8230; <a href="http://michaelhradek.com/blog/2011/07/14/technical-in-nature/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It has been a challenge to keep my personal blog from becoming inundated with the rants and ravings of my technical and professional experiences so I have therefor decided to start a blog on my resume site. I have imported a few posts via the <em>Programming</em> category to put some content here so please pardon the duplication.</p>
<p>This last week I was promoted to Client Software Development Lead. I am excited to take on the role and cannot wait to see what I can accomplish. It seems, for now, that my goals are fairly cursory for a lead position:</p>
<ol>
<li>Establish a general culture of documentation. Whether it be a change list for certain libraries, classes, JavaDoc, or APIs us developers tend to have a hard time keeping track of the things we write and then keeping those things up to date as things change.</li>
<li>Unit testing. At least for things in our libraries. Understandably, mobile software tends to have more user interaction code where this is not unit testable. However, there are several key library packages that handle data, network, databases, and other things which can be unit tested.</li>
<li>Get the team communication flowing. This involves communication both internally and externally. Each team member can potentially disappear in a cave and then we may be unaware of what that member has been up to and conversely, that member may have no idea where things are headed. I think regularly discussing and sharing the trials and triumphs of the week encourages team cohesion although if you add donuts to the equation the effects are much more effective. <img src='http://michaelhradek.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ol>
<p>These are just some rough outlines of what I&#8217;d like to do. Obviously, I still have my work as a developer. There are quite a few other things to do and watch. Overall, I think things I listed here, again, are pretty normal to hear from things that teams can be doing better.</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2011/07/14/technical-in-nature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strange Shared Preferences Loss</title>
		<link>http://michaelhradek.com/blog/2011/02/28/strange-shared-preferences-loss/</link>
		<comments>http://michaelhradek.com/blog/2011/02/28/strange-shared-preferences-loss/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 23:15:45 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://fieldmarshallhradek.com/?p=1138</guid>
		<description><![CDATA[Since recently deciding to try and avoid developing on the emulator I&#8217;ve come across a super annoying bug within Android which would basically lock you from being able to write to the shared preferences of your app. Examples are abound &#8230; <a href="http://michaelhradek.com/blog/2011/02/28/strange-shared-preferences-loss/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Since recently deciding to try and avoid developing on the emulator I&#8217;ve come across a super annoying bug within Android which would basically lock you from being able to write to the shared preferences of your app. <a href="http://groups.google.com/group/android-developers/browse_thread/thread/568884aa0b8bbe94">Examples</a> are <a href="http://code.google.com/p/android/issues/detail?id=2047">abound</a> but basically installing your app over an existing version of the app on your device will potentially muck with the permissions in the shared preferences space. This may not always be a problem except if you read/write from that space. The reason it has suddenly become noticed since trying to avoid developing on the emulator is that I use the &#8220;Run&#8221; button as I did with the emulator and I believe that using this way of overwriting the existing version eventually causes this issue.</p>
<p>However, according to some of the posts with similar symptoms, end users were experiencing the issue on app upgrade!</p>
<p>While developing recently I ran into this problem and it drove me crazy. I had spent some time trying to trouble shoot restarting the device, my dev machine, Eclipse, the ADB; all to no avail. Uninstalling the app didn&#8217;t work either. </p>
<p>I eventually got a work around where I was able to delete the shared preferences directory and its contents which then reinstalling the app allowed it to function correctly. After this point I am trying to uninstall the app and then install it &mdash; via command line script.</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2011/02/28/strange-shared-preferences-loss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working on Things</title>
		<link>http://michaelhradek.com/blog/2010/10/19/working-on-things/</link>
		<comments>http://michaelhradek.com/blog/2010/10/19/working-on-things/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 02:56:36 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://fieldmarshallhradek.com/?p=1020</guid>
		<description><![CDATA[First a quick lesson in Java (for myself). This was a half day lesson that I feel sheepish to admit but I figure hey, let me share! Below I will create an ArrayList which will contain a bunch of like &#8230; <a href="http://michaelhradek.com/blog/2010/10/19/working-on-things/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>First a quick lesson in Java (for myself). This was a half day lesson that I feel sheepish to admit but I figure hey, let me share! Below I will create an ArrayList which will contain a bunch of like objects. They could be strings &ndash; it doesn&#8217;t matter. Then we will add those lists to some other objects or consume them in some fashion.</p>
<pre class="brush:java">
public void mySuperExample() {
    // A generic list
    ArrayList&lt;SomeObj> someObjList = new ArrayList&lt;SomeObj>();

    // Start off by creating or using generic objs
    SomeObj obj1 = SomeObj.createMe();
    obj1.setSomeAttribute("My super object");
    obj1.setAnotherAttribute(3);

    SomeObj obj2 = SomeObj.createMe();
    obj2.setSomeAttribute("My other super object");
    obj2.setAnotherAttribute(2);

    // Add the objects to the list
    someObjList.add(obj1);
    someObjList.add(obj2);

    // A couple different objects use a copy of the list
    ConsumingObj.useMe(someObjList);
    AnotherConsumer.useMe(someObjList);
}
</pre>
<p>Now, this looks perfectly fine for <code>ConsumingObj</code> and <code>AnotherConsumer</code> are both unique as are both instances on <code>someObjList</code>. Oh, here is where it gets good. The members of each of the instances of <code>someObjList</code> are identical! The <code>toString()</code> methods have been wonderful to figure this out but basically each of these items were referenced by the parents which ultimately meant that when I thought I had different sets of identical items I had different sets referencing the same items. Anyway, now that that&#8217;s over I can move on. It was interesting. This and recently having learned about creating <a href="http://www.javaworld.com/javaworld/javatips/jw-javatip10.html">callbacks/event handlers</a>. I love programming and learning!</p>
<p>Moving on, we are pretty much settled at our new house. I road the <a href="http://portofkingston.org/passenger-ferry/soundrunner.html">SoundRunner</a> on Monday which was free (for the inaugural day) and it was quite convenient. My commute wasn&#8217;t much shorter than it was in Fife and I think it costs about the same maybe a dollar or two more. But the important part was that there exists a passenger boat straight to Kingston. There is also the Bainbridge Island and Kingston regular ferries so there are like 3 different ways to get to Seattle and back using public transportation. </p>
<p>Although I love the house and location I do lament a little the fact that it is much harder to do some of the shopping I like to do. There is no Nordstrom (or Rack), European butchers, and general conveniences of having everything close by. It&#8217;s okay because we never went to those places on a daily basis and they are accessible if I want to go to Seattle. I will take this over urban living any day. The main detractor is being away from my mom and dad and other folks that would visit more frequently. Out here, apart from Crystal&#8217;s mom who lives close by, no one has come out to see us. I suspect it will stay that way.</p>
<p>I&#8217;ve had enjoyment out of getting acquainted with living in more space and having to do things like monitor gas usage, yard work (what little there is), cooking on gas, playing music loud, and sleeping in complete silence. Today a heavy fog filled the Sound around our area and I heard the rhythmic announcement from the fog horn. Sound of music compared to what we heard in Fife. </p>
<p>I am currently trying to acquire something to reduce the heat on gas stoves. There are these iron plates you can find about eight inches in diameter. With such a huge kitchen the desire to cook is stronger then ever before. I am checking into making cheese and smoking some meats. Soon enough! I got a shelf for the garage to help stow some extra supplies and foods. We&#8217;re hoping that when a need arises we&#8217;re never caught without a way to take care of ourselves. </p>
<p>Our business is coming along nicely in that we&#8217;re generating some income but more importantly we&#8217;re solid at work. I am working from home most of the week and my partner John is also doing huge work. We&#8217;re trying to make steady improvements to released software and create new stuff. I am working on a game right now. John&#8217;s working on an aggregation software. We also did some work to shore up our <a href="http://www.mokasocial.com/">website</a> and the <a href="http://www.linkedin.com/companies/mokasocial">various</a> <a href="http://maps.google.com/maps/place?cid=9770134434258917042&#038;q=mokasocial+seattle&#038;hl=en&#038;gl=us">places</a> <a href="http://steamcommunity.com/groups/mokasocial">we</a> <a href="http://www.flickr.com/photos/46270824@N06/">get</a> <a href="http://startpad.org/companies/mokasocial">found</a> <a href="http://www.iheartcelebs.mobi/">on</a> <a href="http://www.flicka.mobi/">the</a> Internet. </p>
<p>I&#8217;ve been playing World of Tanks here and there. I finally earned enough points to purchase a Panther tank so it&#8217;s been super exciting to play that. I really enjoy the aspect to playing history. I think the game is pretty shallow and although the developers say they will be adding more stuff I am going to wait and see. Interestingly a lot of MMORPGs have been going free. After Final Fantasy XIV bombed (they got a 4 out of 10 rating on some sites) I gave up on the MMO scene. Everquest II and Lord of the Rings Online are now free to play minus a few features. Amazing actually. &#8220;Freemium&#8221; seems to be the next direction MMOs are taking. I think I remember someone at ArenaNet saying that the money earned seems to be about the same as paid subscription. We&#8217;ll see. Speaking of ArenaNet, the media blitz in anticipation of Guild Wars 2 is growing but I admit I am still tired of the graphics and play style the studio puts out. Whether I worked for them or not, I always felt that something was off playing the games they made. </p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2010/10/19/working-on-things/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP, AJAX, and Race Conditions</title>
		<link>http://michaelhradek.com/blog/2010/04/10/php-ajax-race-conditions/</link>
		<comments>http://michaelhradek.com/blog/2010/04/10/php-ajax-race-conditions/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 06:43:51 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://fieldmarshallhradek.com/?p=762</guid>
		<description><![CDATA[We came across a pretty interesting race condition regarding AJAX requests and our PHP back end. A quick search will find a few articles about the problem; this one I think sums it up best. There are some comments there &#8230; <a href="http://michaelhradek.com/blog/2010/04/10/php-ajax-race-conditions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We came across a pretty interesting <a href="http://en.wikipedia.org/wiki/Race_condition#Computing">race condition</a> regarding AJAX requests and our PHP back end. A quick search will find a few articles about the problem; this <a href="http://www.chipmunkninja.com/Troubles-with-Asynchronous-Ajax-Requests-g@">one</a> I think sums it up best. There are some comments there that are worth skimming over if you want more ideas. Unfortunately, nothing in there about a definitive solution.</p>
<p>To summarize briefly, asynchronous calls are made from the client web browser which are then processed by the server without making sure previous requests are completed. A lot of solutions seem to focus on the front end using Javascript to prevent this. Although it is a good practice to avoid making rapid requests of your server from the client, you will still need to address this issue on the back end. I am sure we can come up with ways to help mitigate this issue but eventually the back end must always be the final say in serving requests relying on <em>nothing</em> from the client.</p>
<pre class="brush:php">/**
 * Create and release database locks to prevent concurrency issues. This is a rough
 * solution and you may want to look at try-catch, closing db connections, throwing
 * exceptions, etc.
 *
 * Also, keep in mind that using persistent connections isn't ideal and neither is
 * sleep. This isn't an ideal solution, IMHO.
 *
 * @author Michael Hradek
 */
final class DatabaseLock
{
    /**
	 * @var int Seconds before lock times out.
	 */
    const LOCK_TIMEOUT = 10;

    /**
     * @var int Retry limit count.
     */
    const LOCK_RETRY_LIMIT = 5;

    /**
 	 * Create a lock using MySQL. This is a wrapper for that functionality.
	 *
 	 * @param String
	 */
    public static function lock($lock_name)
    {
        $i = 0;
        do
        {
            if(self::isLockUsed($lock_name) === false)
            {
                $dbObj = /** Your DB obj instantiation. Persistant connection. */
                $sql = "SELECT GET_LOCK(?, ?)";
                $result = $dbObj->query($sql, $lock_name, self::LOCK_TIMEOUT);
                if($result &#038;&#038; $result->getColumn(0) === 1) {
                    return true;
                }
            }
            usleep(1000); $i++;
        } while ($i < self::LOCK_RETRY_LIMIT);

        return false;
    }

    /**
 	 * Release an existing lock.
	 *
 	 * @param String
	 */
    public static function release($lock_name)
    {
        $dbObj = /** Your DB obj instantiation. */
        $sql = "SELECT RELEASE_LOCK(?)";
        $result = $dbObj->query($sql, $lock_name);

        if($result &#038;&#038; $result->getColumn(0) === 1) {
            return true;
        }

        return false;
    }

	/**
	 * Checks to see if a lockname is in use. Calling GET_LOCK release previous
	 * lock if the lock name is identical.
	 *
	 * @param String
	 * @return bool
	 */
	private static function isLockUsed($lock_name)
	{
        $dbObj = /** Your DB obj instantiation. */
		$sql = "SELECT IS_USED_LOCK(?)";
		$result = $dbObj->query($sql, $lock_name);

		return ($result === false);
	}
}</pre>
<p>The solution my colleagues and I came up with above requires use of MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock"><code>get_lock</code></a> and<code> <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock">release_lock</a></code> functionality. We spent some time thinking about Session flags/semaphores, horribly un-scalable sleeping, and <a href="http://php.net/manual/en/book.sem.php">semaphores</a> via PHP itself. In the case of session flags we found that session was too slow to keep up with multiple incoming requests. We had between four to six to <em>n</em> requests come through and announce that they are starting the session lock. Wha?!</p>
<p>This solution requires InnoDB and a version of MySQL that allows locking. I believe that in conjunction with solid abuse monitoring on the web server side we create a solution that ensures served requests are not abusive and properly handled. Is it scalable? Better than say <code>sleep</code> but still can have problems. Any time we introduce code dealing with timing out we run the risk of trouble. Also, according to the MySQL documentation calling <code>get_lock</code> multiple times overrides the previous lock so you must check to see if its currently in use before calling it. </p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2010/04/10/php-ajax-race-conditions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flicka.mobi Goes Live</title>
		<link>http://michaelhradek.com/blog/2010/01/25/flicka-mobi-goes-live/</link>
		<comments>http://michaelhradek.com/blog/2010/01/25/flicka-mobi-goes-live/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 02:12:46 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Flicka]]></category>

		<guid isPermaLink="false">http://michaelhradek.com/blog/2010/01/25/flicka-mobi-goes-live/</guid>
		<description><![CDATA[We&#8217;ve (Koa + me = MokaSocial, LLC) finally pushed out Flicka.mobi the official portal to Flicka, our Flickr application for the Android platform! It will bring all the free functionality of the Flickr website and add tons of integration into &#8230; <a href="http://michaelhradek.com/blog/2010/01/25/flicka-mobi-goes-live/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div style="margin-bottom: 10px; border: 0;"><a href="http://www.flicka.mobi/"></a></div>
<p style="text-align: center;"><img title="Flicka - Flickr + Android" src="http://www.fieldmarshallhradek.com/images/blog/flicka_logo.png" alt="Flicka - Flickr + Android" /></p>
<p>We&#8217;ve (<a href="http://iamkoa.net/">Koa</a> + me = MokaSocial, LLC) finally pushed out <a href="http://www.flicka.mobi/">Flicka.mobi</a> the official portal to Flicka, our Flickr application for the Android platform! It will bring all the free functionality of the Flickr website and add tons of integration into the mobile platform. We&#8217;re hoping to be able to launch the actual application by the beginning of Q2 this year. We&#8217;ll see.</p>
<p>The page kind of tells you about the release and stuff but here are all the links:</p>
<ul>
<li>Blog &#8211; http://flickamobi.tumblr.com/</li>
<li>Flickr App Garden &#8211; http://www.flickr.com/services/apps/72157623025084241/</li>
<li>Facebook &#8211; http://www.facebook.com/pages/Flicka/189775049761</li>
<li>Twitter (of our Pivotal Tracker feed) &#8211; http://twitter.com/flickamobi</li>
<li>Get Satisfaction &#8211; http://getsatisfaction.com/flicka</li>
</ul>
<p>It&#8217;s been one frantic push to get the code base stabilized and things to a place where we can finally start talking about it. There isn&#8217;t much about the Google Android SDK on the web so that&#8217;s probably the biggest challenge. Also, the Java library we&#8217;re using for our interactions doesn&#8217;t seem to have everything.</p>
<p>Anyway, it&#8217;s been a wonderful dive into Java and I&#8217;ve been thoroughly enjoying it. We&#8217;re hoping it&#8217;s a successful mobile platform application; one in a series of many increasingly complex and sexy!</p>
<p>Special thanks to those that have been helping. The organization, insight, and comradeship has been awesome!</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2010/01/25/flicka-mobi-goes-live/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rate Limiting in PHP</title>
		<link>http://michaelhradek.com/blog/2009/12/05/rate-limiting-in-php/</link>
		<comments>http://michaelhradek.com/blog/2009/12/05/rate-limiting-in-php/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 03:56:32 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://michaelhradek.com/blog/2009/12/05/rate-limiting-in-php/</guid>
		<description><![CDATA[Recently I was having a discussion about putting together an API and some ideas about caching, rate limiting or flood protection, design patterns for rendering the output, scalability, and security came up. A while ago I came up with a &#8230; <a href="http://michaelhradek.com/blog/2009/12/05/rate-limiting-in-php/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I was having a discussion about putting together an API and some ideas about caching, rate limiting or flood protection, design patterns for rendering the output, scalability, and security came up.</p>
<p>A while ago I came up with a rate limiting class. It wasn&#8217;t as thoroughly tested as I would hope as I left a little over a week after putting this together there, but basically we use time as a cross thread limiter for all connections. If we wanted to limit a particular user, then we&#8217;d simply have to create a unique key for the memcache entry for each user.</p>
<p>This logic uses time (as Unix timestamps with microseconds) as a method to &#8220;charge&#8221; each request against the server a &#8220;fee&#8221; which accrues against the max or limit. As time moves forward, it removes accrued cost from the memcache saved value.</p>
<p>The beauty of doing rate limiting in code is it allows the developer to manage flow and how limits are handled to protect our databases and CPU load; dishing out less expensive and properly (and expected) formed API responses.</p>
<p>Here&#8217;s the code:</p>
<pre class="brush:php">////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// 	RATE LIMITER CLASS - rateLimiter.class.php
//
// 	@date:	2009.05.21
// 	@author 	Michael Hradek
// 	@version 	1.0.0
// 	@license 	Apache License, Version 2.0
//
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// INCLUDES
////////////////////////////////////////////////////////////////////////////

require_once("initializeMemcache.class.php");

////////////////////////////////////////////////////////////////////////////
// PRIMARY CLASS
////////////////////////////////////////////////////////////////////////////

class rateLimiter
{
    private $rateLimitKey;
    private $rateLimitMax;
    private $rateLimitCost;

    private $memcache;

    function __construct($rateLimitMax, $rateLimitCost,
                         $rateLimitKey = "rate_limiter_key")
    {
        $this->rateLimitMax = (float)$rateLimitMax;
        $this->rateLimitCost = (float)$rateLimitCost;
        $this->rateLimitKey	= $rateLimitKey;

        // Initialize your memcache. This is just one way of initializing it.
        $this->memcache	= InitializeMemcache::initMemcache();
    }

    public function enforceRateLimit()
    {
        $rateLimitDataMs = $this->memcache->get($this->rateLimitKey);
        list($partMsec, $partSec) = explode(" ", microtime());
        $currentTimeMs = $partSec.$partMsec;
        if($rateLimitDataMs === false)
        {
            $this->memcache->set($this->rateLimitKey, $currentTimeMs,
                                 MEMCACHE_COMPRESSED);
            return true;
        }

        $timeDiffMs = $rateLimitDataMs - $currentTimeMs;
        if($timeDiffMs < 0) {
            $rateLimitDataMs = $currentTimeMs;
        }

        $rateLimitDataMs += $this->rateLimitCost;
        if($timeDiffMs < $this->rateLimitMax)
        {
            if(!$this->memcache->replace($this->rateLimitKey,
                                $rateLimitDataMs, MEMCACHE_COMPRESSED)) {
                $this->memcache->set($this->rateLimitKey, $rateLimitDataMs,
                                     MEMCACHE_COMPRESSED);
            }

            return true;
        }

        $rateLimitDataMs += ($this-&gt;rateLimitCost*2);
        if(!$this-&gt;memcache->replace($this->rateLimitKey, $rateLimitDataMs,
                                     MEMCACHE_COMPRESSED)) {
            $this-&gt;memcache->set($this->rateLimitKey, $rateLimitDataMs,
                                 MEMCACHE_COMPRESSED);
        }

        error_log(get_class().": Rate limit enforced.");
        return false;
    }
}
</pre>
<p>The memcache class is simply something that reads memcache server configuration arrays and loads them into a memcache handle and returns it. I think with some larger volumes we can excuse things like misses in key lookups. We&#8217;re already using a hashed configuration. Why add the trouble of retrying?</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2009/12/05/rate-limiting-in-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Emmm, Easter Egg Function</title>
		<link>http://michaelhradek.com/blog/2009/11/20/emmm-easter-egg-function/</link>
		<comments>http://michaelhradek.com/blog/2009/11/20/emmm-easter-egg-function/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:25:31 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[funny]]></category>

		<guid isPermaLink="false">http://michaelhradek.com/blog/2009/11/20/emmm-easter-egg-function/</guid>
		<description><![CDATA[While carousing the code base I&#8217;ve been alerted of the existence of an interesting function: public static function the_answer_to_life_the_universe_and_everything() { $calculation = sqrt(9) * 12; $calculation = pow($calculation, 2); $calculation = ($calculation / 4); $calculation = ($calculation - 4); $calculation &#8230; <a href="http://michaelhradek.com/blog/2009/11/20/emmm-easter-egg-function/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>While carousing the code base I&#8217;ve been alerted of the existence of an interesting function:</p>
<pre class="brush:php">public static function the_answer_to_life_the_universe_and_everything() {

    $calculation = sqrt(9) * 12;
    $calculation = pow($calculation, 2);
    $calculation = ($calculation / 4);
    $calculation = ($calculation - 4);
    $calculation = ($calculation / 10);
    $calculation = ($calculation + 10);

    return $calculation;
}</pre>
<p>Brilliant. +2 Intelligence, +4 Charisma if you get the reference. Yes, this made my day and yes, it was worthy of a blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2009/11/20/emmm-easter-egg-function/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stored Procedure: Part I</title>
		<link>http://michaelhradek.com/blog/2008/12/19/stored_procedure/</link>
		<comments>http://michaelhradek.com/blog/2008/12/19/stored_procedure/#comments</comments>
		<pubDate>Sat, 29 Jul 2006 03:02:53 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://michaelhradek.com/blog/2008/12/19/stored_procedure/</guid>
		<description><![CDATA[I finally got my stored procedure to work. Its a dynamic select stement for MySQL. It also has an output so you can check the executed query. Since this is a relatively new feature for MySQL (introduced with version 5) &#8230; <a href="http://michaelhradek.com/blog/2008/12/19/stored_procedure/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I finally got my stored procedure to work. Its a dynamic select stement for MySQL. It also has an output so you can check the executed query. Since this is a relatively new feature for MySQL (introduced with version 5) its been hard to find any documentation on it. You need to use MySQLI to use the results a query would return using a stored procedure. Some of the stored procedure documentation out there is for other SQLs and servers. What is awesome about this is that it resides on the server. The applications simply use whatever native connection methodology and call this procedure. That way there is a unified layer of queries to the database and other applications can use them. Also, since its cached on the server box it makes for a much faster execution and it reduces some network traffic. Here is an example:</p>
<pre class="brush:sql">CREATE PROCEDURE p_getDBInfo(IN inputTable char(30), IN inputOrder char(10), IN inputColumn char(20), IN inputFrom INT, IN inputMax INT, IN inputName char(25), IN inputTag char(4), OUT outputQuery varchar(4000))
LANGUAGE SQL
NOT DETERMINISTIC
SQL SECURITY INVOKER
COMMENT ""

BEGIN
    DECLARE query varchar(4000);
	DECLARE debug int; 

    SET debug = 1;
    SET outputQuery = "";
    SET @query = "SELECT Ranks, Names, Tags,
                  Territory, Ratings, Wins, Losses FROM";

    IF inputTable IS NOT NULL THEN
	SET @query = CONCAT(@query, " ", inputTable);
    ELSE
	SET @query = CONCAT(@query, " ladder_world");
    END IF;

    IF inputName IS NOT NULL || inputTag IS NOT NULL THEN
	SET @query = CONCAT(@query, " WHERE");
    END IF;

    IF inputName IS NOT NULL THEN
	SET @query = CONCAT(@query, " Names LIKE ", inputName);
    END IF; 

    IF inputName IS NOT NULL &amp;&amp; inputTag IS NOT NULL THEN
	SET @query = CONCAT(@query, " AND");
    END IF;

    IF inputTag IS NOT NULL THEN
	SET @query = CONCAT(@query, " Tags LIKE ", inputTag);
    END IF; 

    IF inputColumn IS NOT NULL THEN
	SET @query = CONCAT(@query, " ORDER BY ", inputColumn);
    ELSE
	SET @query = CONCAT(@query, " ORDER BY Ranks");
    END IF; 

    IF inputOrder IS NOT NULL THEN
	SET @query = CONCAT(@query, " ", inputOrder);
    ELSE
	SET @query = CONCAT(@query, " ASC");
    END IF;

    IF inputFrom IS NOT NULL THEN
	SET @query = CONCAT(@query, " LIMIT ", inputFrom);
    ELSE
	SET @query = CONCAT(@query, " LIMIT 0");
    END IF;

    IF inputMax IS NOT NULL THEN
	SET @query = CONCAT(@query, ", ", inputMax);
    ELSE
	SET @query = CONCAT(@query, ", 20");
    END IF; 

    IF debug = 1 THEN
	SET outputQuery = @query;
    END IF;

    PREPARE pst FROM @query;
    EXECUTE pst;
    DEALLOCATE PREPARE pst;
END;</pre>
<p>To execute this stored procedure with PHP 5 with MySQL 5 you would:</p>
<pre class="brush:php">$link = mysqli_connect("localhost", "username", "password", "ladder");
    $query = mysqli_multi_query($link, "CALL p_getDBInfo(null, null, null, null, null, null, null, @a)") or die(mysql_error());
    if ($result = mysqli_store_result($link))
    {
	while ($row = mysqli_fetch_row($result)) {
		print_r($row);
        }
	mysqli_free_result($result);
    }

mysqli_close($link);</pre>
<p>From what I&#8217;ve read the procedural language is very much like PASCAL but I wouldn&#8217;t know. I recognize the IF&#8230; END IF; from my computer science classes and stuff. Anyway, I need to rework the connection tools I put together. We&#8217;ll see.</p>
]]></content:encoded>
			<wfw:commentRss>http://michaelhradek.com/blog/2008/12/19/stored_procedure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

