<?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>Red Leopard &#187; flex</title>
	<atom:link href="http://www.redleopard.com/tag/flex/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.redleopard.com</link>
	<description>A Stranger in a Strange Land</description>
	<lastBuildDate>Mon, 07 Jun 2010 22:59:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Actionscript GZIP Alternative</title>
		<link>http://www.redleopard.com/2008/12/actionscript-gzip-alternative/</link>
		<comments>http://www.redleopard.com/2008/12/actionscript-gzip-alternative/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 00:08:57 +0000</pubDate>
		<dc:creator>kelly</dc:creator>
				<category><![CDATA[KellyBlog]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.redleopard.com/?p=126</guid>
		<description><![CDATA[I really wish Actionscript 3 had a native decompression utility for opening GZIP compressed files. I really do. After reading (and trying to implement the advice of) numerous postings, I gave up on GZIP.
In my investigation, I walked byte-by-byte through numerous binary dumps. Somewhere along the way I noticed a pattern. Forget about the head [...]]]></description>
			<content:encoded><![CDATA[<p>I really wish Actionscript 3 had a native decompression utility for opening GZIP compressed files. I really do. After reading (and trying to implement the advice of) numerous postings, I gave up on GZIP.</p>
<p>In my investigation, I walked byte-by-byte through numerous binary dumps. Somewhere along the way I noticed a pattern. Forget about the head and foot bytes, the basic GZIP compressed data is simply not the same as the actionscript base deflate-algorithm compressed data.</p>
<p>People argue with me on that one. They say the compressed bytes are simply deflate-algorithm compressed and that these bytes can be decompressed by actionscript. I have but one comment. &#8220;Good luck with that, Cowboy. Knock yourself out.&#8221;</p>
<p>I have working code in production. Who you gonna believe?</p>
<p>I&#8217;ll start with the flex side first (flex3, as3). Use a URLLoader and set the dataFormat to BINARY or <em>it will not work</em>. Since the source data is not GZIP, I&#8217;ve made up a new file extension &#8216;xmlz&#8217;. </p>
<p>The code in listing 1 fetches the compressed XML, decompresses it and dumps it in a TextArea.</p>
<p>Listing 1. Simple Flex app to load compressed XML</p>
<div class="terminal">
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    backgroundGradientColors="[#ffffff, #c0c0c0]"
    width="100%"
    height="100%"&gt;

  &lt;mx:Script&gt;
  &lt;![CDATA[
    import flash.utils.ByteArray;

    [Bindable]
    private var bytes:String = "";

    private var loader:URLLoader = new URLLoader();

    private function urlLoaderSend():void
    {
      loader.addEventListener(Event.COMPLETE, setResult);
      loader.dataFormat = URLLoaderDataFormat.BINARY;
      loader.load(new URLRequest("http://example.com/data.xmlz"));
    }

    private function setResult(event:Event):void
    {
      var ba:ByteArray = loader.data as ByteArray;
      ba.position = 0;
      ba.uncompress();
      bytes = ba.toString();
    }
  ]]&gt;
  &lt;/mx:Script&gt;

  &lt;mx:Button
      label="get playlist"
      click="urlLoaderSend()" /&gt;
  &lt;mx:TextArea
      id="resultTA"
      width="600"
      height="600"
      text="{bytes}" /&gt;
&lt;/mx:Application&gt;
</pre>
</div>
<p>The server-side java is quite simple. I use the StAX XMLStreamWriter to generate XML. The writer&#8217;s constructor takes an OutputStream as an argument. Simply wrap the original OutputStream in a DeflaterOutputStream. The trick is to explicitly create the Deflater. If you don&#8217;t, the default will produce bytes incompatible with actionscript&#8217;s uncompress().</p>
<p>Listing 2. Java DeflaterOutputStream fragment (with StAX writer)</p>
<div class="terminal">
<pre>
OutputStream out = new OutputStream();
    ⋮

Deflater d = new Deflater(Deflater.BEST_COMPRESSION, false);
OutputStream zipper = new DeflaterOutputStream(out, d);

XMLOutputFactory factory = XMLOutputFactory.newInstance();

XMLStreamWriter writer;
writer = factory.createXMLStreamWriter(zipper, "utf-8");
    ⋮
</pre>
</div>
<p>And that&#8217;s it! The compression is size-equivalent with GZIP (within a few bytes). I would rather actionscript supported GZIP. Until it does, I&#8217;ll continue using &#8216;xmlz&#8217;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.redleopard.com/2008/12/actionscript-gzip-alternative/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flexible Web Services</title>
		<link>http://www.redleopard.com/2008/09/flexible-web-services/</link>
		<comments>http://www.redleopard.com/2008/09/flexible-web-services/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 22:00:15 +0000</pubDate>
		<dc:creator>kelly</dc:creator>
				<category><![CDATA[KellyBlog]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://www.redleopard.site/?p=107</guid>
		<description><![CDATA[Things don&#8217;t change. You change your way of looking, that&#8217;s all.
&#8211; Carlos Castañeda
Early this spring, I made some big architectural changes in the company&#8217;s website. The two most far-reaching changes involved Amazon&#8217;s Web Services and Adobe&#8217;s Flex product. Sometimes you regret big changes. I only regret having not made the changes earlier.
I admit that I [...]]]></description>
			<content:encoded><![CDATA[<p>Things don&#8217;t change. You change your way of looking, that&#8217;s all.<br />
&#8211; Carlos Castañeda</p>
<p>Early this spring, I made some big architectural changes in the company&#8217;s <a href="http://www.sonicswap.com">website</a>. The two most far-reaching changes involved Amazon&#8217;s Web Services and Adobe&#8217;s Flex product. Sometimes you regret big changes. I only regret having not made the changes earlier.</p>
<p>I admit that I wasn&#8217;t always a flex fan. Indeed, I dismissed the flex out of hand in the early days mainly as a response to Macromedia&#8217;s steep pricing model. Ouch. Since then, Adobe had bought Macromedia and the pricing model changed several times. I never noticed. Such is the cost of writing something off.</p>
<p><img width="150" height="188" style="float: left; margin: 0 0.5em 0.5ex 0; border: 1px solid black;" alt="Flexible Rails book cover" src="http://www.redleopard.com/images/flexiblerails-cover.jpg" /></p>
<p>Then I saw Peter Armstrong&#8217;s <a href="http://www.sdforum.org/_data/global/images/SDF_Images/events/ruby/Armstrong%20SDForum_Presentation">presentation</a> at the <a href="http://www.sdforum.org/index.cfm?fuseaction=Page.ViewPage&#038;PageID=853">Third Annual Silicon Valley Ruby Conference</a> (April 18-19, 2008). Turns out, flex is now free. (uhhhmmm, ok. you will want to buy the developer ide but it&#8217;s possible to use the free command line compiler.)</p>
<p>I bought Armstrong&#8217;s <a href="http://manning.com/armstrong/">book</a> and started working through the tutorials. By the time I finished Chapter 6, I knew that I was going to change our webapp from a javascript-driven front-end to an flex-based, actionscript-driven front-end. We deal with a <em>lot</em> of tabulated data. Over a million sets and growing. Some of the datasets are small and some are quite large. Furthermore, each row had numerous event listeners attached. We had plans to add more, add mashups, add slicky bells and wistles. The larger tables were dozens of megabytes large. Which isn&#8217;t a problem in and of itself except that&#8230;</p>
<p>Javascript sucks.</p>
<p>Well, not really. It&#8217;s the browser&#8217;s that suck. All of them. We had to back off functionality just to get IE to render. Firefox&#8217;s javascript+dom engine (including ff3) would render the tables (if it didn&#8217;t crash) but not all the event listeners worked. Safari (web-kit) would render and all events worked but then Apple released the 5-second script warning. We schemed endlessly on how to break the problem up. Mostly we hoped one of the miracle javascript libraries would solve these problems. We knew it was unlikely but we hoped.</p>
<p>I made some side-by-side comparisons on my MacBookPro and actionscript beat javascript hands down. Orders of magnitude faster to load and render. Less code. Consistency between browsers. And finally, actionscript/flex worked. And worked well.</p>
<p>What didn&#8217;t work well was our MySQL database. Our million datasets occupied hundreds of millions of database rows in scads of tables and hundreds of gigabytes of disk space. A 3ware RAID10 disk subsystem with master/slave configuration was in complete IO overload <em>all the time</em>. I had Matt from <a href="http://www.mysql.com/consulting/">mysql</a> come in to help us unravel our mess. This guy was good. He identified, explained, documented and proposed a prioritized list of solutions.</p>
<p>But I started thinking, why the hell do we even store the datasets in MySQL in the first place? The only time we ever change a dataset is when we replace it. The relational database solution had always been a problem and was getting worse by the day. Thinking like a mathematician, I decided to solve a different problem. Why not just save the datasets in flatfiles and overwrite them when they change? Just store them in flatfiles. Like pictures.</p>
<p>Of course, every solution brings its own problems. And storing a million flatfiles has its problem: you cannot store a million files in a single directory (not on Centos+ext3 you cannot). I recalled reading about mogileFS some time back. It presented what looked like a flat directory in which you could store millions of files in a single directory, distributed the save over multiple machines with redundancy, and so on. Looking at that solution lead me to smugFS. And to <a href="http://blogs.smugmug.com/don/2007/03/30/etech-2007-smugmug-amazon-slides-are-up/">Don MacAskill&#8217;s</a> presentation on <a href="http://blogs.smugmug.com/don/files/ETech-SmugMug-Amazon-2007.pdf">Scalability</a>. Crap! I said. I don&#8217;t need to host the flatfile&#8217;s at our colocation center. I&#8217;ll put them on <a href="http://www.amazon.com/S3-AWS-home-page-Money/b/ref=sc_fe_l_2/103-0195969-2128613?ie=UTF8&#038;node=16427261&#038;no=3435361&#038;me=A36L942TSJ2AJA">Amazon S3</a>. And While I&#8217;m at it, I&#8217;ll build a RESTful API on <a href="http://www.amazon.com/EC2-AWS-Service-Pricing/b/ref=sc_fe_l_2/103-0195969-2128613?ie=UTF8&#038;node=201590011&#038;no=3435361&#038;me=A36L942TSJ2AJA">Amazon EC2</a> to import the datasets.</p>
<p>And my team has done it. We have completed the move to EC2/S3 and Flex. I couldn&#8217;t be happier. Armstrong&#8217;s book, <em>Flexible Rails</em>, lit the spark for our migration to <em>Flexible Web Services</em>.</p>
<p>I will write about some of the hurdles we&#8217;ve overcome in future posts. Some of the things we&#8217;ve solved are (i) building an EC2 image from scratch, (ii) compressing flat files in a format which actionscripts&#8217; ByteArray can uncompress, (iii) using the struts2 REST plugin, (iv) XML parsing using StAX.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.redleopard.com/2008/09/flexible-web-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
