An Arboreal Addendum, or, More About Flex Trees

June 23, 2006 on 8:56 pm | In Uncategorized | 1 Comment

Yesterday I discovered one more detail that can potentially fry one’s ITreeDataDescriptor implementation: in the public release of Flex 2, the ICollectionView instance returned from ITreeDataDescriptor.getChildren() will have to implement the [] operator, with integer arguments. In other words, it has to be indexable like an Array. This is not part of the ICollectionView contract; it’s an extra, undocumented requirement imposed by the Tree code. If you use ArrayCollection or ListCollectionView as your concrete type, you’ll be OK, since they do support indexing via []; likewise, FDS collections are probably also OK (though I haven’t tested this).

If you are rolling your own ICollectionView implementations like we are, this means you’d better extend flash.util.Proxy so you can implement []. Fortunately we already had, for other reasons.

Furthermore, data paging is not respected for these child node collection views. Whatever you return from getChildren() will be scanned in its entirety, and any ItemPendingErrors thrown during the process will be ignored. So you’d better not return some huge collection there that you hope will be paged in gradually as the user scrolls through the expanded node’s children. Ain’t gonna happen that way. This probably does affect FDS remote collections, so if you return one of those from getChildren() it might not page in the way you’d hope for.

Suggestive patterns in my tea leaves have led me to retain hope that this will be fixed in some reasonable timeframe. I’m working around the problem for now.

1 Comment

Up a Tree Without a Paddle (and Down Again)

June 21, 2006 on 12:03 pm | In Flex, Programming | 12 Comments

The last few days have been spent working with Adobe, sorting through a blizzard of serious issues and bugs in Flex 2’s Tree control. Some of the outcomes from this seem worth sharing, so that others might avoid various painful problems.

I’ll start at the end, lest this be interpreted as a Flex Flame: Adobe was extremely responsive to fixing the problems and clearing up unclear points, and in the last release I’ve looked at (6/19), the Tree control behaves well — if you treat it right.

Now, how does a Tree want to be treated? I’ll start at the beginning.

In one of our applications at Allurent, we used a Tree to browse a large remote graph of relationships starting at a “root object” that is the root node of the tree. The data structure was so large (potentially millions of nodes) that there was no hope of reading it all in at once, so we opted to make a “lazy Tree” that didn’t access a node’s children until the node is expanded by the user. At any given point, the Tree represents a data provider that goes no deeper than what one sees in the display.

The official approach to this kind of problem is to implement an Flex 2 interface named ITreeDataDescriptor (not really an appropriate name, since it does much more than describe data), and provide the Tree with an instance of it. This object sits in between the Tree and its dataProvider; the Tree uses it to determine whether a node object can be expanded or not, whether it has children or not. The Tree also uses the descriptor to retrieve a node’s children as an ICollectionView of child nodes. The key methods in question here are:
[code lang=”ActionScript”]
public interface ITreeDataDescriptor
{
function getChildren(node, model):ICollectionView;
function hasChildren(node, model):Boolean;
function isBranch(node, model):Boolean;
// other methods omitted..
}
[/code]

We started with a data descriptor whose isBranch() method always returned true (since you always have to be able expand a node to find out what’s inside), whose hasChildren() method always returned true (for the same reason), and whose getChildren() method returned an empty child collection for an unexpanded node. Upon expanding a node, we would read that node’s child data over the net, and have that formerly-empty child collection would fire CollectionEvents with kind == ADD for all new children that were added to it.

This didn’t work: the Tree threw a runtime error as soon as we opened a node, because Flex assumed that any node with hasChildren() == true would have at least one child. On the other hand, if we tried returning hasChildren() == false from an unexpanded node to avoid this error, the Tree never showed the new children because it wouldn’t listen for ADD events on a node with no kids.

It turned out that Adobe hadn’t really thought through the contract between the descriptor and the Tree in this case. To their credit, they nailed the behavior down and fixed the Tree so that it would work with zero-length child collections. So…

Rule 1: If you have an empty node that might acquire children later, return hasChildren() == true and return an empty ICollectionView from getChildren() that fires CollectionEvents to signal the children’s arrival.

Another obscure Tree problem had also reared its head during our work: after expanding a bunch of nodes, our app would get slower and slower exponentially, eventually grinding to a halt. I used the debugger to pause the code and analyze what was going on. At that time, our nodes’ child collections were instances of IList and we would wrap them in a ListCollectionView to return them to the tree from our descriptor’s getChildren() method. Because we returned different wrapper objects every time this method gets called on a node, the Tree was adding event listeners to these multiple wrappers. Each time those event listeners fired, the handler methods would call getChildren() during their work, manufacturing even more wrappers and adding even more listeners… hence the exponential slowdown. So, another rule:

Rule 2: Always return the same identical object from a call to getChildren for a given value of the node argument. This might require some sort of weak-keyed Dictionary scheme, depending on how your data structures are set up.

Anyway, once Adobe fixed the descriptor contract, we started experiencing all kinds of issues with corrupt display in the Tree whenever remote data arrived while actively scrolling up and down. It seemed that the Flex team hadn’t considered this possibility thoroughly — the internal bookkeeping of the Tree simply didn’t account correctly for new data arriving on the fly. Another last-minute flurry of activity at Adobe fixed this problem.

At that point, we still thought there were more problems, but it turned out to be our bug: we were firing an extra ADD CollectionEvent sometimes, which threw off the Tree display. With that in mind…

Debugging Note: if you fire garbage change events into a Tree, you’ll get a garbage display out of the Tree.

One final issue: our big lazy data structure isn’t really a tree, but a graph. This means that one can find one’s way to the same node in the graph via multiple paths from the “root object”. Well, if you return the same node object in two different child collections returned from calling getChildren() on two different nodes, that messes the Tree’s bookkeeping up royally: it maintains internal dictionaries based on node object identity, and it assumes that a given node object is displayed in exactly one place in the tree. So:

Rule 3: Never return the same child node object within different collections returned by getChildren() for different parent nodes.

I remain a bit surprised that Adobe didn’t consider some of the angles that we were exercising while these controls were under development. I’m hoping that these oversights aren’t part of a larger pattern, but realistically, a platform as complex as Flex 2.0 is just going to need a lot of exposure and real-world hammering to bring out all the issues. The good news is that Adobe seems really committed to constantly improving the product and getting updates out in a timely fashion (as Macromedia failed to do with Flex 1.5). And the release of the framework source with the product makes it far easier to diagnose problems and create test cases.

12 Comments

The True Stories Behind The Spam

June 20, 2006 on 12:43 pm | In Miscellaneous | 1 Comment

bill.bagley <przdyujixfi@hotmail.com>: Bill Bagley is the most unusual of direct online marketers, in that he is a true clairvoyant. He actually senses his prospects’ sexual problems from thousands of miles away, and sends them helpful suggestions on products that are ready to assist them. Naturally, this approach is liable to shock the recipient — who would expect an email from a perfect stranger to be so completely and perfectly dead-on in its accuracy? Without special powers, how else could some unknown Mr. Bagley be aware that one’s girlfriend thinks one is perfect and a wonderful choice for her, but that all the time one has been hiding the problems with one’s erections? And that one has been trying to postpone sex as long as possible? And that there is simply no way to hide the truth anymore? And that having sex can make one look up to 12 years younger? Of course, this would all be quite ridiculous and unbelievable in its presumptuousness, if it weren’t the absolute truth, down to every last detail. That’s where being a clairvoyant can get you the edge in direct marketing — knowing the absolute truth, from a distance. Despite his severe difficulties in typing “Viagra” without accidentally hitting a lot of punctuation keys, Bill’s unique talents have enabled him to make it in a tough, competitive sales environment. He may be able to help you out, too.

Locoweed K. Patrolman <dave923@gothicinnbi.com>: “Loco” was the only child of a state trooper and a whorehouse madam in the desolate high plains of West Texas. He acquired his unusual last name due to a mixup on his birth certificate; his father, never a detail man, accidentally wrote his occupation where the child’s intended last name (Smith) should have been. Young Locoweed’s isolated environment led him early to computers and the Internet as a means of connecting with other people and feeding his hunger for information about the outside world. An almost obsessive fascination with chemistry and biology overtook him; he spent hours in the basement, perfecting complex organic syntheses. One fateful morning, one of his mother’s regular customers joined the family for a hearty pancake breakfast. When this gentleman, one Wrongly Q. Arctic by name, mentioned that he was a traveling representative of a major pharmaceutical company, Loco instantly struck up a conversation, and out there in the arid Texan wilderness an online business was born. Loco would synthesize cheap but effective knockoffs of prescription drugs and handle all the email, and Wrongly would write the clever, unique advertising copy, handcrafting it for each customer with folksy spellings and turns of phrase. In under one year, Locoweed earned enough to help his folks not only pay off the mortgage, but refurbish their establishment’s somewhat somber decor in a more traditional and welcoming style.

belajio5 <ylubikanmiu@yahoo.com>: Ylubikanmiu Bellagio, Jr. was born in the slums of Naples in 1975, the youngest son in a troubled family. His mother, an Albanian, left home when he was only 3 years old; his father was a hopeless drug addict. Left to fend for himself much of the time, young Ylubi (as he was called by his friends) sold candy and spumoni on the tough Neapolitan streets, a canny urchin barely scratching out a living. When he was 20, his father died, his ice cream business collapsed, and his girlfriend left him for another man who was using Advanced Gain Pro Penis Enlargement Pills. It was there, at the bottom of the bottom, that Ylubi heard about an obscure traditional herbal distillate peddled by his Albanian half-uncle that had the power to change lives. After only a single dose, not only was he suddenly awash in hot dates, but he realized he had a hell of a product on his hands. Branding the herbal concoction “Ultra Allure Pheromones”, he made it his life goal to share his good fortune with others through the miracle of direct online marketing. Thanks to his passionate emails that he personally composes for each and every sales prospect, Ylubi has prospered. He now lives in Key West, Florida, a successful and happy entrepreneur whose chief satisfaction is helping others experience their sex lives to the fullest extent possible.

Oksana <admin@mydatingrussiaweb.info>: Oksana Karushchenko, to be perfectly plain, is just a lonely 25 year old Russian woman with a human heart like yours or mine. As if being lonely wasn’t bad enough, she suffers terribly from the stereotyped responses of most people who receive her emails: they assume she is a brassy, mobbed-up gold-digger who’s only looking for a wealthy American mark with a credit card account to drain. Nothing could be further from the truth. Ms. Karushchenko is not only a delicate, sensitive and frail beauty, but is also a woman of considerable and independent means. She was the only daughter of a corrupt party functionary who for years ran Komkatlit, the state kitty litter monopoly, with an iron fist. After the fall of communism he made billions of rubles from kickbacks and bribes before he died, leaving Oksana with the delicate problem of how to move this ill-gotten fortune out of Russia. All she seeks is a thoughtful, selfless man who wants to share life and love with her, while living out the rest of his days in unimaginable wealth and luxury. Nonetheless, people assume the worst of her when they discover she needs a mere $10,000 advance to pay for an Ill-Gotten Gains Export Permit from the Russian government. Sometimes her quest feels doubtful, but in the meantime, Oksana sits and studies her English, hoping against hope that there is one man left in the West who has not yet lost the simple ability to believe.

1 Comment

Entries and comments feeds. Valid XHTML and CSS.
All content copyright (c) 2006-2007 Joseph Berkovitz. All Rights Reserved.