« September 2008 | Main | November 2008 »

October 14, 2008

Using Flex & Cairngorm with LCDS Data Management

Using Flex & Cairngorm with LCDS Data Management from Brian O'Connor, Principal Architect at Universal Mind.
Will focus on Flex 3.0 &LCDS 2.6 and post the slides and sample code on his blog.

Previously with Macromedia consulting and Adobe consulting. Some of the audience have used Cairngorm and a few have used LCDS.

Really looking at Data Management as the focus since it has a lot of power. Lots of problems with how best to model data management and data services this type of application.

BlazeDS versus LCDS. BlazeDS offers RPC Services and messaging with back-end support for JMS and Java with a limited proxy service. No RTMP, no data management, AMF support, and non-NIO (aka blocking) HTTP streaming. LCDS adds Data Management, many more back-end adapters (ColdFusion, Hibernate, SQL, etc.) and NIO (aka non-blocking) HTTP streaming.

LCDS can't be opened to the internet due to denial of service and security issues. Still issues with web servers being the block that sits in front of LCDS.

LCDS helps solve lots of data management issues, like paging million row result sets, collaboration, offline capabilities.

Start with a DataService pointed at a Destination that talks to a Java object called an Assembler. Data send to client to populate ArrayCollections. Can be pointed at client side Data Management Controls like a DataGrid. LCDS remembers which client has which data to do intelligent data handling. Default Fill and Page Fill are key methods of an Assembler. DataService.saveCache() handles persisting to local database for offline storage.

Running through a sample application. JBoss running in the background. Cairngorm application with DataGrid for editing data. Uses samples.war that comes with LCDS to make it easier to setup and run yourself. Showing difference between default and page based filles. Page only got first 11 rows.

Data Service calls fill on Assembler. Default Fill got all the data from the database. Assembler then pages it out to the client. Data Service populates ArrayCollection which is bound to DataGrid. More than 100,000 rows and you want to be sure to use Page Fill which will only grab the requested data from the back-end. Must include count() method so that a paged based query knows how much data can be returned. In either case after a data update has occurred Data Service calls CRUD operations on Assembler. Assembler uses refreshFill(). A badly tuned refreshFill() can kill performance. Really need to understand it. If you update the database directly without going through LCDS you need to notify it through the Data Services Transaction mechanism.

In order to sort by a column you need to manually determine the column and direction to sort by (called fill arguments) and then call a data service manager to get the data in the newly sorted manner. DataGrid is good a paging and data presentation but you need to manually add custom sort order or filtering.

With auto commit set to true clicking off a row will send the CRUD operation. RTMP is best to synchronize data. AMF polling is okay but you really want to use HTTP Streaming (can't proxy streams through Apache). Three options to resolve a conflict given to you as an Array of conflicts. 1) accept server, 2) accept client, or 3) custom conflict resolution. You can use these techniques with or without using auto commit.

Handling large data sets can be tricky. ItemPending errors didn't upgrade nicely from Flex 2 to Flex 3. The UI needs the count method to accurately reflect the total length of available data. Trying to lazy load ahead of the user was problematic updating from Flex 2 to Flex 3. Better left to Flex UI component logic unless you are writing something completely custom.

Configuration on a DataService in MXML overrides the base behavior defined in the data-management-config.xml file. Many errors (best to debug with trace log turned on) result from a missing or incorrect metadata identity element.

When using Cairngorm with Data Management the typical Command/Delegate pattern has problems. Best to have DataServiceManager as a Singleton so it sticks around and holds reference to DataService. Have manager create event listeners on DataService that it keeps around all the time. It is a different type of connection.

refreshFill() on an Assembler can be a performance issue. Tied to autoRefreshFill() result. Append to fill is added at end (not sorted or filtered). Don't need to fill when just doing an update, really should do it on an insert. AutoSync will pick that up for you. 4 different status that can be returned. Really want to optimize when and if a fill is ever needed.

DataServiceTransactions allow server side only code to tell the rest of the system that their are data updates that it should synchronize. Different entry points to the database may make it harder to use LCDS. Really depends on frequency and type of updates to the database and its ability to call Data Service Transactions.

AIRs ability to save a local cache lets you access it offline. Must use same parameters (i.e. same filtering and or sorting). Can do a sync that will handle updates and trigger normal conflict resolution mechanism. autoSaveCache may have row limit but has tested up to 16K without issues, stated limit is 2K.

Where to look for data aware components? No good resources yet, best to look at Flex source code and how it does it.

Some of the limitations are with clustering. Hard to do. Destinations and Data Synchronizing is hard. Built on top of JGroups which is very chatty so really can't scale.

100s/CPU with BlazeDS versus 1000s/CPU with LCDS. Really want to use RTPM but non-blocking I/O in LCDS is better. On the Internet polling type cab make a big difference especially with browser being used. A connect and wait system will eat up a browser HTTP channel.

Retrieved data is fed directly to UI as the model. Managed model objects have client and server side pieces which handle the pieces for you. Granularity of updates is per property can control with autoCommit settings.

Tags: cairngorm flex lcds

October 8, 2008

Antennae 1.2.2 Released

Antennae 1.2.2 has been released. This is a very minor update that just changed the bundled version of FlexUnit. I'm now bundling the version from the Adobe Open Source Site. I've also created a discussion group for Antennae available at http://groups.google.com/group/antennae-discussion.

Tags: ant antennae flex

October 6, 2008

PPE 2: Java Project Skeleton


I've been following the progression of the tool AppFuse for some time now but haven't had a chance to use it. This seems like a prime time (cue learning curve for first new technology). While there are many Java frameworks I could use, I've found the Spring Framework to be rock solid and know that it covers everything I could want to do with this simple application. Spring has also created Spring Web MVC to support the front-end pieces. I think it offers a cleaner solution than Struts. AppFuse supports Spring Web MVC based projects so that should make this straight forward.

Alas AppFuse requires Maven (cue learning curve for second new technology) which I don't currently have installed. Back to the command line for that. I already have Java installed so that AppFuse requirement is there and I'll start off with the HSQLDB profile since my MySQL server runs on a different machine and I don't want to mess with configuration just yet.

# 3rd party Java projects I store in a standard directory
cd /Applications/Java
# downloaded from one of the available mirrors
tar -zvxf ~/Storage/apache-maven-2.0.9-bin.tar.gz
setenv MAVEN_HOME /Applications/Java/apache-maven-2.0.9
setenv PATH "${PATH}:${MAVEN_HOME}/bin"

The latter two lines I'll be adding to my shell so that they get picked up next time I launch a terminal window. If you hadn't noticed those commands are in tcsh. I like it better than bash as my terminal shell (since I never made the switch to zsh which I hear is even better) but any scripting I do is in bash.

Now to let AppFuse do its magic.

cd ~/source/trunk/danielr/projects/PPE/
# tried to run the AppFuse Maven command line but got an error, see below
svn delete GameOfLifeServer
svn commit -m "Remove server directory since AppFuse complains if it already exists"
# now I can run it
mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring -DremoteRepositories=http://static.appfuse.org/releases -DarchetypeVersion=2.0.2 -DgroupId=com.neophi.gol -DartifactId=GameOfLifeServer
# checking this into subversion as recommended
svn add GameOfLifeServer/
svn commit -m "Initial AppFuse generated project"
# now to play with the project
cd GameOfLifeServer/
# since I don't want to deal with MySQL properties right now
mvn -Phsqldb
mvn -Phsqldb jetty:run-war

Man those Maven targets are downloading a lot of stuff. That makes sense since I've never used Maven before so have nothing in my local repository. Overall as I've been playing with AppFuse the documentation on their site has been good enough that I can muddle through it. Now to pull it into the IDE.

# create Eclipse project files
mvn eclipse:eclipse

After launching Eclipse I added a Java Classpath Variable called M2_REPO pointing at "/Users/danielr/.m2/repository". I tried to use Maven to add it but it didn't work. Turns out it might have worked but had issues trying to use "~" when specifying the location of my Eclipse workspace directory. Next I imported the project located at "~/source/trunk/danielr/projects/PPE/GameOfLifeServer/". It imported and compiled with the expected errors. I think that means it's time to commit to subversion again.

# don't check in the directory Maven creates its files in
svn propset svn:ignore target .
# add the Eclipse created files
svn add .classpath .project .settings/
svn commit -m "Added ignores and Eclipse project files"

And with that, I'm calling it quits for today.

Closing Thoughts

For a snapshot of the project in process grab PPE-2.tar.gz.

For the history of this project see Programming Project Experiment (PPE).

Tags: gameoflife java ppe

October 5, 2008

PPE 1: Flex Project Skeleton

The most tedious part of any project I find is getting the skeleton setup. Thankfully Flex Builder's project wizards make this easier. I'll be creating two Flex projects, one called GameOfLife, which will hold the UI application, and one called GameOfLifeTest, which will hold the testing code. Additionally I'll create a Java project called GameOfLifeServer which will hold the back-end code. Both the production and test code will reside in the same Java project since you can easily mix them in Eclipse's Java mode, unlike with Flex. These will all be sibling projects in a top level directory.

Command Line

First a little command line mucking to get the directories setup:

cd source/trunk/danielr/projects/
mkdir PPE
mkdir PPE/GameOfLife
mkdir PPE/GameOfLifeTest
mkdir PPE/GameOfLifeServer


Run through the Eclipse new Flex Project Wizard using the directory above as the project root and accepting all the defaults.

Now onto the associated test project.


Run through the Eclipse new Flex Project Wizard using the directory above as the project root and accepting all the defaults.

To GameOfLifeTest I need to add the testing library I'm going to use. For this project I'm planning on sticking with FlexUnit. An alternative that I considered was fluint. Like some of my other decisions I'm sticking with what I know works well and I don't see anything with fluint that I'll be needing that FlexUnit doesn't already cover. After downloading the current release I drop it into the libs folder of the recently created project.

Next I need to put in the FlexUnit test runner scaffolding. Makes me wonder how hard it would be to extend Flex Builder to add a "Create new FlexUnit Project Wizard". In this case I'm just going to cut and paste the code from the recipe I wrote that is up on the Adobe Cookbook. Lastly I want to setup how the test project is going to reference the code from the main project. Since Flex Builder can't efficiently handle compiling multiple projects at once (i.e. a SWC library project and the application that it depends on) I'm setting this up as a source path reference. Be warned that such a setup has it's own set of problems.

Since I'm the only developer on the project I'm doing the quick and dirty "source path" add folder option. Eclipse will store a hard coded path in the project file which means that anyone else importing the project will get an error unless they also happen to store the folder at "/Users/danielr/source/trunk/danielr/projects/PPE/GameOfLife/src". The simple fix is once the project is imported, go to the project properties and update the source path folder reference.

To finish this skeleton code I want to make sure I can create and test something that exists in the referenced source path. At this point I only have the main application, but that's good enough to verify things are working with some trivial test. Note I'm break from the traditional test naming scheme since I'm going to delete this test once I have some real code to work on.

package com.neophi.gol
    import flexunit.framework.TestCase;

    import mx.core.Application;

    public class ApplicationTest extends TestCase
        public function testApplication():void
            var gol:GameOfLife = new GameOfLife();
            assertTrue(gol is Application);

Next I need to include it in the test suite that gets run. A quick edit to GameOfLifeTest.mxml will do the trick:

private function createTestSuite():TestSuite
    var testSuite:TestSuite = new TestSuite();
    return testSuite;

Sweet. That compiles and runs and passes! Next up a small stub of the main application.


Not much to do here but make sure it compiles and runs. For that I'm just going to stick in a simple label.

<mx:Label text="Game Of Life" horizontalCenter="0" verticalCenter="0"/>

That was easy enough. That is also now compiling and running. For the paranoid, you could run the test suite project again to make sure everything is still working. Remember to refresh the test project otherwise Eclipse might not pick up the fact that we changed a file in a referenced source path. Have I mentioned that source paths are buggy? Now to create a skeleton back-end. Looks like I'll work on that tomorrow as it's later than I thought.

For a snapshot of the project in process grab PPE-1.tar.gz.

Closing Thoughts

The format I used for this post is working well so I'm going to continue using it, not that you can tell all of the thought process behind it. What I've been trying is before I do something I've been writing the step down and then performing it to make sure what I thought I was going to do actually worked. Given how bad I am with tenses when writing most of the time, these posts will probably be worse in that regard so fair warning on that front. As a tongue-in-cheek expression call this approach blog first development, which some might say is a BFD.

For the history of this project see Programming Project Experiment (PPE).

Tags: flex gameoflife ppe

Programming Project Experiment (PPE)

I've been toying with the idea of building a site around the game of life simulator. In the spirit of just playing, I figured I'd blog about my process and thinking to see where it goes while keeping a record of it. With that broad mandate some rough idea of what I could see happening along the way.

Provide an online tool for exploring game of life instances. Flex based front-end with a Java based back-end and data storage in MySQL.

Why those technologies?

Well I think Flex is where it is at for rich UIs right now. I do most of my day work in Flex so I should be able to develop quickly. While Silverlight and JavaFX might be fun to play with, I'm more interested in getting something working versus learning a new language, that's better suited, in the context of some project. I'm always up for learning new stuff if I can see some clear benefit. Switching from Flex to something else right now doesn't seem to offer that clear win so I'm going to stay with what I know works.

Many people who's work I follow would say that Ruby would be the language to do the back-end in. While there is some appeal to that, given other aspects of this open development I don't want to throw too many new things into the mix. There are already some Java tools I'm looking at on the Java side that I've not used before. In fact I could see reimplementing the final functionality in Ruby as a good example of getting a better grasp on how the technologies differ.

As for MySQL, well its what I already have installed and running on my machine. In fact its the data store behind this blog. Given that I don't foresee any need for a lot of heavy lifting from the database layer I'm certain MySQL can handle it.

As far as a development environment, I'll be using my Mac. I'll be using Eclipse as my IDE since it has great Java support and okay Flex support. I'll probably throw in some Ant scripts for deployment and the like since my web server resides on a different machine. Lastly I'll be using Subversion to store my code.

Tags: ppe

October 2, 2008

Amazon Web Services (AWS) for ActionScript 3, Flex, or AIR

As I've been toying with some new application ideas I've been curious what the current state of Amazon Web Service (AWS) support for ActionScript 3, Flex, or AIR is. Most of the sample code I've found so far is for Ruby, PHP, or Java, basically languages that have a rich server side presence. The lack of AS3 libraries makes some sense given security issues with running code on the client and its need to access your AWS secret key to create valid requests. However, management applications or user based services (i.e. the user must sign up for an AWS account) that could hold the keys for a session or store securely for AIR applications would benefit from such an interface. Below are the libraries that I've been able to find so far, if there are additional resources out there I'd love to hear about them.

Given the lack of cross domain files for certain AWS services, the lack of ActionScript only APIs kind of makes sense.

as3awss3lib: ActionScript 3.0 library for interacting with Amazon S3. Requires the AIR runtime environment and some other libraries. Source code only.

awsapi: An actionscript library to access the Amazon Web Services API. No documentation. Code doesn't look like its fully baked. Looks to only be for Amazon's eCommerce features.

SimpleDB for AS3: An implementation of SimpleDB for AS3. Requires the AIR runtime environment. Minimal documentation.