<?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"
	>

<channel>
	<title>Cynically Optimistic</title>
	<atom:link href="http://www.ajaxtrans.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ajaxtrans.com/blog</link>
	<description></description>
	<pubDate>Tue, 22 Jul 2008 23:10:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Fun with decorators on the Google AppEngine</title>
		<link>http://www.ajaxtrans.com/blog/2008/07/22/fun-with-decorators-on-the-google-appengine/</link>
		<comments>http://www.ajaxtrans.com/blog/2008/07/22/fun-with-decorators-on-the-google-appengine/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 23:10:34 +0000</pubDate>
		<dc:creator>Joel Parish</dc:creator>
		
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.ajaxtrans.com/blog/?p=12</guid>
		<description><![CDATA[Well I thought I&#8217;d give writing for the Google AppEngine a try and have found it a delightful platform to work with. Easy deployment, easy scalability (the DataStore non-RDBMS is a bit harder to get your mind around), and a squeaky clean WebOb-based WSGI minimalist framework called WebApp. Anyways, in developing a simple REST service, [...]]]></description>
			<content:encoded><![CDATA[<p>Well I thought I&#8217;d give writing for the <a href="http://appengine.google.com/">Google AppEngine</a> a try and have found it a delightful platform to work with. Easy deployment, easy scalability (the DataStore non-RDBMS is a bit harder to get your mind around), and a squeaky clean <a href="http://pythonpaste.org/webob/">WebOb</a>-based WSGI minimalist framework called <a href="http://code.google.com/appengine/docs/webapp/">WebApp</a>. Anyways, in developing a simple REST service, I ran across a great place to use <a href="http://www.python.org/dev/peps/pep-0318/">Python Decorators</a>. I needed to restrict access to a specific REST method based on IP Address so I wrote the following decorator:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">def</span> bind_ip<span style="color: black;">&#40;</span>ips<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> _dec<span style="color: black;">&#40;</span>handler<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">def</span> _check_ip<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:            
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">request</span>.<span style="color: black;">remote_addr</span> <span style="color: #ff7700;font-weight:bold;">in</span> ips:
                <span style="color: #ff7700;font-weight:bold;">return</span> handler<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                  <span style="color: #008000;">self</span>.<span style="color: black;">error</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">403</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> _check_ip
    <span style="color: #ff7700;font-weight:bold;">return</span> _dec</pre></td></tr></table></div>

<p>The decorator returns a closure which only calls the method it encapsulates if the IP address of the client is specifically allowed. Notice the <code>@bind_ip</code> on line 11</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> wsgiref.<span style="color: black;">handlers</span>
<span style="color: #ff7700;font-weight:bold;">from</span> google.<span style="color: black;">appengine</span>.<span style="color: black;">ext</span> <span style="color: #ff7700;font-weight:bold;">import</span> webapp
<span style="color: #ff7700;font-weight:bold;">from</span> util <span style="color: #ff7700;font-weight:bold;">import</span> bind_ip
&nbsp;
allowed_ips = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>
    <span style="color: #483d8b;">'127.0.0.1'</span>,
    <span style="color: #483d8b;">'ip.of.rest.client'</span>
    <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SecretHandler<span style="color: black;">&#40;</span>webapp.<span style="color: black;">RequestHandler</span><span style="color: black;">&#41;</span>:
  @bind_ip<span style="color: black;">&#40;</span>allowed_ips<span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, secret<span style="color: black;">&#41;</span>:
     <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot; Do something Secret &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
     <span style="color: #008000;">self</span>.<span style="color: black;">response</span>.<span style="color: black;">out</span>.<span style="color: black;">write</span> <span style="color: black;">&#40;</span>secret<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
  application = webapp.<span style="color: black;">WSGIApplication</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>
          <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'/secret/(.*)'</span>, SecretHandler<span style="color: black;">&#41;</span>
      <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
  wsgiref.<span style="color: black;">handlers</span>.<span style="color: black;">CGIHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">run</span><span style="color: black;">&#40;</span>application<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
  main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Decorators are a simple way to easily annotate how functions should be called, and can be used for Authentication, Data Validation or however else you&#8217;d like to use them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxtrans.com/blog/2008/07/22/fun-with-decorators-on-the-google-appengine/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An illegal function</title>
		<link>http://www.ajaxtrans.com/blog/2007/05/01/illegalfunction/</link>
		<comments>http://www.ajaxtrans.com/blog/2007/05/01/illegalfunction/#comments</comments>
		<pubDate>Wed, 02 May 2007 04:33:49 +0000</pubDate>
		<dc:creator>Joel Parish</dc:creator>
		
		<category><![CDATA[math]]></category>

		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.ajaxtrans.com/blog/2007/05/01/illegalfunction/</guid>
		<description><![CDATA[Can a function be illegal? Thanks to the blessings of interpolation and of Mathematica (Wolfram just happened to release version 6 today), I present the HD-DVD AACS Processing key interpolated into a polynomial equation!  

]]></description>
			<content:encoded><![CDATA[<p>Can a function be illegal? Thanks to the blessings of interpolation and of <a href="http://www.wolfram.com/products/mathematica/index.html">Mathematica</a> (Wolfram just happened to release version 6 today), I present the HD-DVD AACS Processing key interpolated into a polynomial equation! <img src='http://www.ajaxtrans.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img src="http://private.parish.ath.cx/equation.png" alt="the Illegal Function" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxtrans.com/blog/2007/05/01/illegalfunction/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AjaxTrans rewritten in Mod-Python</title>
		<link>http://www.ajaxtrans.com/blog/2007/03/04/ajaxtrans-rewritten-in-mod-python/</link>
		<comments>http://www.ajaxtrans.com/blog/2007/03/04/ajaxtrans-rewritten-in-mod-python/#comments</comments>
		<pubDate>Sun, 04 Mar 2007 21:57:24 +0000</pubDate>
		<dc:creator>Joel Parish</dc:creator>
		
		<category><![CDATA[AjaxTrans]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.parish.ath.cx/2007/03/04/ajaxtrans-rewritten-in-mod-python/</guid>
		<description><![CDATA[After many months of dissatisfaction regarding PHP (especially its Unicode Support), I decided to rewrite AjaxTrans in mod_python. A language which has allowed a much greater flexibility in the area of character sets. This transition has allowed me to incorporate 4 new languages into AjaxTrans:

Chinese
Japanese
Korean
Russian


Enjoy!
PS: Comment on any bugs/errors/interface mistakes (The spanish interface translation is [...]]]></description>
			<content:encoded><![CDATA[<p>After many months of dissatisfaction regarding PHP (especially its Unicode Support), I decided to rewrite <a href="http://translate.parish.ath.cx/">AjaxTrans</a> in <a href="http://www.modpython.org/">mod_python</a>. A language which has allowed a much greater flexibility in the area of character sets. This transition has allowed me to incorporate 4 new languages into AjaxTrans:</p>
<ol>
<li>Chinese</li>
<li>Japanese</li>
<li>Korean</li>
<li>Russian</li>
</ol>
<p><a href="http://translate.parish.ath.cx/"><img src="http://images.parish.ath.cx/ajaxtrans.jpg" /></a></p>
<p>Enjoy!</p>
<p>PS: Comment on any bugs/errors/interface mistakes (The spanish interface translation is likely full of errors as it&#8217;s written by a student who&#8217;s only currently taking Spanish&#8230; in High-School&#8212;me)  feedback much appreciated, also translations of the interface into your language would be greatly welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxtrans.com/blog/2007/03/04/ajaxtrans-rewritten-in-mod-python/feed/</wfw:commentRss>
		</item>
		<item>
		<title>From a self-confessed bandwidth-o-holic&#8230;</title>
		<link>http://www.ajaxtrans.com/blog/2007/03/04/adventures-in-bandwidth/</link>
		<comments>http://www.ajaxtrans.com/blog/2007/03/04/adventures-in-bandwidth/#comments</comments>
		<pubDate>Sun, 04 Mar 2007 21:11:39 +0000</pubDate>
		<dc:creator>Joel Parish</dc:creator>
		
		<category><![CDATA[AjaxTrans]]></category>

		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://blog.parish.ath.cx/?p=3</guid>
		<description><![CDATA[This is my first blog, and coincidentally my first blog post, so please forgive me if I am completely irrelevant, make horrendous errors in nature of fact, grammar or spelling or even abuse commas by creating very long winded introductions.
Anyways, just about a week ago I noticed my server had slowed to a crawl. Not [...]]]></description>
			<content:encoded><![CDATA[<p>This is my first blog, and coincidentally my first blog <em>post</em>, so please forgive me if I am completely irrelevant, make horrendous errors in nature of fact, grammar or spelling or even abuse commas by creating very long winded introductions.</p>
<p>Anyways, just about a week ago I noticed my server had slowed to a crawl. Not just any crawl mind you, but like that slow-as-molasses kind of crawl which makes you want to scream. I quickly opened my trusty copy of <a target="_blank" href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a> and ssh&#8217;d into the server. PuTTY was configured to automatically send my username to the server and wait for &#8220;keyboard-interactive authentication&#8221; to enter my password. I waited for about five seconds before the password prompt appeared, I dutifully entered my password and hit the enter key. Nothing&#8230; Waiting&#8230; still nothing and then finally</p>
<blockquote><p>Last login: Mon Aug  21 13:43:39 2006 from 68.68.*.*<br />
www ~ $</p></blockquote>
<p>Curious as to the cause of such slowness in my precious 3GHz P4 Gentoo <a href="http://funroll-loops.org/">-O3 -funroll-loops -fomit-frame-pointer -fgo-uber-fast</a> server, I prodded around a little bit. After checking <a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?top+1">top</a>, CPU usage wasn&#8217;t the culprit, memory was fine, EUREKA the <a href="http://www.penguin-soft.com/penguin/man/1/apachetop.html">apachetop </a>was showing that the connection was bottlenecking at only 6 KB/s. Had someone switched the colo&#8217;s OC-3 for a Dialup connection? The next day I took a visit to the colo and visited my cute-little-rack-mounted-box did a diagnostic from there, only to find the same results: 6KB/s. This was driving me crazy, I couldn&#8217;t even transfer a day&#8217;s log file, let alone serve more than 2 clients with my bandwidth intensive <a href="http://ajax.parish.ath.cx/translator/">translation application</a>. Turned out some backhoe operator hadn&#8217;t &#8220;Dialed Before he Dug&#8221; and had cut right through a fiber-optic line which my server depended on the traffic was being routed through an alternate connection which was did not have nearly enough capacity for the event.</p>
<p>So this got me thinking, what is life like without broadband. I hadn&#8217;t used a dialup connection in years, much less used a dialup connection to connect to the bandwidth-heavy Web 2.0 goodness which dominates the current incarnation of the web. I wondered what my <a href="http://ajax.parish.ath.cx/translator/">AjaxTrans</a> application looked like from the eyes of its dialup users. Whipping out my trusty web-development swiss army knife, the <a href="https://addons.mozilla.org/firefox/60/">Firefox Web Developer Toolbar</a>, I opened the tools menu to see what was there. Ahh, &#8220;View speed report&#8221; that looks nifty, I click and this is what I find:</p>
<blockquote>
<table>
<tr>
<th>Connection Rate</th>
<th>Download Time</th>
</tr>
<tr>
<td>14.4K</td>
<td>86.79 seconds</td>
</tr>
<tr>
<td>28.8K</td>
<td>43.50 seconds</td>
</tr>
<tr>
<td>33.6K</td>
<td>37.31 seconds</td>
</tr>
<tr>
<td bgcolor="lightyellow">56K</td>
<td bgcolor="lightyellow">22.47 seconds</td>
</tr>
<tr>
<td>ISDN 128K</td>
<td>7.02 seconds</td>
</tr>
<tr>
<td>T1 1.44Mbps</td>
<td>0.79 seconds</td>
</tr>
</table>
</blockquote>
<p>23 Seconds! That must be unbearable. I quickly read the report to see what I could do to change this enormous amount of loading time, and I saw that it was loading 7 Scripts externally in addition to the images and CSS.</p>
<p>After asking some friends what they would do to alleviate the problem, one suggested that I use two tools:</p>
<ol>
<li>The  <a href="http://dojotoolkit.org/docs/shrinksafe">Dojo Toolkit Compressor</a></li>
<li><a href="http://www.crockford.com/javascript/jsmin.html">JSMin</a></li>
</ol>
<p>I flattened the seven scripts into one file, streamlined.js and with one command I was off:</p>
<blockquote><p>java -jar custom_rhino.jar -c streamlined.js | jsmin > compressed.js</p></blockquote>
<p>I had reduced the file size by 50%, but I wasn&#8217;t quite done yet. I used an old trick from when I did code for dialup connections&#8230; gzip. After editing my .htaccess</p>
<blockquote><p>
<code>&lt;Files ~"\.js$"&gt;<br />
ForceType application/php<br />
&lt;/Files&gt;</code>
</p></blockquote>
<p>I added</p>
<blockquote><p><code>&lt;?php ob_start("ob_gzhandler"); ?&gt;</code></p></blockquote>
<p>to the beginning of compressed.js and squeezed another 16% size out of it.</p>
<p>The final results:</p>
<blockquote>
<table>
<tr>
<th>Connection Rate</th>
<th>Download Time</th>
</tr>
<tr>
<td>14.4K</td>
<td>26.61 seconds</td>
</tr>
<tr>
<td>28.8K</td>
<td>13.40 seconds</td>
</tr>
<tr>
<td>33.6K</td>
<td>11.52 seconds</td>
</tr>
<tr>
<td bgcolor="lightyellow">56K</td>
<td bgcolor="lightyellow">6.99 seconds</td>
</tr>
<tr>
<td>ISDN 128K</td>
<td>2.28 seconds</td>
</tr>
<tr>
<td>T1 1.44Mbps</td>
<td>0.38 seconds</td>
</tr>
</table>
</blockquote>
<p>The comparasion:<br />
<img src="http://images.parish.ath.cx/speedoptimization.png" width="400" height="334" /><br />
Just under 7 seconds! Yay, I reduced the load time by a factor of pi! How nerdy&#8230; well a factor of 3.147 anyways, a 66% size reduction.</p>
<p>You have no idea how much I sympathize with you dialup users.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxtrans.com/blog/2007/03/04/adventures-in-bandwidth/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
