ColdFusion 8 ValueObjects vs Typed Structs for Flex RemoteObjects

March 28, 2008

ColdFusion Objects transfer nicely over to Flex, making the remote data connection for Flex run like a dream.  It can get out of hand, however, when there are a large number of Objects to return from ColdFusion, for example, an array of ValueObjects, which might have other value objects as members.  In researching this, I ran across a few very helpful postings.  Basically, CF8 has a workaround wherein you use typed Structs instead of full blown Objects to pass VO’s to Flex:

http://www.briankotek.com/blog/index.cfm/2008/1/28/Returning-Typed-Structs-vs-CFCs-to-Flex

http://groups.google.com/group/transfer-dev/browse_thread/thread/0abdb2191dcfd226#2cbf827754e75376


So, I decided to run a few very simple tests to see what the impact of CreateObject was on a large dataset.  I put together a CF script with a loop to create 5000 objects using CreateObject (with init), another for 5000 with CreateObject (without init), another to simply duplicate a template Object and another to create 5000 structs.  The breakdown and the code follow:
 

Test

Iterations Elapsed Time (ms) ms/Instance
structTest 5000 157 0.0314
FullCreateTest 5000 17468 3.4936
createTest 5000 16610 3.322
dupeTest 5000 12469 2.4938
structTest 5000 15 0.003


This was run on a CF8 Box with JRun running on Java 1.5 I had similar results on a CFMX 7 Box with JRun running on Java 1.42 The option of rolling query results into typed structs is really a lifesaver given the performance numbers.       

<cfset t1 = GetTickCount() />

<cfset myArray=ArrayNew(1)>
<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newStruct=StructNew()>
<cfset newStruct[“iter”] = #i# />
<cfset ArrayAppend(myArray,newStruct) />
</cfloop>
<cfset t2 = GetTickCount() />
<cfset elapse1 = t2 – t1 />
<cfset myArray2=ArrayNew(1)>

<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newObj=CreateObject(“component”,”com.test.TestIter”) />
<cfset newObj[“iter”] = #i# />
<cfset ArrayAppend(myArray2,newObj) />
</cfloop>
<cfset t3 = GetTickCount() />
<cfset elapse2 = t3 – t2 />
<cfset myArray3=ArrayNew(1)>

<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newObj2=CreateObject(“component”,”com.test.TestIter”).init() />
<cfset newObj2[“iter”] = #i# />
<cfset ArrayAppend(myArray3,newObj2) />
</cfloop>
<cfset t4 = GetTickCount() />
<cfset elapse3 = t4 – t3 />
<cfoutput>Results<br/>Structs : #elapse1# ms for 5000</br>

CreateObject (no init) #elapse2# ms for 5000<br/>CreateObject (with init) #elapse3# ms for 5000<br/></cfoutput>

<cfcomponent name="TestIter"> 
      <cfproperty name="iter" type="numeric"> 
      <cffunction name="init"> 
            <cfreturn this /> 
      </cffunction> 
</cfcomponent>
Advertisements

When to Use ColdSpring: one example

June 4, 2007

  I have conversations with people I work with, regarding the pros and cons of employing a framework like Coldspring.  Well, ColdSpring in particular, actually.  While explanations of its benefits have been present, there has lacked a concrete example that I could share with with my coworkers and comrades.  The benefits realized from loose coupling of objects have been demonstrated, and ColdSpring is a way of moving toward that end, but that is fairly abstract.  Also, as trends in OOP have moved away from inheritance and have leaned toward composition, the process of decorating or injecting the objects in this model, is also worthy as part of a prevalent approach, but it remains too abstract.  The notion of logging, or security, or changing the DSN does not get people too excited about putting ColdSpring into place.  Instead, Coldspring could be the source of a whole new batch of problems without even giving any benefits in return.  And the notion that everyone is doing it, brings requests for a new glass of Kool-Aid. 

A ColdSpring Example Transaction  A real example that can be seen by our organization comes with the wave of demand for Dashboard enabled applications with analytics, and metrics that could never be satisfied.  (I will lay aside for this writing, my thoughts and concerns on Dashboards, and the dangers of their overuse).  So, in this perhaps hypothetical situation, we have a customer who uses our eCommerce application, and decides that he wants some real time metrics, of things which do not neatly fall into one table or another, and might require some data consolidation, or something, to pull what he wants to see.  Let’s say he wants to know what aisle of the store people spend the most time in (category), and of those, how many buy product.  For people that hang out in category A, how often are their carts abandoned.  Do people get lost in aisle A?  Questions like that bubble through the storeowner’s head, and he pictures a dashboard, with a realtime visualization as solving the problem.  Now, it could have been anything.  We don’t track which aisle people are in, only what they put in their basket.  And we don’t pair that with the cross sells.  How can we get the data that he wants without making huge changes?

   The important thing to note is this:  The huge changes that need to be made to facilitate this customer’s desires do *not* benefit the shopping workflow at all.  They are a separate concern.  A possible solution, with ColdSpring, would be to introduce an AfterAdvice, which would feed the desired data into a log, which would be fed to the dashboard, and so on.  So, this could be done without any major impact on the workflow code itself.  This is huge.  This could have made the shopping cart code just a little bit more complicated.  Instead, it has left it alone.

  In some ways, having programming in database scripts, Oracle PL/SQL procedures and triggers, this dependency injection is not so different.  It is just happening at a different layer in the process.  In fact, I had thought of using database triggers, at first.  It took a little while to realize that this would be a decent situation for using ColdSpring, and realizing some tangible benefit from it.

  Now, with a concrete example in front of me, I can think of another situation, which again, could have been dealt with using database triggers, that could benefit from this architecture.  Stepping back, I think that will continue to be the case.  The immediate solution that jumps out in response to the problems that ColdSpring addresses could often be taken care of with the application.cfc (security), or by the RDMS (logging).  Caching goes in the middle there somewhere, in certain situations, but even that for some situations, has solutions easily employed at different layers.  So, part of the difficulty is beyond the abstraction, and in the realm of problems which we have already solved in one way or another.  And while that may be so, as customer demands shift, we must at least be prepared to shift our strategies and solutions to problems.


ObjectProxy in Flex 2

May 18, 2007

ObjectProxy in Flex 2 (continued) I went over the problem of the null responder, and a solution, in the last discussion of Delayed Instantiation. This deserves a deeper look because it is a frequently misunderstood and misapplied area of the Flex framework. Fortunately, Adobe provides the source code for ObjectProxy, and it can be found in the Flex SDK under [Flex SDK Folder]’frameworks’source’mx’utils’ObjectProxy.as. I’ll dig into one particular area, the getter function, as that was what was in doubt in the example.



 
/** * Returns the specified property value of the proxied object. 
** @param name Typically a string containing the name of the property, 
* or possibly a QName where the property name is found by 
* inspecting the localName property. 
* * @return The value of the property. 
* In some instances this value may be an instance of 
* ObjectProxy. 
*/ 
override flash_proxy function getProperty(name:*):* { // if we have a data proxy for this then 
   var result:Object = null; 
   if (notifiers[name.toString()]) return notifiers[name]; 
    result = _item[name]; 
    if (result) { 
       if (_proxyLevel == 0 || ObjectUtil.isSimple(result)) 
           { return result; } 
             else 
           { result = object_proxy::getComplexProperty(name, result); } 
// if we are proxying } 
  return result; 
} 



In the traditional use of the Virtual Proxy, the caller is requesting the value of some property. The only way to access this property is through the accessor interface, or the getter, which is what is listed above. Now, the getter does not simply return the private value and be done with it. It can do several things. In this case, it does the following: 1) Check to see if we are waiting for a response on this item (from the notifiers). If so, pass back a reference to the notifier. 2) Get the indexed item, and if it is a simple object (a Number, say) or if the _proxyLevel is 0, just return the object 3) Otherwise, send back a proxy to the complex object The caller is never sure what he is going to get, and has to work with the interfaces presented to him. In the first use case, where the Notifier is returned, is this what we see when we are givge, en the null error, as in the last article? Or is this a different case altogether? Now, you think, it would be really handy if I could introspect the proxy to see if it is the real object, or if it is a notifier or proxy. But it would also be the exact opposite of what the design pattern was supposed to encourage, thus reducing the solution’s overall effectiveness, and lowering the measure of loose coupling between those layers. As soon as you start digging inside of the object to find out stuff (not during debug, I am talking about realtime deep uinstrospecting to gain knowledge about the state of an object when it was intended to be encapsulated. This is a good time to go ahead and trace through a test case with the debugger, to see what is going on. Why is there a delay in that object’s instantiation, and why do we get a null error? What are the mechanics of what is going on? What is the proper way to handle these objects with care, to avoid producing that error. And finally, if there is an inherent problem with the architecture, how could it be fixed, so that a deeper look would not be necessary? (continued) Here’s another solution I have seen applied, which eliminates the errors, but we still haven’t fully clarified the root cause yet.:

public function result( event : Object ) : void
{
   trace("myCairngormCommand.result()");
   var resultEvent:ResultEvent = ResultEvent(event); 

   var result:ArrayCollection = resultEvent.result as ArrayCollection;
    for (var i:String in result) 
    { result[i] = new ObjectProxy(result[i]);}
    ModelLocator.getInstance().myArray = result;
} 

This looks suspiciously like the code in the previous post, in the framework itself. So, this move compensates for something the framework is not handling for some reason. That is, the result is not being wrapped in a Proxy because of the type of variable the result is being assigned to. So, the return code is doing what the framework would have done, wrapping it in a Proxy, so the Proxy will handle peeking at the contents to see if it’s ready. More can be gleaned from the documentation on RemoteObject, and the ways to handle the results and bindings. The best results seem to come from letting the bindings do the hard work, and to not beat the framework into submission with multiple type casts, and extraneous events. But, sometimes, this seems to be all you can do to make it go… (to be continued)


ArrayUtil and RemoteObject Proxies in Flex

May 17, 2007

The problem:

In Flex, you’ve performed all of the steps to issue a remote query, and your responder has received the resultevent, and you go to evaluate the payload, and it gives you a null error:  “Error #1009: Cannot access a property or method of a null object reference”.

A solution (as described in Peter Ent’s blog):

Assign the result through ArrayUtil.toArray 

gallery.photos = mx.utils.ArrayUtil.toArray(data.photo);

(link (solution near bottom) : http://weblogs.macromedia.com/pent/archives/2005/12/day_6_finished.cfm

What’s really going on?

The underlying object carried by the result event is a Proxy Object, and not an ArrayCollection, nor an array.  It could look like an ArrayCollection, but only if handled in a particular way.

Why can’t the problem be fixed?

Because the paradigms have been mixed, and they can’t be unmixed. 

The paradigms I refer to are what contrast delayed instantiation, which is characteristic of functional programming languages like Scheme, Lisp, and Haskell, and eager evaluation, which is typical of declarative programming languages like C, Java, and PHP.  In order to force declarative languages to use delayed instantiation (or lazy acquisition, or lazy loading), a bit of code has to be put in place to manage the laziness properly, and as unobtrusively as possible.  The pattern typically used is the Virtual Proxy Pattern.

In this pattern, the interface to the object that is presented, is in fact, a proxy.  It may return the real fully populated object, and it may return a shell.  That all depends on how it is implemented.  In Flex, if an object is not quite ready, you can bind it with no problem, but you don’t want to directly access the underlying object, or its members.  There are interfaces (like ArrayUtil) which you can operate through to either force it to load up all of the data, or to tickle the object, and set a listener for when it is populated (basically binding).

The Rich Client interface in Flex, provides many cases where this behavior is desireable, and to force it to load up all of the data is not always appropriate.  It is similar to the problem developers run into when they first start trying to actively drive a command into a view that has not been instantiated.  They will get a null error.  Then, after trying many things, and poring through the books, they find creationPolicy=”ALL”.  And the immediate error goes away.  That is how you defeat delayed instantiation in your views.

But, the delayed instantiation is there for a reason.  It was put in place to solve a problem, and by incrementally removing the solution, without understanding what it solved, is tantamount to inviting or encouraging the problem to surface.

It’s all about timing.  And making good use of time, which can be devoured very quickly by rich user interfaces.  For anyone who has done Windows programming, or other UI programming, you might be familiar with onDraw() event handlers for views, and how that all happens on a larger reDraw cycle.  The same principle applies here.  The data and the view are on different schedules.

When I continue, I will look at some code examples, with Haskell first, and then Java, for comparison.  Speaking of Haskell, looks like they have an actionscript byte code assembler for Haskell, with support for the Flash 9 virtual machine (AVM2).  Great work guys!

(to be continued)


Opposing Trends : Predictive Fetching and Lazy Loading

May 10, 2007

The Web is full of contradictions.  An animation toy (Flash), essentially a diversion, the antithesis of work, has been a driving force for Adobe in launching their forward strike to gain space on the user desktop.  Macromedia first, then Adobe, has the pole position now on the Rich Internet Application marketspace, with a strong solid product. (that was once a mere toy).

Now, inspired by animation strategies, perhaps, the practice of lazy instantiation, or delayed instantiation, or lazy loading seems pretty ubiquitous.  It is built into the Flex framework, and built into the ORM engines, and is a well worn design pattern for data access.  In animation, 3D animation, the computer, or the artist, need only draw the things which are seen.  There is no need to puzzle out what the other side of a building looks like if you never have to render it.  And there is no need to draw that little short guy, because the stout man is always directly in front of him.  And so it goes.  If animators, or cg, had to render every surface, then the production of animated sequences would take many times as long as it does, and it is processor intensive.

  For data access, lazy loading plays a similar role, in minimizing hits to the database, thus boosting performance overall, and raising capacity.  On the other side of the coin, however, is the bleeding edge of Web 2.0 concerns, not content with merely being fast, but wanting instead to peer into the future, patterns for prefetching some data are being used to enable typeahead controls, and faster access to some data sets.  And the proper positioning of the data depends on the usage of the data, which will vary from population to population.  And so to precisely balance the predictive client side cache load, with timely garbage collection, boosted by the yields of lazy loading for other objects requires statistical analysis of the user community, and to some degree, specialized analysis of the data usage patterns of the individual.

“Is this the type of guy who is only going to really look at the first 4 books on his book search?”  if so, we can get the first four, and maybe fake the rest with a proxy.  But is this same guy almost guaranteed to view every page with a “special offer” on it?  If so, some of this data may do well to be prefetched or staged for him.

So, do we run headfirst into the first into the first wave of Delayed Prediction engines?  More likely, we deal, as best as we can with the business problems at hand, always keeping an eye out for the low hanging fruit.  And for some software house, which will be bought by a larger company, and then swallowed by a mega corporation, for that plucky little entrepeneur will see huge gains by implementing a liquid GUI, with predictive fetching, lazy loading, statistical throttling, enterprise messaging, as a framework for the company’s killer app.  We shall see. 


Flex, Spring, iBATIS, Cairngorm: Bringing It All Together

May 10, 2007

Chris Giametta gives instructions for everything you need, right now, today, and it is all possible.  Flex, Spring, iBatis, and Cairngorm.  Grab your favorite power drink and enjoy:

http://www.appfoundation.com/blogs/giametta/2007/05/09/flex-spring-ibatis-caringorm-bringing-it-all-together/