Tuesday, November 3, 2009

Earlest time to call a RemoteObject?

I was doing some investigation on how best to retain your session. A lot of Flex applications don't utilize session management especially in the case when the app is restarted by a refresh or a new window. Which then the users are faced by a annoying login window even though the server has retain the session information which negates this need to re-login. But before I really go into that I got sided tracked looking into when is it best or the earliest time you can send off a request to get session information. This is an interesting question with an obvious answer as well. But I wanted to really understand why.

To do the call I'm using RemoteObjects with ColdFusion as the destination. The ColdFusion CFC is fairly basic just returning an array with the JSessionID. All of this will complete quickly to negate any long server processes. Ideally in a production environment I would use a session structure to return to speed things up.

So I wrote some basic ActionScript code to connect and call the CFC. I first tried calling it from preinitialize call. The call worked but it took ~100ms to complete which was troubling which it was just calling a server on my machine. I then did a quick speed test of calling the RemoteObject and was able to call it and get a responds in < 1ms so something else was at play here. I then thought about maybe I should push the call further up the process since preinitilization was happening at ~200ms since application start but I wanted it to start earlier.

Preloader here I come! The preloader was being called at ~100ms and I was really happy but then I hit a road block...
[FaultEvent fault=[RPC Fault faultString="[MessagingError]" faultCode="InvokeFailed" faultDetail="null"] messageId="33578681-51C7-A64A-7C04-B829D52F7A4C" type="fault" bubbles=false cancelable=true eventPhase=2]
This is a puzzling error message since it doesn't give me any reasons why the InvokedFailed? If I called the call the RemoteObject later in the Flex life cycle it worked so seemed strange that it would fail at this point. So bring on Flex Debugger! I got it down to one call which was causing an exception and it was the mx.messaging.config.SeriviceConfig.xml getter. It was being called before it had been set with the complied flex-services.xml which seems strange that it didn't have this embed. Then I started to look into when it got set so and found that it hadn't been called by SystemManager to initialize this value. So even though the complier embeds the value of the flex-services.xml it needs to be set at initialization by the SystemManager.

So what does this boil down to? You can't call RemoteObjects prior to the start of Application preinitialization process since the SystemManager has not completed its own initialization process. Remember that the Application is a child of the SystemManager so following the Flex startup rules you shouldn't do anything with it until initialization of the SystemManager is complete. So using the Application preinitialization/preinitialize event is the best/earliest time to do a call to the server to get data using RemoteObjects.

Oh and the other point about the call taking so long ~100 ms... well I put that down to the additional things that occur at start up. A lot happens when a component/Application is created ;-)

3 comments:

Anonymous said...

Clearly the earliest time to call a RemoteObject is three days after the first date... You don't want to appear too needy.

Anonymous said...

I am having an initialise problem.

I deploy my compiled server side code in Tomcat, and watch it start up.

I then run up a new browser with my start page in it. This page does a preinitialize="init()" inside it. The init() method has some code to make a RemoteObject call to get some data from the server side.

I have a breakpoint ready in the server side code to trap any call to the method (using java remote debug).

private function init() : void{

Alert.show("I am inside init()");
marginxRO.getFunds();
}


However, when I load the page, the init() method IS CALLED (as I have an alert in there), but I get nothing trapped on the server side. For some reason, the marginxRO.getFunds() is not called.
No exception is thrown in the faultHandler either.

Here's the funny thing. If I Refresh the browser, then the init() is called, AND the marginxRO.getFunds() is called, and it works !?

So what could be not firing in the first call ???

Regards

will@travellazy.com



Now,

Ross Phillips said...

@Will

The call will return an event of some kind be it a fault or result. Why your debug point on the server side is not being fired I'm not sure. I would not expect a browser refresh to get the call to work so I suspect something else is at play here.

You may find the use of a proxy app like Charles to check if the Flex app is making the call but waiting on a response.

Ross