<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Reapplied Engineering</title>
	<atom:link href="http://rickonrails.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rickonrails.wordpress.com</link>
	<description>Rick Branson on Web Development, Data Warehousing, and other boring stuff I can&#039;t talk to my girlfriend about.</description>
	<lastBuildDate>Fri, 25 Mar 2011 22:41:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='rickonrails.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Reapplied Engineering</title>
		<link>http://rickonrails.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://rickonrails.wordpress.com/osd.xml" title="Reapplied Engineering" />
	<atom:link rel='hub' href='http://rickonrails.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Chrome Frame Ain&#8217;t So Hard</title>
		<link>http://rickonrails.wordpress.com/2009/09/22/chrome-frame-aint-so-hard/</link>
		<comments>http://rickonrails.wordpress.com/2009/09/22/chrome-frame-aint-so-hard/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 00:31:20 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=99</guid>
		<description><![CDATA[&#8230; it just takes a little while to install. There&#8217;s quite a buzz going on around the coolkidsosphere about Google&#8217;s rather audacious move to build a browser plug-in that essentially embeds the Chrome engine inside of Internet Explorer. Called Chrome Frame, it&#8217;s a big punch in the face to Microsoft for sure. There&#8217;s a big [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=99&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>&#8230; it just takes a little while to install. There&#8217;s quite a buzz going on around the <em>coolkidsosphere</em> about Google&#8217;s rather audacious move to build a browser plug-in that essentially embeds the Chrome engine inside of Internet Explorer. Called Chrome Frame, it&#8217;s a big punch in the face to Microsoft for sure. There&#8217;s a big crowd of folks on various forums screaming &#8220;rubble rubble! nobody is going to download this!&#8221; So, I took it upon my humble self to see what was involved in the installation of Chrome Frame.</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step1.png"><img class="size-medium wp-image-100 aligncenter" title="Step One" src="http://rickonrails.files.wordpress.com/2009/09/step1.png?w=300&#038;h=254" alt="Step One" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Step One: </strong>Get Harassed by Google JavaScript code.</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step2.png"><img class="size-medium wp-image-101 aligncenter" title="step2" src="http://rickonrails.files.wordpress.com/2009/09/step2.png?w=300&#038;h=254" alt="step2" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Step Two: <span style="font-weight:normal;">Agree to life without parole for uttering &#8220;Microsoft ain&#8217;t so bad.&#8221;</span></strong></p>
<p style="text-align:left;"><strong><span style="font-weight:normal;"><a href="http://rickonrails.files.wordpress.com/2009/09/step3.png"><img class="size-medium wp-image-102 aligncenter" title="step3" src="http://rickonrails.files.wordpress.com/2009/09/step3.png?w=300&#038;h=254" alt="step3" width="300" height="254" /></a></span></strong></p>
<p style="text-align:left;"><strong>Step Three: </strong>Click &#8220;Run.&#8221; No, God, shut up, don&#8217;t read the instructions.</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step4.png"><img class="size-medium wp-image-103 aligncenter" title="step4" src="http://rickonrails.files.wordpress.com/2009/09/step4.png?w=300&#038;h=254" alt="step4" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Step Four: </strong>Didn&#8217;t we already click Run?</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step5.png"><img class="size-medium wp-image-104 aligncenter" title="step5" src="http://rickonrails.files.wordpress.com/2009/09/step5.png?w=300&#038;h=254" alt="step5" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Step Five: </strong>Cool. FINALLY we&#8217;re getting somewhere.</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step6.png"><img class="size-medium wp-image-105 aligncenter" title="step6" src="http://rickonrails.files.wordpress.com/2009/09/step6.png?w=300&#038;h=254" alt="step6" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Step Six: </strong>You&#8217;re welcome! Do I bend over now or later?</p>
<p style="text-align:left;"><a href="http://rickonrails.files.wordpress.com/2009/09/step7.png"><img class="size-medium wp-image-106 aligncenter" title="step7" src="http://rickonrails.files.wordpress.com/2009/09/step7.png?w=300&#038;h=254" alt="step7" width="300" height="254" /></a></p>
<p style="text-align:left;"><strong>Not-Really-A-Step:</strong> That&#8217;s a strange UserAgent string!</p>
<p style="text-align:left;">Sooooo, overall, not that bad. The installer itself was small, but it does it&#8217;s own download of a few megabytes of Chrome &#8220;guts&#8221; from the Google servers. The download only takes a few minutes, but that might push the patience of your end users. Next step is to test this on an unprivileged account. Any volunteers?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=99&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2009/09/22/chrome-frame-aint-so-hard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step1.png?w=300" medium="image">
			<media:title type="html">Step One</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step2.png?w=300" medium="image">
			<media:title type="html">step2</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step3.png?w=300" medium="image">
			<media:title type="html">step3</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step4.png?w=300" medium="image">
			<media:title type="html">step4</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step5.png?w=300" medium="image">
			<media:title type="html">step5</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step6.png?w=300" medium="image">
			<media:title type="html">step6</media:title>
		</media:content>

		<media:content url="http://rickonrails.files.wordpress.com/2009/09/step7.png?w=300" medium="image">
			<media:title type="html">step7</media:title>
		</media:content>
	</item>
		<item>
		<title>Ruby Threads, Werd.</title>
		<link>http://rickonrails.wordpress.com/2009/08/30/ruby-threads-werd/</link>
		<comments>http://rickonrails.wordpress.com/2009/08/30/ruby-threads-werd/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 05:37:39 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=94</guid>
		<description><![CDATA[So I&#8217;m finally playing around with Ruby 1.9 threads because that is what all the cool kids are doing. After seeing some data processing scripts of mine run way faster in 1.9, my interest was piqued. Using Twitter&#8217;s performance issues as a model around which to write little benchmarks is what I consider weekend fun. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=94&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;m finally playing around with Ruby 1.9 threads because that is what all the cool kids are doing. After seeing some data processing scripts of mine run way faster in 1.9, my interest was piqued. Using Twitter&#8217;s performance issues as a model around which to write little benchmarks is what I consider weekend fun.</p>
<p>From what I gleaned reading blog posts during all the noise about Twitter hatin&#8217; on Ruby and switching to Scala, they had issues with the mainstream open sores MQ software that forced them to write their own. The two issues Twitter had with existing MQs is that RabbitMQ would run out of memory and crash because it had to store all of it&#8217;s &#8220;metadata&#8221; in main memory, and ActiveMQ is a very featureful but strange pile of Java poo that can&#8217;t really handle more than a few thousand queues.</p>
<p>So here we have it, twitterlite, a hacky Ruby script that attempts to re-enact a scene where we use an SQLite3 database as a disk-backed message store. The script creates a fixed-size list of &#8220;actors&#8221; (or users) that can send messages to each other. It then simulates a huge flood of writes for ~140 character messages. All of the fun is wrapped up in it&#8217;s own class that manages queueing the writes and the activities of the background thread. Each actor gets it&#8217;s own table that is comprised of two columns: source and message. (NOTE: This does not model the actual Twitter MQ usage, which is for background processing; this is just for fun.) Every N seconds or after the message backlog grows to N size, the background thread is prodded to run. The background thread does the writes to database wrapped up inside transactions that will run N number of INSERTs before it commits. The SQLite database is set to do full, synchronous writes to prevent any kind of corruption or data loss on disk failure.</p>
<p>While there is no disk corruption risk, the trade-off for fast writes is that we have some bit of &#8220;in-flight&#8221; data that could be lost if the server was to die. In production, you would probably have two of these boxes that would be receiving replicated write requests. Even then, if the background thread is set to flush every second or after the backlog reaches 250 messages, you&#8217;re not going to be out of very much. On my Mac Pro, with 1,000 actors and 2.5 million messages, it ran at 3,482 msg/sec. The higher you set the actor count, the slower it gets, primarily because a &#8220;CREATE TABLE&#8221; is pretty expensive and it&#8217;s doing these when it runs into a table-not-found error. I did some very unscientific testing and was successful in creating a single SQLite database with 1 million tables. It performed pretty well too (no hard numbers, you&#8217;ll just have to trust me).</p>
<p>Obviously this does not come close to reality as there&#8217;s some reads that are going to be going on and likely blocking some writes, but from what I understand, Kestrel (Twitter&#8217;s queueing software) only hits disk if the queues grow beyond a certain size, during rare &#8220;burst&#8221; periods where they would be seeing an extraordinary amount of messages. In this scenario, there would still be plenty of messages ready in memory to satisfy any consumers.</p>
<p>Really though, writing your own message queue software is dumb. I&#8217;ve heard all the excuses and still don&#8217;t buy it. The Gist for my lame benchmark script is <a href="http://gist.github.com/178302">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/94/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=94&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2009/08/30/ruby-threads-werd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>Instant Polls</title>
		<link>http://rickonrails.wordpress.com/2009/08/28/instant-polls/</link>
		<comments>http://rickonrails.wordpress.com/2009/08/28/instant-polls/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 19:33:42 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=92</guid>
		<description><![CDATA[File this under &#8220;Shameless SEO.&#8221; I&#8217;ve created a simple site for building instant polls in less than a minute. It&#8217;s called smokepoll. Hopefully that satisfies some sweet SEO requirements.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=92&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>File this under &#8220;Shameless SEO.&#8221; I&#8217;ve created a simple site for building <a href="http://smokepoll.com/">instant polls</a> in less than a minute. It&#8217;s called <a href="http://smokepoll.com/">smokepoll</a>. Hopefully that satisfies some sweet SEO requirements.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=92&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2009/08/28/instant-polls/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>Big Ole&#8217; MySQL Spatial Table Optimization Tricks</title>
		<link>http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/</link>
		<comments>http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 08:28:08 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Databases]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=74</guid>
		<description><![CDATA[So in the great saga of rolling out our mapping system, getting all the way down to street-level &#8212; and showing something there &#8212; has been one of the trickiest tasks. Between the sheer amount of data involved, labeling it all, making it look half-way decent, and paying protection money to ESRI, all while not [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=74&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So in the great saga of rolling out our mapping system, getting all the way down to street-level &#8212; and showing something there &#8212; has been one of the trickiest tasks. Between the sheer amount of data involved, labeling it all, making it look half-way decent, and paying protection money to ESRI, all while not spending a million bucks (literally), it&#8217;s no easy task. We&#8217;ve got this streets table from a commercial data provider that holds 30.8 million records for all of North America. It has 92 columns with a spatial index and consumes 14GB on disk in PostgreSQL. Needless to say, any 14GB table can be a real jerk to deal with. When you aren&#8217;t looking, it will sneak into your bathroom and piss all over the toilet seat, turning your girlfriend into <strong>Shiva, goddess of sitting on piss-laden toilet seats, who will show you no mercy on her path to vengeance.</strong></p>
<p>We need to make this data available to a couple of different mapping systems in both our Amazon EC2 cloud environment and here in development. MapGuide&#8217;s native spatial file format, <em>SDF</em>, is based on SQLite and is really fast for read operations, so we keep a copy of all the SDF files we need to draw the map wherever we&#8217;re going to do it. In EC2, we have specific instances dedicated to running MapGuide that each have the full compliment of SDFs for whatever map they&#8217;re supposed to be rendering. Unfortunately, keeping a local copy of the street data (which would be &gt;6GB in SDF format) on each instance is sort of out of question. Even if it were compressed heavily, the OS would so totally give me the hand if I expected it to cache any respectable portion of this data (along with all of the other geographic data). MapGuide really throws a little fit if the feature source files aren&#8217;t somewhere in the OS disk cache, especially if it&#8217;s churning the cache because the feature files won&#8217;t fit in RAM. It already starts a fight about my porn subscriptions, blah, blah, blah the first time it hits the ~500MB water &#8220;polygon&#8221; SDF file. </p>
<p>We receive  new copies of this data on a quarterly basis, so it&#8217;s pretty much read-only. As much as PostgreSQL is my homie, I will admit that MySQL is honestly <em>just better</em> for this case. MyISAM, MySQL&#8217;s oft-maligned fast-at-all-costs storage format sports killer table compression and MySQL is unendingly tunable. Even though people may slam PostgreSQL for having a bogus tune from the factory, after you adjust like three (..literally) config variables you&#8217;re pretty much good to go. MySQL, on the other hand, gives you a few thousand options all over the place, which may or may not be good thing depending on your level of competency. In your typical cases, PostgreSQL, when given a decent sized shared memory cache area, will perform excellently without low-level tuning. This isn&#8217;t your <em>Joe the Plumber</em> case though; this is return 10,000 rows of needle in a 30 million row spatial haystack, and do it <strong>right now</strong>. I need MySQL&#8217;s redneck, badass, big block &#8212; with a quadruple Demon Carb and lots of positive signs next to imperial measurements &#8212; attitude.</p>
<p>To just render the streets with the right style and label, we don&#8217;t need but 3 columns (geometry, name, class), so I dropped the other 89,000. I use the fabulous OGR tools to transfer data between different formats. The OGR tools throw a primary key column in the tables by default, causing the index file to explode in size, so it&#8217;s gone as well. Just putting the data on Weight Watchers shrank the MYD file, where the table data lives, down to 3.7GB. I used myisampack to compress the table (+1,000,000 bonus points for read-only situations), which usually yields excellent compression on tables with lots of columns. This one only dropped to 3.1GB. That&#8217;s still 600MB of data that we don&#8217;t need to carry around &#8212; I&#8217;ll take it. <strong>After building the index, we had 1.9GB + 3.1GB = 5GB&#8230; from 14GB&#8230; not bad. </strong>This is probably as small as I&#8217;m going to get an indexed version of this data set.</p>
<p>Of course, that&#8217;s still 30 million rows over 5GB. These days we like to throw gigabytes around like they&#8217;re nothing, but that&#8217;s literally 40 billion zeros and ones. Don&#8217;t hit the print button. Even tweaking the data with the myisamchk tool, which allows you to re-order the data and index in a few different ways, will have almost no affect on a gigantic R-tree structure like that. MySQL, like PostGIS, stores it&#8217;s spatial index data in an R-tree structure so it can find stuff fast. An R-tree, like a B-tree, is organized in such a manner that it is optimized for retrieving only a small fraction of the total data in the table. It is actually faster to ignore the index for queries that need to read a large section of the table to return data or perform a huge join, a classic case which gives rise to many database forum village idiots complaining about a query that returns half their table <em>&#8220;not using the new index they just created.&#8221;</em></p>
<p>Even when the total number of rows returned is still a fraction of the table, where the query needs something like 1,000+ rows, you&#8217;re in trouble. Each time the database server has to bravely go where it hasn&#8217;t been in a while, into a land of uncharted R-tree, it likely performs a pretty heinous <em>random disk read</em> every time it jumps from one part of the tree to another. In large indexes, like our nearly 2GB spatial index, which is easily 20 branches deep, this is a lot of disk seeks. To make matters worse, it&#8217;s unlikely the actual end-game table data is organized in such a fashion that we can perform a sequential scan over the disk. For those just joining the program, a random read does a disk seek, which puts the database to sleep while it waits for granny (disk head) to cross the street (magnetic platter). While the Linux disk queues act like a traffic cop and can tell granny to go home during busy traffic in many situations, there is only so long you can make granny wait before she keels over. In the seemingly minor 8-10 milliseconds it takes for granny to cross the street, the relatively coked out CPU can do like 100 million arithmetic operations &#8212; <em>per core</em>.  <strong>We&#8217;re still stuck doing hundreds to thousands of painfully slow disk operations just to fetch a single tile worth of street data.</strong></p>
<p>So what to do? We go back to our true love &#8212; <em>the &#8220;scaling&#8221; ingredient of choice</em> &#8212; memory. You probably already know, as indicated by you not panicking and entering &#8220;hot chicks&#8221; into the search box before you got anywhere near this paragraph, that memory is easily a thousand times faster than your traditional magnetic hard disk in every single way. This is about the only thing even the most argumentative, <em>foot-long-beard-having</em> computer nerds can agree on. The almighty &#8220;memcached,&#8221; practically the most celebrated computing achievement of all time, is nothing more than a network-accessible in-memory hash table. Now that memory is like $5 per GB (or really like $20/GB if you can use in any decent quantity), it&#8217;s way chic to use lots of network-shared memory to speed up your slow ass Y Combinator-funded social networking site for people with both HIV<em> and </em>herpes which &#8220;<em>just happens&#8221;</em> to be written in the slowest web framework you could find. If you still don&#8217;t believe me, below is a simple experiment almost anyone with a computer running a recent copy of OEM-installed Windows XP, Windows Vista, Mac OS X can perform.</p>
<ol>
<li>Buy a 128MB memory stick that is compatible with your computer. It will likely cost more money than the equivalent 1GB module.</li>
<li>Take all the memory out of your computer.</li>
<li>Put the 128MB memory stick in.</li>
<li>Hope your motherboard isn&#8217;t a dick about paired modules for dual channel memory access.</li>
<li>Boot up your computer.</li>
<li>Wait about thirty minutes for it to boot.</li>
<li>Try to do anything considered cool, like watch a Decemberists music video on iTunes in HD. Good luck. Your iPhone has more memory than that you faux indie motherfucker.</li>
</ol>
<p>Like the 2009 era Republican party, the OS will flail around desperately trying to get anything done. The basic home computer now has more than 250MB of stuff loaded just to get started, 200MB of which is anti-virus software &#8212; or a complete ecosystem of porn spyware because you didn&#8217;t have it installed &#8212; and the rest being the cute buttons for the interface. It is really a spectacular site watching this drama unfold. Needless to say, you will now be thoroughly convinced that memory is faster than disk.</p>
<p>The OS disk cache does a pretty good job of storing files we read over and over again. For most tasks, it&#8217;s great (I want to have it&#8217;s babies, etc), but sometimes a specialized, application-specific cache performs significantly better. The application itself (in this case, MySQL) will use a different strategy to read data, one that is better adapted, and much more efficient, at reading data out of memory, namely going nuts on the random access part of Random Access Memory. In some cases, the application cache will even compress data before caching it to allow more data to get packed in there. The small computational penalty paid by uncompressing the data before it can be used far eclipses the massive cost of hitting disk.</p>
<p>MySQL has three such special caches: <em>query</em>, <em>key</em>, and <em>table</em>. The query cache stores the results from past queries in memory. This isn&#8217;t so useful for our situation because we don&#8217;t have very many repeated queries as the upstream tile cache stores the resulting fully rendered images, preventing MySQL from even getting touched. While this is a good thing, it puts ketchup water all over our burger bun. Next is the key buffer, which stores frequently accessed portions of data indexes in memory. The key buffer saves a huge amount of disk work as index traversal on a large table can often require expensive disk work than fetching the actual data that it ends up pointing to. These days we&#8217;re also smart enough to batch table data reads together and do them sequentially as much as we can, saving precious disk I/O time. Unfortunately this isn&#8217;t enough &#8212; between the various layers of abstraction and planetary alignment, it&#8217;s highly unlikely that enough of the table data is actually stored on disk in the right order to make this batching process all that useful. The table cache augments all of these by going the final step &#8212; cache even the table data in memory. Again, the lack of repeated requests means we won&#8217;t really have data &#8220;hot spots&#8221; and just plain using caching isn&#8217;t going to get us anywhere. The incoming requests are going to be totally random and all over our 3GB table. We&#8217;d be lucky to have a warm spot.</p>
<p>So hell with it, we cache it all, which realistically requires available main memory for every last byte of the table and it&#8217;s index. This is in Amazon EC2, so we opt for the luxurious &#8220;large&#8221; instance (OoOoO&#8230; <em>large</em>) at $.40/hour, with it&#8217;s 7GB of main memory to house our MySQL server. The other instances, the ones that run MapGuide and draw the map images are &#8220;medium&#8221; sized, and only have 1.7GB of main memory. Even if we setup MySQL on each of these instances, it wouldn&#8217;t even come close to the performance of our &#8220;large&#8221; MySQL dedicated instance. Even if we tied 8 EBS volumes together in a striped RAID array and had Tom Cruise perform his <em>demon voodoo magic</em>. <strong>Not even close.</strong> The MapGuide instance each eat up all of their available 1.7GB of memory caching the ~1GB of SDF data files we&#8217;re using to render the outgoing map images. So we&#8217;re going with dedicated instance(s) for MySQL that are configured with no query cache, a 4GB table cache to cache the 3.1GB MYD file, and a 2GB key buffer to cache the 1.9GB MYI file. This gives plenty of room for the OS to do it&#8217;s dirty work&#8230; oh yeah. Even with all of these cache resources at it&#8217;s disposal, the performance when I first start up MySQL is lackluster as I expected.</p>
<pre>mysql&gt; SELECT COUNT(*) FROM streets WHERE MBRIntersects(GeomFromText('Polygon((-10018150.920914
4048533.503548,-10009717.327164 4048533.503548,-10009717.327164 4056967.097298,-10018150.920914
4056967.097298,-10018150.920914 4048533.503548))'),SHAPE);
+----------+
| COUNT(*) |
+----------+
|     3779 |
+----------+
1 row in set (2.11 sec)
 </pre>
<p><strong>Yuck. </strong>We need some way of making MySQL go ahead and fill it&#8217;s cache coffers. I use a brute force SELECT scan and a specific LOAD INDEX command to <em>warm the cache</em> &#8212; a cool scalable web 2.0<em>rgasm</em> term for pre-loading data into the cache before anyone asks for it.</p>
<pre>mysql&gt; select sum(length(shape)) from streets;
+--------------------+
| sum(length(shape)) |
+--------------------+
|         3009892693 |
+--------------------+
1 row in set (1 min 7.76 sec)

mysql&gt; load index into cache streets;
+------------------------+--------------+----------+----------+
| Table                  | Op           | Msg_type | Msg_text |
+------------------------+--------------+----------+----------+
| geography.streets      | preload_keys | status   | OK       |
+------------------------+--------------+----------+----------+
1 row in set (39.64 sec)
 </pre>
<p>Using the closely guarded &#8220;top&#8221; command, we can see that MySQL gorges itself on RAM as I&#8217;ve instructed it to.</p>
<pre>11557 mysql     15   0 5198m 4.9g 2.9g S    0 65.2   0:50.06 mysqld   
 </pre>
<p>That&#8217;s 4.9GB of resident memory, just for MySQL. I clear the OS disk cache to keep myself following some iota of scientific method.</p>
<pre># echo 1 &gt; /proc/sys/vm/drop_caches
 </pre>
<p>I pulled the MBR (or bounding box) coordinates out of the development MySQL server&#8217;s log for queries against this particular table to test the performance a little bit. It now can only be described as <strong>stupid fast</strong>.</p>
<pre>mysql&gt; SELECT COUNT(*) FROM streets WHERE MBRIntersects(GeomFromText('Polygon((-9998307.170914
4053494.441048,-9989873.577164 4053494.441048,-9989873.577164 4061928.034798,-9998307.170914
4061928.034798,-9998307.170914 4053494.441048))'),SHAPE);
+----------+
| COUNT(*) |
+----------+
|     2866 |
+----------+
1 row in set (0.00 sec)

mysql&gt; SELECT COUNT(*) FROM streets WHERE MBRIntersects(GeomFromText('Polygon((-8222291.545914
4772830.378548,-8213857.952164 4772830.378548,-8213857.952164 4781263.972298,-8222291.545914
4781263.972298,-8222291.545914 4772830.378548))'),SHAPE);
+----------+
| COUNT(*) |
+----------+
|     4767 |
+----------+
1 row in set (0.02 sec)

mysql&gt; SELECT COUNT(*) FROM streets WHERE MBRIntersects(GeomFromText('Polygon((-10018150.920914
4043572.566048,-10009717.327164 4043572.566048,-10009717.327164 4052006.159798,-10018150.920914
4052006.159798,-10018150.920914 4043572.566048))'),SHAPE);
+----------+
| COUNT(*) |
+----------+
|     3859 |
+----------+
1 row in set (0.01 sec)
 </pre>
<p>Hell yeah I fight people! I wanted even more proof, so I threw some dirty little Ruby scripts together to run a battery of these queries. I pulled 8,000 unique MBRs from the development query log that should represent a gamut of requests from real sessions. My &#8220;torture test&#8221; uses 8 simultaneous connections, the Ruby-MySQL native compiled driver, and does SELECT COUNT(*) requests as I&#8217;m not interested in measuring the marshaling performance at either end. The script emits the number of rows returned as well as the time we waited to get a result back for each request. At the end I run a statistics script that reads the raw output and gives it a decent paying job <em>with</em> good insurance.</p>
<p>For our large EC2 instance with a huge supply of empty Red Bull cans, performance was unimpressive.</p>
<p><strong>EC2 Large Instance, Cold MySQL Cache:</strong> 3m44.645s (~35 q/s &#8212; 16,463 rows/s)</p>
<pre>=== 8000 QUERIES ===
COUNTS: avg 176 (462), med 104, dev 1010.408, 99% &lt;5216, min 0, max 11892, sum 3698505
TIMES: avg 0.054 (0.153), med 0.005, dev 0.542, 99% &lt;2.465, min 0.000, max 16.251, sum 1222.613
 == 0: avg 0.000 (0.004), med 0.000, dev 0.036, 99% &lt;0.001, min 0.000, max 0.784, sum 4.116
 &gt;0: avg 0.065 (0.173), med 0.014, dev 0.574, 99% &lt;1.966, min 0.000, max 16.251, sum 1218.497
 &lt;1000: avg 0.042 (0.110), med 0.004, dev 0.348, 99% &lt;0.993, min 0.000, max 11.641, sum 667.707
 1000+: avg 0.243 (0.566), med 0.128, dev 1.207, 99% &lt;1.775, min 0.009, max 16.251, sum 550.790
</pre>
<p></p>
<p>One of these requests took 16 seconds to return! Even the max time for the requests between 0 and 1000 rows was 11.641 seconds. The 99% time of 2.465 was just unacceptable. The amount of latency this adds to tile drawing times is brutal. Especially when hitting dense, urban areas at a (relatively) high scale, which can require upwards of 10,000 rows to be returned for each tile. Using iostat, a Linux tool for monitoring disk activity, I could see MySQL&#8217;s data partition getting pounded. As the concurrency climbs with these larger queries, the disk I/O starts to get spread out across multiple queries and the aggregate time is even higher. In development it curiously seemed as if it all got put into a queue anyway, as simultaneous tiles would be returned in the order they were requested.</p>
<p>The improvement in performance after I warm the caches is stellar &#8212; <strong>nearly 25 times the throughput</strong>.</p>
<p><strong>EC2 Large Instance, Warm Cache: 9.484s </strong>(~843 q/s &#8212; 389,973 rows/s)</p>
<pre>=== 8000 QUERIES ===
COUNTS: avg 176 (462), med 104, dev 1010.408, 99% &lt;5216, min 0, max 11892, sum 3698505
TIMES: avg 0.003 (0.006), med 0.001, dev 0.026, 99% &lt;0.076, min 0.000, max 0.673, sum 46.914
 == 0: avg 0.000 (0.001), med 0.000, dev 0.018, 99% &lt;0.001, min 0.000, max 0.539, sum 1.290
 &gt;0: avg 0.003 (0.006), med 0.001, dev 0.027, 99% &lt;0.063, min 0.000, max 0.673, sum 45.624
 &lt;1000: avg 0.002 (0.004), med 0.001, dev 0.019, 99% &lt;0.029, min 0.000, max 0.673, sum 22.436
 1000+: avg 0.014 (0.024), med 0.010, dev 0.051, 99% &lt;0.054, min 0.003, max 0.665, sum 23.188
</pre>
<p></p>
<p>This means we can easily back over 40 MapGuide instances with a single large, dedicated instance for MySQL before performance will even think about degrading. In reality, that&#8217;s far more than we&#8217;d have before we started another MySQL instance just for failover purposes.</p>
<p>I did notice an odd thing with EBS, what Amazon calls persistent data volumes &#8212; disk storage that can survive a server reboot or crash &#8212; for it&#8217;s EC2 service. EBS volumes are accessed over the local network and are attached and detached by the Xen hypervisor, which provides the virtualization layer for EC2 instances. While EC2 instances are provided with machine-local storage, the data effectively becomes lost after a reboot, so you have to either download what you need to work with every time you boot an instance or use an EBS volume. I&#8217;m using an EBS volume to store the MySQL data files for this prototyping work and I&#8217;ve noticed some strange performance patterns. It does seem as if there is a decent sized cache somewhere between my instance and the disk drive it&#8217;s attached to through the various levels of abstraction of EBS. It seems plausible that Amazon followed the el-cheapo Linux box pattern and the nodes that house EBS are just more of them, which should do their own disk caching.</p>
<pre># dd if=/dev/sdh of=/dev/null bs=8k count=100k
Cold: 840392704 bytes (840 MB) copied, 16.1159 s, 52.1 MB/s
Locally Cached: 838860800 bytes (839 MB) copied, 0.964485 s, 870 MB/s
Warm: 838860800 bytes (839 MB) copied, 10.8145 s, 77.6 MB/s
</pre>
<p></p>
<p>Next I intentionally crank up the size to about the amount of RAM of an average run-of-the-mill server and things start to slow down.</p>
<pre># dd if=/dev/sdh of=/dev/null bs=8k count=500k
Cold: 4194304000 bytes (4.2 GB) copied, 68.7886 s, 61.0 MB/s
Warm: 4194304000 bytes (4.2 GB) copied, 71.4547 s, 58.7 MB/s
</pre>
<p></p>
<p>So that sounds about right. After I saw this I had to re-run my tests and force a cache flush to make sure I had the most accurate numbers and I wasn&#8217;t just hitting some remote EBS cache boogie man. As you can see, performance of single EBS volumes is about as stellar as a cheap SATA drive.</p>
<p><em>So&#8230;</em> what have we learned today in about 3,000 words?</p>
<ul>
<li>Don&#8217;t let anything piss on your girlfriend&#8217;s toilet.</li>
<li>Pre-cook your data so comes out filtered and sorted without filtering and sorting.</li>
<li>Fit everything you can in memory, <strong>as if that hasn&#8217;t already been said enough</strong>.</li>
<li>A single box that can house all the data in RAM is faster than 20 boxes that have to hit disk.</li>
<li>MySQL has a few key features that make it <em>totally</em> rock for big tables of read-only data.</li>
<li>Use MyISAM table compression to get read-only tables as small as possible.</li>
<li>EBS is an independent woman with it&#8217;s own cache and doesn&#8217;t need yours, unless there&#8217;s a sale at Aldo.</li>
<li>For Web 3.0, main memory will just not be fast enough, so someone will invent the successor to memcached, <em>cachecached</em>, which will only store data in L2 cache.</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/74/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/74/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/74/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=74&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>Half-Assed Python SHP to SDF FDO Scripts</title>
		<link>http://rickonrails.wordpress.com/2008/12/02/half-assed-python-shp-to-sdf-fdo-scripts/</link>
		<comments>http://rickonrails.wordpress.com/2008/12/02/half-assed-python-shp-to-sdf-fdo-scripts/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 01:38:23 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[1]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=72</guid>
		<description><![CDATA[So we needed automated SHP to SDF conversion for MapGuide and doing it on Windows was out of the picture, so I hobbled together some Python-based scripts that use FDO to do it. It works alright so far. I know this is coded poorly and I will regret releasing these scripts when I go in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=72&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So we needed automated SHP to SDF conversion for MapGuide and doing it on Windows was out of the picture, so I hobbled together some Python-based scripts that use FDO to do it. It works alright so far. I know this is coded poorly and I will regret releasing these scripts when I go in for some anal interview and they ask me why I didn&#8217;t use a bunch of metaprogramming and/or OOP fanciness and/or DRY, but it works and works well. It&#8217;s modeled after old versions of FdoToolbox, so blame those guys <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  It&#8217;s also kinda slow, but I&#8217;m sure an implementation of batch inserts would speed it up.
</p>
<p>
<a href="http://rickbranson.com/sloppy-python-fdo-tools.tar.gz">TARBALLZ HERE!!!1</a> (WARNING: This unpacks in ., so it will piss you off and pollute your home directory. You probably deserve it though you self-righteous Linux-using bastard)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=72&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/12/02/half-assed-python-shp-to-sdf-fdo-scripts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>Fix Ubuntu 8.04 Xen Python XML Error</title>
		<link>http://rickonrails.wordpress.com/2008/10/03/fix-ubuntu-804-xen-python-xml-error/</link>
		<comments>http://rickonrails.wordpress.com/2008/10/03/fix-ubuntu-804-xen-python-xml-error/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 14:15:28 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=63</guid>
		<description><![CDATA[So if you have Ubuntu 8.04 LTS installed with the ubuntu-xen-server packages, none of the xend management stuff will work. This is a really awesome bug, especially when everyone is screaming at you wondering why the server isn&#8217;t back up when you&#8217;re trying to install sweet virtualization everywhere. Apparently they don&#8217;t understand how much of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=63&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So if you have Ubuntu 8.04 LTS installed with the ubuntu-xen-server packages, none of the xend management stuff will work. This is a really awesome bug, especially when everyone is screaming at you wondering why the server isn&#8217;t back up when you&#8217;re trying to install sweet virtualization everywhere. Apparently they don&#8217;t understand how much of a hardon I get when I execute live migrations. Anyway, it&#8217;s not too hard to fix.</p>
<pre># apt-get install python-xml
# `echo 'oldxml' &gt; /usr/lib/python2.5/site-packages/oldxml.pth</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=63&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/10/03/fix-ubuntu-804-xen-python-xml-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>How to hack MapGuide Studio to run on 64-bit Windows</title>
		<link>http://rickonrails.wordpress.com/2008/09/24/how-to-hack-mapguide-studio-to-run-on-64-bit-windows/</link>
		<comments>http://rickonrails.wordpress.com/2008/09/24/how-to-hack-mapguide-studio-to-run-on-64-bit-windows/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 23:36:32 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=60</guid>
		<description><![CDATA[So we&#8217;ve got a bunch of GIS people with 64-bit Windows, as you&#8217;d expect. Unfortunately, Autodesk thinks supporting 64-bit Windows is unnecessary. The installer won&#8217;t let you install it, and even when you bypass that, it throws an error when you launch the program. With Studio being a .NET application and WOW64 being pretty damn [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=60&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So we&#8217;ve got a bunch of GIS people with 64-bit Windows, as you&#8217;d expect. Unfortunately, Autodesk thinks supporting 64-bit Windows is unnecessary. The installer won&#8217;t let you install it, and even when you bypass that, it throws an error when you launch the program. With Studio being a .NET application and WOW64 being pretty damn good at running things in 32-bit mode, I was pretty sure this was just some obscene laziness on their part. After some unsuccessful hacking with compatibility modes and editing the .manifest file, I landed on something that works. There&#8217;s a tool distributed with the .NET SDK (in Visual Studio) called CorFlags. This tool can be used, among other things, to set a .NET assembly to be forced to run in 32-bit mode. After getting MapGuide Studio to install by directly executing the MSI on the trial DVD, I used this command to make it run right:</p>
<p><code><br />
C:\Program Files (x86)\Autodesk\MapGuideStudio2009&gt; CorFlags Studio.exe /32BIT+<br />
</code></p>
<p>&#8230; and it works flawlessly. Yes, it&#8217;s that easy. What a bunch of douchebags.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=60&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/09/24/how-to-hack-mapguide-studio-to-run-on-64-bit-windows/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>Squid for Bandwidth Management</title>
		<link>http://rickonrails.wordpress.com/2008/09/23/squid-for-bandwidth-management/</link>
		<comments>http://rickonrails.wordpress.com/2008/09/23/squid-for-bandwidth-management/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 00:21:39 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=58</guid>
		<description><![CDATA[So I grew tired of our constantly bandwidth-strained T1. After successfully setting up bandwidth management on our SonicWall to at least make SSH and RDC usable during downloads, I was wanting to be able to still use the web while other people used YouTube or downloaded porn or whatever else the other people here do. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=58&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So I grew tired of our constantly bandwidth-strained T1. After successfully setting up bandwidth management on our SonicWall to at least make SSH and RDC usable during downloads, I was wanting to be able to still use the web while other people used YouTube or downloaded porn or whatever else the other people here do.</p>
<p>Squid, a caching proxy, came to the rescue. I&#8217;m not sure how they got the name &#8220;squid&#8221; for &#8220;caching proxy,&#8221; but regardless, it&#8217;s the only free/decent/stable proxy that would do what I needed. First I had to get all the routing setup so it&#8217;d be &#8220;transparent.&#8221; I created IP aliases on both the firewall and the proxy box that allowed me to transmit to-be-proxied traffic over a &#8220;black&#8221; network (192.168.80.x). The problem with simply just forwarding the packets to the proxy is that the proxy will try to respond to the connection directly back to the source host (instead of the firewall) which won&#8217;t have a clue what the proxy is talking about. It all has to be passed thru the NAT process to work correctly. For the individual host-throttling to work, we need the different hosts to be broken out, so just marking everything as sourced from the firewall&#8217;s IP was also out. The last 8 bits of of the client host directly map onto the black network (192.168.1.5 -&gt; 192.168.80.5). At this point the proxy box can be administered via the normal network and is listening for requests on the black network.</p>
<p>Cool. Now we&#8217;re caching and happy, but how do we do some bandwidth management? Squid delay pools are kind of a black art. It works like a bucket of bytes, where downloads take out of the bucket and a certain amount of &#8220;bytes&#8221; are added to the bucket every second. If the bucket is 0, no transmission takes place. Of course, in another second, some bytes will be added. If you set the bytes being added to the bucket every second (reserve) to 64 kilobytes and the entire bucket is 512 kilobytes, only the net difference is actually being taken out of the bucket (download speed &#8211; bucket reserve = net difference). So for a download that&#8217;s using 128 kilobytes a second, you&#8217;re only seeing 64 kilobytes being taken out of the bucket every second. That means it&#8217;ll take 6 seconds, or 1MB of data transfer, for the bucket to be empty. By this point I wanted to find the largest bucket and dunk my head in it until the pain went away.</p>
<p>To add to the complexity, you can create different buckets for the entire aggregate pool or individuals. I wish I knew more about how it all worked, but after about 3 hours of tweaking the numbers, this seemed to work pretty damn well for our T1&#8230;</p>
<p><code>delay_class 1 2<br />
delay_parameters 1 140000/160000 96000/128000<br />
delay_initial_bucket_level 100</code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/58/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/58/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/58/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=58&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/09/23/squid-for-bandwidth-management/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>A Cloudy Day</title>
		<link>http://rickonrails.wordpress.com/2008/09/19/a-cloudy-day/</link>
		<comments>http://rickonrails.wordpress.com/2008/09/19/a-cloudy-day/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 02:57:16 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[1]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=56</guid>
		<description><![CDATA[&#8230; is always some inspiration to sit down and write a blog entry. It was not only cloudy outside, but at work as well. An omen suspended in the lower atmosphere covered the building this morning as I gave a presentation that paired a move to the MapGuide product for IMS with the use of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=56&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>&#8230; is always some inspiration to sit down and write a blog entry.</p>
<p>It was not only cloudy outside, but at work as well. An omen suspended in the lower atmosphere covered the building this morning as I gave a presentation that paired a move to the MapGuide product for IMS with the use of Amazon Web Services as a platform for our interactive mapping. I cooked up a fresh PowerPoint with some krispy graphics from Visio. I built a POC in like 2 days with MapGuide Open Source + OpenLayers and the AutoDesk Studio product running on my workstation. Showed this as well as the Studio GUI product. An hour and a half later all the haters were at bay and the boss had bug eyes. It used to be that serving up hits off our IMS servers were the costly part of hosting maps, but with MapGuide + AWS, our plans should reduce it to something like a tenth of the cost of the data licensing.</p>
<p>I&#8217;ve now got an AWS account on the company card and I&#8217;m giddy like a schoolgirl to mess with all of these little cute doo-dads. Seriously, how could you ask for more of a toy as a developer? I am such a sucker for this stuff. I think over the last week I&#8217;ve turned down sex to dream of the cloud. Geeked out in the worst way.</p>
<p>The MapGuide Open Source product is good, but it could definitely use some work just to get everything fleshed out. They&#8217;re sort of in the phase between taking a &#8220;fair&#8221; commercial product and turning into an &#8220;excellent&#8221; open source project. I&#8217;m really hoping I can carve out some time to start contributing patches. I just hope AutoDesk&#8217;s product can keep up with the fury of an open source project OR the alternative Maestro GUI gets good. With all of my forced .NET slavery, I might just lend a hand with Maestro since it&#8217;ll be a good place to start. We&#8217;ll see.</p>
<p>OpenLayers, is, of course, amazing. I&#8217;ve been trying to find it a place here since last year.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=56&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/09/19/a-cloudy-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
		<item>
		<title>OpenLayers + MapGuide without logging in&#8230;</title>
		<link>http://rickonrails.wordpress.com/2008/09/17/openlayers-mapguide-without-logging-in/</link>
		<comments>http://rickonrails.wordpress.com/2008/09/17/openlayers-mapguide-without-logging-in/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 00:55:28 +0000</pubDate>
		<dc:creator>rbranson</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://rickonrails.wordpress.com/?p=53</guid>
		<description><![CDATA[This snippet of code before you instantiate your MapGuide layer gets rid of the pesky login&#8230; OpenLayers.Layer.MapGuide.prototype.TILE_PARAMS.USERNAME = "Anonymous"; Not beautiful, but works.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=53&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This snippet of code before you instantiate your MapGuide layer gets rid of the pesky login&#8230;</p>
<p><code>OpenLayers.Layer.MapGuide.prototype.TILE_PARAMS.USERNAME = "Anonymous";</code></p>
<p>Not beautiful, but works.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/rickonrails.wordpress.com/53/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/rickonrails.wordpress.com/53/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rickonrails.wordpress.com/53/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rickonrails.wordpress.com/53/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rickonrails.wordpress.com/53/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rickonrails.wordpress.com&amp;blog=1048090&amp;post=53&amp;subd=rickonrails&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rickonrails.wordpress.com/2008/09/17/openlayers-mapguide-without-logging-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1a0183b26287dd6caf49a9d2bf4f798a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rbranson</media:title>
		</media:content>
	</item>
	</channel>
</rss>
