9/11/2009

What if HTML wasn't Top Dog?

What if HTML wasn't the top node in our web pages? Sounds strange right? But, what if it was just another node inside a larger structure? HTML is great for defining textual documents where you want page flow layout as your choice. However, it really is painful to use a general purpose UI layout language. Which I would argue is the more common practice these days. Even the simplest blogs, forums, or search pages have some form of application layout involved. Why is it so hard with HTML? Lots of that derives from page flow layout and legacy support of this concept. But, if we embed HTML in a larger structure we could do whatever we wanted.

What sucks most about HTML? I would argue it's all the time I waste trying to get the layout I wanted. All the time I spent learning CSS and HTML 4 was probably 6 months or more before I felt comfortable with it. I could come close to the layout I had in my mind. However, as soon as I switched browsers my beautiful layout went to crap, and I had to dig into arcane browser hacks to make it work. Who enjoys that?

How much of that is the complexity of CSS rules and HTML? Ever tried or thought about creating a browser? It's NOT easy. I find understanding the interaction between CSS and HTML arcane as a web designer. If I find it hard then it's really hard for the browser developer to get it right. And that's precisely what we've seen. Lots of inconsistency in how they interpret the meaning of things. Leading to browser inconsistencies. If it's simple to understand then it's simple to implement. If it's simple to implement it's easier for two people to come to a common expectation.

Let's get specific. Say I wanted my node to be position relative to it's parent. I want to set the top left corner of an element to be 50 pixels from the left and 50 pixels from the top. In HTML I can set the left and right of my component, but I also have to set the layout to absolute on the child, and set the parent to relative. This is a common practice in other UI toolkits, but it's complex in HTML. What if all I did was this:


<application>
<box top="50" left="50" width="200" height="200"></box>
</application>


Pretty simple right? Although this isn't that far from HTML/CSS, there are other things that aren't so easy. What if I wanted to horizontally align that box relative to the parent's center.


<application>
<box width="800" height="600" horizontalCenter="0"></box>
</application>


Simple. HTML/CSS you would use margin: auto? WTF!? Doesn't horizontalCenter make more sense? Of course it does. Try vertical centering on for size:


<application>
<box width="800" height="600" verticalCenter="0"></box>
</application>


Try that with HTML and you'll come up short or at best bizarre.

What about defining boxes that grow when the window is changed? That can easy too:


<application>
<box id="banner" left="0" right="0" top="0" height="50"></box>
<box id="leftmenubar" left="0" width="250" top="50" bottom="0"></box>
<box id="content" left="250" right="0" top="50" bottom="0"></box>
</application>


Simple. The content area sets his left and right relative to the parent's edges. When the parent grows so does the child. The banner and leftmenubar are fixed in position. However, the banner grows its width as the parent's width grows.

Even supporting legacy HTML documents could be simple.


<application>
<box width="800" height="600" horizontalCenter="0" verticalCenter="0">
<HTML width="100%" height="100%">
</HTML>
</box>
</application>


HTML just becomes another possible node within the super document. It would create yet another box that can display text documents using what you want for text documents which is page flow layout. HTML nodes could occur as many times as we need in our over all application.

Furthermore, legacy HTML documents (e.g. those starting with HTML) could be converted into our application tag just by surrounding the application tag around the legacy HTML only document. Hence making all HTML documents forward compatible with application documents.

It's a simple idea to fix the constant layout problems with the web.

9/03/2009

On the Importance of being Synchronous: Asynchronous + Actionscript

Dealing with Asynchronous Events Part-2

Damn Blogspot sucks. What the hell? Why haven't they added the 1st new feature in like 5 years? Trackbacks hello???? WTF? I'm not up for cobbling a solution together with greasemonkey, yada, yada, yada. I need a new blog platform. Enough about that let's get to code.

Anyway I wanted to add my fuel to the fire on asynchronous programming. This is a topic I'm very interested in because Actionscript isn't the only language suffering from this. It's very much rooted in classic Computer Science so it's a deep topic. That blog post is old, but it's still something that doesn't have a satisfactory answer yet. Computer scientists have been discussing this topic since the 1970s in one form or another.

I'm very satisfied with my solution to the single request problem. By that I mean making a single round trip to the server and back. Here is roughly how I do asynchronous calls in actionscript.


var tag : String = "Archive";
var loader : URLLoader = defaultLoader();
loader.addEventListener( Event.COMPLETE, function( event : Event ) : void {
var json : Object = JSON.decode(loader.data);
var mail : Array = json.map( funcion( json : Object, index : int, arr : Array ) : Email {
return new Email( json )
} );
var event : DynamicEvent = new DynamicEvent('mail.loaded');
event.mail = mail;
dispatch( event );
} );
loader.load( session.httpGet( '/home/email/', { tag: tag } ) );


Really tight code, and it doesn't feel like the infrastructure for doing the calls are in the way of understanding what's going on. Now I'm using several factory methods to encapsulate common error handling, host name, authentication tokens, etc. Of course all of this can be overridden, but having defaults keeps that code out of the flow of how you work.

The difficult part comes when you need synchronous flow control over asynchronous calls. This only starts to show up with more than one trip to the server. Say for example, server call 1 must complete before server call 2. You can chain them like so:


var loader : URLLoader = defaultLoader();
loader.addEventListener( Event.COMPLETE, function( event : Event ) : void {
var json1 : Object = JSON.decode(loader.data);

// do something with json1

var nextLoader : URLLoader = defaultLoader();
loader.addEventListener( Event.COMPLETE, function( event : Event ) : void {
var json2 : Object = JSON.decode( nextLoader.data );

// do something else with json2, and maybe json1

});
loader.load( session.httpPost( '/home/update', { arg1: json1.arg1 } ) );
} );
loader.load( session.httpGet( '/home/synchronize/', { hashkey: hashkey } ) );


It's doable, but it's getting messy. And quite frankly a little hard to understand. Is that all we need? If so, then we can stop here and be ok. Sadly, no the rabbit hole can get worse and twisted. Say we want to do server call 1, server call 2, or both based on some conditions! And we want to maintain the order call 1 precedes call 2 if call 1 is done. Kinda of like:


var result : Object = null;
if( someExpression ) {
result = executeServerCall1();
}

var result2 : Object = null;
if( someOtherExpression ) {
result2 = executeServerCall2( result.arg1 );
}


Now I want to stop right here and say. Look how easy that was to specify in synchronous code. Jr. programmers can understand that code. All things like conditional logic, control flow, data flow, and more importantly re-usability are all effortless. Just doing simple control flow between asynchronous code is a real challenge.

One thing that I really have trouble with is refactoring logic into a re-usable method that I can call from multiple locations. In synchronous land I can wrap behavior around it doing logic before and after that method. I can easily pass data between in and out. All of these properties lead to reuse and powerful constructs for hiding details. The basis of easy to follow and maintain algorithms.

Adding logic before and after is very hard when the method uses asynchronous calls. I've decided that adding callback objects into the calls it the best route. For example,


public function updateUser( user : User, callback : Function ) : void {
var loader : URLLoader = defaultLoader();
loader.addEventListener( Event.COMPLETE, function( event : Event ) : void {
var json : Object = JSON.decode(loader.data);
var user : User = new User( json );
callback( user );
});
loader.load( session.httpPost( '/user/update/', { id: user.id, email: user.email } ) );
}


I prefer callbacks to using event listener. The main reason for that is event listeners are more long living, i.e. longer than a single method call. If you use event listeners you have to register and unregister between calls, i.e. more mess. If this method is apart of a longer living instance, as I typically do, you could get more than one callback happening. Callbacks are isolated between method calls so they can independent from one another. (There's a lot to discuss here too, but I'll save that for later).

I'm working on my next evolution of this idea to try and build up an architecture to help aid in making multiple round trips to the server in order without adding fuss, and hopefully allowing an outside person to read my code without needing a lobotomy to put my brain in their head. We will have to step away from our friend closure for this to work. But, I want to leave you with this thought.

All of the tools we use today are aided by synchronous control flow. When we remove synchronous flow our tools fall apart. We have very little tools at our disposal to help specify complex flow using asynchronous semantics. Closures are about it, but they aren't enough and fall apart quickly. We need new constructs that aid in asynchronous control flow. Possibly a way to restore synchronous flow, but asynchronous underneath. If we had these constructs we could do this type of work independent from things we typically think of like threads, processes, message passing, etc. Those constructs could be underneath it, but we as programmers would be less involved with their presence.

5/21/2009

Agile Methods are Disruptive

Now I might actually start a fight with that title, but at least it got you here. I recently just finished reading the "Inventor's Dilemma" by Clayton Christensen. It's an amazing book that focuses on the difference between disruptive technologies and sustaining technologies. This distinction is important because it changes how your organization should attempt to develop and manage these types of technologies. Within the book he discusses some of the social forces at play that make developing disruptive technologies different from sustaining ones. I believe these same dynamics are at work with adopting agile development processes.

In order to understand this you have to understand the difference between what is disruptive and what is sustaining. Sustaining technologies are complimentary to existing technologies your customers use. Sustaining technologies will be easily accepted by your existing customer base. That property makes it very easy for you to develop within product line using your existing resources and process. Disruptive technologies are the opposite. They most likely won't be accepted by your customers at first and your organization will find it extremely hard to develop them in house. Christensen's argument is that disruptive technologies only work if they are spun off into a separate organization independent from your own. They must be quarantined away from the core or else your organization will kill them at all costs.

It's a fascinating phenomenon, but at the end of the book he gives hints as to why this is so. He starts talking about the three components that make up any organization: resources, processes, and values. This is where the book starts to sound more like a sociology study on business structure. He points out that resources are portable: people, assets, software, money, etc. They can be fired, hired, moved, procured, sold, bought, etc. They don't care where they are, and they can be applied anywhere you want. This the key difference between the other two because processes and values are NOT portable. It's much harder to move processes and values to between organizations. These are very important properties because without them the organization would disappear. Remember resources move in and out of an organization but it's these processes and values that stay behind and keep it alive. This also means that changing these processes and values is next to impossible. Why? Well because they are what define the organization if you change them then the organization dies, and a new one comes into being.

This got me thinking about agile environments and how they try to affect the later two components. Agile is a process, but mainly targeted at software development. And with it comes a certain set of values you must adopt or else you're going to find it very hard to follow the process. If you don't accept the idea that high levels of communication and collaboration are much better than comprehensive documentation then you'll find agile methods very hostile.

The other day a group of developers were all talking about agile development. Eventually we drifted towards the difficultly we were all having trying to convert an organization into an agile one. Almost all of us felt like it was somewhere between limited success to impossible. It finally hit me. We're trying to do the exact thing Christensen says you can't do. Change a company's process AND values! Not so much a company, but a development team which like a company has processes and values.

We all had anecdotal evidence of a lack of success in doing so. In fact of all the organizations I know that have successfully adopted agile development were green field starts, or they were able to convert everyone in their organization to it all at once. This normally meant small shops or isolated teams. And, in fact my only successful attempt was when I was on a team that was separate from the rest of the development organization that had virtually no dependencies on non-agile groups. My other attempts were very large groups, or groups that had lots of dependencies on other non-agile groups. No surprise those all failed to reap the benefits of agile development.

Why do groups with dependencies fail? It seemed obvious at the time, but I think another idea Christiansen mentions is to blame. And, that is Resource Dependence Theory. In the book Christiansen explains a theory of management that says something like the following. Employees (e.g. CEO, the board, VPs, managers, etc) aren't in control of the decisions in a company. The customers they serve are. I would actually add to this that it's not just the customers, but suppliers, partners, etc. For example, think of the car dealers for GM and how they have crippled GM's ability to cut costs by closing dealerships through the years. The CEO could do nothing to change this until they almost went bankrupt. That's how entrenched customers can make an organization.

This same idea of resource dependence comes into play with agile teams. If you have a lot of dependency between you another team then you will find it increasingly difficult to be agile yourself. Why? Just like company heads aren't in charge of their companies you aren't in charge of your group.

Just like when you develop a new disruptive technology you can't stop at the product development teams. You have to break everything off: sales, marketing, etc. Agile is much the same as it requires you to adopt a new set of processes and values in how you build your products.

Agile processes' values are in conflict with traditional development values. For one, agile can't predict what will be in the release and when it will be done. It can only predict one or the other, but not both. Traditional development thinks it can do both, but really it can't. However, this points out a key difference in values between the two. Traditional shops like both pieces, or they like the idea that they might know both pieces. Traditional development believes you can reliably predict outcomes and plan for long term success. Agile shops believe predictions are unreliable and reject the idea of long term planning in terms of project management. Traditional shops call for loads of documentation and check points. Agile groups reject documentation as wasteful and unproductive in favor of collaboration and high level of communication. These differences in values makes traditional shops find reasons to reject agile, or at best neuter it into submission.

I remember one such conversation that illuminated how ferocious this difference in values can be. We were in a meeting trying to explain agile development practices work. It turned into a huge argument with one of the vice presidents about why agile practices would never work for product development. He fixated on the lack of "robust" agile procedures. He claimed that they might work in the consulting world, but don't apply to product development because product development need more "robust" procedures. His main evidence was this problem of predictability. Agile development could not predict both features and delivery schedule. The VP insisted agile development would not deliver quality software that a product company needs. In many ways it sounded exactly like an existing customer might come after a disruptive technology. Disruptive technologies typically don't have the same level of performance the entrenched technology does at first. The VP was making an argument over quality much in the same way Christensen says existing customers will make over disruptive technologies. Disruptive technologies, at first, don't perform as well, scale as well, or meet the high end needs of the existing customer base. So they usually find their foothold in smaller markets with lower margins. The incumbents are often all to happy to let the disruptive technology provider enter them because they don't make much money from these lower level markets anyway. I think it's interesting how agile development found it's foothold in consulting and small teams first.

If you want to succeed with agile development in your organization don't try and change your existing development process into an agile one. It won't work or if you are able to do it it will be a very frustrating and tiresome process. Better is to start an agile organization. Separate them from other non-agile groups, give them autonomy to affect the processes outside your development organization. Don't see agile as just something your engineers do.

3/12/2009

GridGain, GigaSpaces, Windows HPC on EC2

For those of you interested in grid computing I found an older, but great post about scalability of ec2 for grid based applications. The thing that caught my eye was the final test using Windows HPC and Velocity. The tests were not comparable to each other, but the final test shows how much degradation you suffer when you're data is stored away from your computations. In there tests 31x reduction in performance when your data is stored "out of the cloud". I think this really shows the importance for good redundant storage at the point of computation.

http://highscalability.com/your-cloud-scalable-you-think-it

The good news is for GridGain is the near linear scalability up to 512 nodes in pure CPU tests. Not as high as 2000 nodes for Hadoop, but that's the only real numbers I've seen anywhere on it. Does hint that GridGain's network overhead is really pretty light.

Grid Computing: Intro To GridGain Talk is Online

I finally got some time to put up the slides, and source code for my talk I gave at the Devnexus conference in Atlanta. Here is the link to the slides, and the source code is here.

2/21/2009

Actionscript and Concurrency (III of III)

In the previous article we covered techniques for breaking up our long running job, but the performance was 40x slower than if we just ran our algorithm straight out. The problem is our algorithm spends very little time doing work, and a lot of time waiting for the next frame. Actionscript's performance is really quite high. We need to increase the time spent running our algorithm and minimize the time we spend doing nothing. We can do that by doing many iterations per frame instead of just one. Using getTimer() we measure how much time we spent looping and back off right before the next frame. Let's look at the code:


public function start() : void {
Application.application.addEventListener( Event.FRAME_ENTER, onCycle );
}

private function onCycle( event : Event ) : void {
var cycle : Boolean = true;
var start : Number = getTimer();
var milliseconds = 1000 / Application.application.stage.frameRate - DELTA;
while( cycle && (getTimer() - start) < milliseconds ) {
cycle = doLongWork();
}

if( cycle == false ) {
Application.application.removeEventListener( Event.FRAME_ENTER, doLongWork );
}
}

public function doLongWork() : Boolean {
// do some work
i++;
return i < total;
}


Now we broken up our algorithm into an extra method. First the start() method which we're already seen. The new method is the onCycle which calculates how long a frame is in milliseconds. The loop continues until either the doLongWork method returns false, or we run out of time. Notice the DELTA constant is some constant that keeps us from eating up the entire frame. We need to give a little breathing room for Flash to drain the queue. Notice how our doLongWork method is just the code pertaining to our job. This makes it's easier to build a general purpose solution that we can reuse.

Green Threads


We can't use true OS threads in Actionscript, but any language can emulate threads. This technique is often called Green Threads. Lots of languages have used this in the past. Threads in Ruby are still green, and early versions of Java were green as well. Now Actionscript can too. I should pause and give credit to Drew Cummins who implemented a version of this for Flash player 10. I've rewritten this to remove the dependency of Flash 10, and changed some of the API so event dispatch is more natural, added easy progress events, and optional progress tracking. Let's see how our Mandelbrot algorithm changes when we use this.

In order to use GreenThreads create a subclass of GreenThread, override run method, and optionally override initialize method to add code that runs at the start. Here is an example:


public class Mandelbrot extends GreenThread {
private var _bitmap : BitmapData;
private var _maxIteration : uint = 100;
private var _realMin : Number = -2.0;
private var _realMax : Number = 1.0;
private var _imaginaryMin : Number = -1.0;
private var _imaginaryMax : Number = 1.0;
private var _shader : Shader;

private var _realStep : Number;
private var _imaginaryStep : Number;
private var screenx : int = 0;
private var screeny : int = 0;

override protected function initialize( ) : void {
_bitmap = new BitmapData( width, height, false, 0x020202 );
screenx = screeny = 0;
_realStep = (_realMax - _realMin) / Number(_bitmap.width);
_imaginaryStep = ( _imaginaryMax - _imaginaryMin ) / Number( _bitmap.height );
}

override protected function run():Boolean {
if( screenx > _bitmap.width ) {
screenx = 0;
screeny++;
}
if( screeny < _bitmap.height ) {
var x : Number = screenx * _realStep + _realMin;
var y : Number = screeny * _imaginaryStep + _imaginaryMin;
var x0 : Number = x;
var y0 : Number = y;
var iteration : int = 0;
while( x * x + y * y <= (2 * 2) && iteration < _maxIteration ) {
var xtemp : Number = x * x - y * y + x0;
y = 2 * x * y + y0;
x = xtemp;
iteration = iteration + 1;
}

if( iteration == _maxIteration ) {
_bitmap.setPixel( screenx, screeny, 0x000000 );
} else {
_bitmap.setPixel( screenx, screeny, shader.lookup( Number(iteration) / Number(maxIteration) ) );
}
screenx++;
return true;
} else {
return false;
}
}
}


The run() method is the body our of loop. The intialize() method is called once after the user calls the start() method. After that run() method is called repeatedly until it returns false. It's perfectly acceptable to call start() more than once to kick off the thread again after it's finished. That means you can calculate the Mandelbrot set from different zoom levels without needing to recreate new instances. The initialize() method will be called every time start() is called. Check out the results here.

You can also add optional progress tracking by setting maximum, and progress members. This will automatically dispatch ProgressEvents so that your instance can be a source to a ProgressBar. It makes tracking your job easy. GreenThread also subclasses EventDispatcher so you can dispatch events from within the run method.

By in large we've solved the performance problems or we've gotten very close. What's holding us back is the resolution of getTimer(). Since we only have precision of millisecond we really can't run the risk of going smaller than 1 millisecond for our DELTA. That costs us a few iterations on our run() method which can make a difference over 1000 cycles. We could be a full second behind Actionscript that just ran the job straight through. There are a few things we can do to squeeze a little more performance out of GreenThreads.

Frame rate governs everything we do, and by default Flex applications run at 24 frames/s, but really most Flex applications don't do that much animation so if we dropped the frame rate in half to 12 frames/s we would be able to run for longer periods uninterrupted. The fewer interruptions we have, the faster we'll go.

GreenThreads also allows you to configure how much of the frame's time you dedicate to running your thread. By default it's set at 0.99 that roughly leaves 1 ms to update the UI. Under some experimentation this has proven to work quite well without creating lots of timeouts, but if you want to tweak it just provide a new value in the start method like so:


public function go() : void {
start( 0.5 );
}


If the delta is less than 1 then it means a percentage of the length of a frame. If it's >=1 then it means the number of milliseconds to subtract from the length of a frame. Some more thought needs to go into this so that as you run your application on different machines with different CPUs so the pause is appropriate for the CPU. In the future it might need to be dynamically adjusted as the algorithm runs.

Thread Statistics


GreenThreads supports runtime statistics for tracking your job. To turn on thread statistics pass true to the GreenThread constructor. Thread statistics collects total time the job took, number of timeouts, min and max iteration times, average time a single iteration took, how many cycles it took, etc. There is a fair amount of information that can be gathered to help tune your thread. You can access that information by doing the following:


public class SomeJob extends GreenThread {

public function SomeJob() {
super( true ); // turn on debug statisitics

addEventListener( Event.COMPLETE, function( event : Event ) : void {
trace( statistics.print() );
});
}
}


Conclusion


There are some drawbacks to doing concurrency this way. One is algorithm have to be cooperative, and stop processing in the middle to let Flash do its thing. That means your algorithm normally have to be rewritten to conform with this approach. That can be particularly difficult for recursive algorithms. There needs to be more research done into how you might fix this with the callLater() technique. The biggest draw back is that we cannot take advantage of multi-processors. For all the code you write Flash runs on a single OS thread. This is a serious disadvantage for us going forward because as Actionscript developers we cannot access boosts in hardware performance as cores are added.

It's been a lot of information but hopefully you now understand the theory behind concurrency in Actionscript, and you have a new library that helps you optimize your code. You can access the source code here, and download the GreenThread's library here. I look forward to hearing about what sorts of long running jobs you create.

Full source code of the Mandelbrot set is here.

Download GreenThread's library here.

2/19/2009

Actionscript and Concurrency (II of III)

Now that we understand more about how Flash works internally we can begin to talk about strategies to chop up our large running job into smaller pieces. We'll render the Mandelbrot set. It's a time consuming algorithm, and it's fun when your demos make pretty pictures too. Let's look at a simple implementation.


public function calculate( width : int, height : int ) : void {
_bitmap = new BitmapData( width, height, false, 0x020202 );

var realStep : Number = (_realMax - _realMin) / Number(_bitmap.width);
var imaginaryStep : Number = ( _imaginaryMax - _imaginaryMin ) / Number( _bitmap.height );

for( var screeny : int = 0; screeny < _bitmap.height; screeny++ ) {
for( var screenx : int = 0; screenx < _bitmap.width; screenx++ ) {
var x : Number = screenx * realStep + _realMin;
var y : Number = screeny * imaginaryStep + _imaginaryMin;
var x0 : Number = x;
var y0 : Number = y;
var iteration : int = 0;
while( x * x + y * y <= (2 * 2) && iteration < _maxIteration ) {
var xtemp : Number = x * x - y * y + x0;
y = 2 * x * y + y0;
x = xtemp;
iteration = iteration + 1;
}

if( iteration == _maxIteration ) {
_bitmap.setPixel( screenx, screeny, 0x000000 );
} else {
_bitmap.setPixel( screenx, screeny, shader.lookup( Number(iteration) / Number(maxIteration) ) );
}
}
}
var evt : Event = new Event( Event.COMPLETE );
dispatchEvent( evt );
}


Click here to see it in action. Notice how there was a pause before it actually drew the Mandelbrot set. Maybe you got the pinwheel of death or not responding. That is what happens when you hold up the Event Queue.

At a high level this algorithm calculates whether or not a pixel at (screenx,screeny) is inside the Mandelbrot set (i.e. stays below 4). If it stays below 4 after maxIterations of the loop then it colors the pixel black. If not it's color is based on how many times the inner while loop ran before going past 4. It's not as important you understand what the algorithm is doing as so much the parts of the algorithm. The parts that make this a long job are the three loops inside.

Breaking Apart Algorithms


In order to split this job up and run across many frames we'll need to break up those top two loops. Before we jump into that let's talk in a little more general terms. Say we want to bust up a general purpose loop something like:


public function doLongWork( arg1 : String ) : void {
for( var i : int = 0; i < 1000000; i++ ) {
// do some work
}
}


callLater() Technique


We could use the UIComponent.callLater() method to trigger our loop that might look like the following:


public function doLongWork( arg1 : String, i : int, total : int ) : void {
// do work
if( i < total ) {
uicomponent.callLater( doLongWork, [ arg1, i + 1, total ] );
}
}


This is nice. We've removed the for loop and replaced it with what looks like a recursive call, but it's not. Actually what we're doing is doing a single iteration of the loop, and then scheduling the Event Queue to call us back later to do the next iteration of our loop. We do this until i == total, and that point we stop.

Timer Technique


Another way we could restructure our code is to us a timer. Here is another way to do this:


public function start() : void {
i = 0; total = 1000000;
var milliseconds = 1000 / Application.application.stage.frameRate;
_runner = new Timer( milliseconds );
_runner.addEventListener( TimerEvent.TIMER, doLongWork );
}

public function doLongWork() : void {
// do some work
i++;
if( i >= total ) {
_runner.stop();
_runner.removeEventListener( TimerEvent.TIMER, doLongWork );
}
}


A little more code, but this works too. Now we're scheduling a timer to call us at an interval of a single frame. That's the first line where we calculate in milliseconds the length of a single frame. Then we register our doLongWork method to get called back by the timer. We then remove the listener and stop the timer once i reaches total. Notice that in this method we have to move i and total into instance variables which means we have to initialize those in some sort of start method.

FRAME_ENTER Technique


The final option we could use is FRAME_ENTER event. That looks like this:


public function start() : void {
i = 0; total = 1000000;
Application.application.addEventListener( Event.FRAME_ENTER, doLongWork );
}

public function doLongWork( event : Event ) : void {
// do some work
i++;
if( i >= total ) {
Application.application.removeEventListener( Event.FRAME_ENTER, doLongWork );
}
}


This is nice because we don't have to fiddle with math in order to call us back at the frame rate. We just register a listener, when we're done we unregister our listener. Not as clean as callLater, but this works in both Flash and Flex. What's important to remember is that all of these techniques are equivalent. There is no discernible difference in performance between them.

Restructuring Our Demo


So now we can restructure our Mandelbrot algorithm to match one of these patterns. In our case we'll move screenx, screeny, _realStep, _imaginaryStep, and our BitmapData outside of our calculate() method, and put them inside calculateAsync(). Here's our Mandelbrot algorithm restructured:


public function calculateAsync( width : int, height : int ) : void {
_bitmap = new BitmapData( width, height, false, 0x020202 );
screenx = screeny = 0;
_realStep = (_realMax - _realMin) / Number(_bitmap.width);
_imaginaryStep = ( _imaginaryMax - _imaginaryMin ) / Number( _bitmap.height );
Application.application.addEventListener( Event.FRAME_ENTER, calculate );
}

private function calculate( event : Event ) : void {
if( screenx > _bitmap.width ) {
screenx = 0;
screeny++;
}
if( screeny < _bitmap.height ) {
var x : Number = screenx * _realStep + _realMin;
var y : Number = screeny * _imaginaryStep + _imaginaryMin;
var x0 : Number = x;
var y0 : Number = y;
var iteration : int = 0;
while( x * x + y * y <= (2 * 2) && iteration < _maxIteration ) {
var xtemp : Number = x * x - y * y + x0;
y = 2 * x * y + y0;
x = xtemp;
iteration = iteration + 1;
}

if( iteration == _maxIteration ) {
_bitmap.setPixel( screenx, screeny, 0x000000 );
} else {
_bitmap.setPixel( screenx, screeny, shader.lookup( Number(iteration) / Number(maxIteration) ) );
}
screenx++;
} else {
Application.application.removeEventListener( Event.FRAME_ENTER, calculate );
}
}


Now if we ran this version of it you'd see it's 40x slower! Why is that? Well we're executing a single iteration every start of a frame (~40ms). If you timed the running of the calculate method. You'd see that it probably takes less than a millisecond to complete a single iteration. So we've just take a single iteration that ran in <1ms and now we're running it in 40ms! Yikes!

Remember when I said Flash is all about animation? Running jobs at the frame rate is great for animation, but horrible for general purpose concurrency. We need a better way. So our final part we'll discuss optimizing our technique and demonstrate a general purpose solution so that you don't have recreate the wheel when you need to run jobs for long periods of time. See you in the next installment.

Actionscript and Concurrency (Part I of III)

This is a three part series from a talk I gave at the Atlanta Flex and Flash User Group meeting in February. Original slides are here.



I can hear it now Actionscript can't do that. And some of you might say what is concurrency? Concurrency goes by a lot of names, but it simply means doing two things at once. More accurately stated doing two things simultaneously. Now I can hear what you might say "But, Flash already does that? I mean I can animate two objects on the screen at once." While that's true, Flash is optimized for animation not for general purpose concurrency. In fact the design of animation is so foundational it governs everything that happens in Flash.

Timeline


If you're a Flash developer I'm sure you're familiar with the timeline. The timeline is divided into a series of frames, and Flash executes those frames at a particular rate one after the other. For flex applications the rate is 24 frames / second. If you do the math that means each frame lasts a little more than 40ms. The timeline is very natural for designers. But, for developers this concept is a little strange because it's hard to understand where my code is executed?

Event Queue


For developers I think a thought experiment helps clarify the timeline. Say you were hired to implement the timeline concept. What data structure would help you in doing this task? The answer is surprisingly simple and bears a lot of resemblance to most UI toolkits out there. At the heart of the Flash platform there exists a queue of events. The Event Queue, as it's known, is where all code is triggered. Every piece of code in Flex and Flash is related back to some event being triggered. So when you move your mouse, click a button, type on the keyboard, set timers they all go onto the queue. Flash then pops off those events from the queue and executes them one by one. When one event is done processing the next event is processed. There's no way any two events can be processed at the same time. It all happens one at a time.

Now in Flash even those frames from the timeline are modeled as events. The difference between them and other events is that frame events must occur at certain points in time. Unlike mouse or keyboard which can wait till the next frame to be processed. Frame events must be processed every ~40ms (or 1000 ms / 24).

That means if one event takes too long to process Flash can't update the screen, process other events, or doing anything. What happens is Flash locks up and you get a pinwheel of death or a Not Responding next to your application. In fact Flash punishes such acts and stops processing mouse, keyboard, or button clicks till it catches up. Why? Well that because if you block the queue from processing it won't update that nice animation, and Flash prioritizes that over anything else.

Rule number one is that any code you write must execute within the time span of a frame. If not you run the risk of having Flash coming down on you. This leads us to the second rule which is Flash is not concurrent. There is no way for Flash to update the UI and run your job at the same time.

Timeslicing


So what do you do if you have a long running job? Well the answer lies in how animation works in Flash. Animating several objects at once requires a series of many smaller steps. Say you want to move a ball from one side of the screen to the other. That means you need to move it a little, redraw, move it some more, redraw, etc until the ball is at the other side of the screen. In a way animation is chopping up a long running job into several smaller jobs that run once per frame. We can do that too by chopping up our job into many smaller jobs, and executing them a little at time until we're done!

So how might you do this? Well there are several tricks you can use, and they all perform the same. It's more a matter of taste in which one you choose, but remember technically there is no real difference between these. Our next part we'll look at each of these techniques and discuss unique problems when doing concurrent actions in Flash.

1/07/2009

Fun with Fluent Interfaces and Java

I've written about fluent interfaces before, but I thought I'd share this one I use quite a bit. You never know how much you like something until it's gone. I never thought I really liked Java's InputStream and OutputStream that much until I had to do a lot of streaming work in Actionscript. They have no abstraction for doing stream manipulations. But, let's be honest Java's io first settler's haven't changed much since their introduction. In fact their interfaces have not changed one bit. Sad really because they are so ubiquitous. I find I'm always copying data from one stream the other, dealing with IOExceptions, remembering to close streams, etc. And I got really tired of doing it over and over. What started out as static methods has evolved into a very simple object called ExtendInputStream. Extended as in extending the interface to add more rich functionality rather than the use of inheritance.

The greatest single thing about InputStream and OutputStream is that it's the quintessential example of a decorator. Decorator is one of the foundational software patterns. What I love about decorators is the ability to encapsulate related classes behind a new interface while still retaining interoperability with other decorators.

ExtendedInputStream is a InputStream so it can interact just as plain old InputStream would, but it adds methods like copy, closeQuietly, copyAndClose, and integration with File objects which has always been a pet peeve of mine with InputStream. Let's look at some examples:

Here is copying a file to a directory.


new ExtendedInputStream( someFile ).copyAndClose( dir );


One liner! It's amazing how File object doesn't have these methods already implemented, but then again this approach is much more flexible because we can copy this file to any OutputStream. Here is copying a set of files to a zip.


ZipOutputStream zout = new ZipOutputStream( out );
for( File myfile : files ) {
ZipEntry entry = new ZipEntry( myfile.getName() );
zout.putNextEntry( entry );
new ExtendedInputStream( myFile ).copyAndClose( zout );
}


Five lines of code! Not bad given that 4 of those lines is just to work with ZipOutputStream. Notice how I'm not saving the reference to the ExtendedInputStream here. The copyAndClose() method copies the contents of the file to the OutputStream and closes the InputStream. Closing the OutputStream is your responsibility.

And the more general case of copying an plain old InputStream to any OutputStream.



URLConnection remote = new URL("...").openConnection();
new ExtendedInputStream( new URL("...").openStream() ).copyAndClose( remote.openOutputStream() );


Here is a more advanced version. Say we want to pull down a URL and save it to a file on our local filesystem.


File someDirectory = ...;
new ExtendedInputStream( new URL("...").openStream() ).name( "SavedUrl.txt" ).copyAndClose( someDirectory );


Here we use the optional method name() to set the name of the stream so when we save something to a directory it will use this name as the filename. You could have just as easily done new File( someDirectory, "SaveUrl.txt" ), but it's not always convenient.

You can use a similar pattern for increasing the buffer size used when copying as well.


new ExtendedInputStream( new URL("...").openStream() ).bufferSize( 8096 * 2 ).copyAndClose( someDir );


While I have enjoyed writing this simple class I think I've enjoyed using it more so. I really can't start a new Java project without it now. It's a lot of fun to use. I'd be interested in hearing other features people might want to see added.


package com.wrongnotes.util;

import java.io.*;

public class ExtendedInputStream extends InputStream {

private InputStream delegate;
private String name;
private int bufferSize = 8096;

public ExtendedInputStream( InputStream stream ) {
this( "no_name_file", stream );
}

public ExtendedInputStream(String name, InputStream delegate) {
this.name = name;
this.delegate = delegate;
}

public ExtendedInputStream( File src ) throws FileNotFoundException {
name = src.getName();
delegate = new BufferedInputStream( new FileInputStream( src ) );
}

public int read() throws IOException {
return delegate.read();
}

public int read(byte b[]) throws IOException {
return delegate.read(b);
}

public int read(byte b[], int off, int len) throws IOException {
return delegate.read(b,off,len);
}

public long skip(long n) throws IOException {
return delegate.skip(n);
}

public int available() throws IOException {
return delegate.available();
}

public void close() throws IOException {
delegate.close();
}

public synchronized void mark(int readlimit) {
delegate.mark(readlimit);
}

public synchronized void reset() throws IOException {
delegate.reset();
}

public long copy(File dest) throws IOException {
if( dest.isDirectory() ) {
dest = new File( dest, name );
}
FileOutputStream out = new FileOutputStream(dest);
try {
return copy( out );
} finally {
out.close();
}
}

public long copy(OutputStream out) throws IOException {
long total = 0;
byte[] buffer = new byte[bufferSize];
int len;
while ((len = this.read(buffer)) >= 0) {
out.write(buffer, 0, len);
total += len;
}
out.flush();
return total;
}

public void closeQuietly() {
try {
close();
} catch( IOException ioe ) {
// ignore
}
}

public void copyAndClose( File file ) throws IOException {
try {
copy( file );
} finally {
close();
}
}

public void copyAndClose(OutputStream out) throws IOException {
try {
copy( out );
} finally {
close();
}
}

public ExtendedInputStream bufferSize( int size ) {
bufferSize = size;
return this;
}

public ExtendedInputStream name( String newName ) {
name = newName;
return this;
}
}