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.