I'm working on a project that is performing "real-time saving" of data in a Flex UI. In other words, if they do something in the UI, that change is saved to the database automatically, rather than waiting until the user presses a save button.

One concern we had was what happens if multiple requests are sent to the server, and for whatever reason some take longer to complete than others? i.e. you send RequestA then RequestB, and RequestA takes 10 seconds but RequestB takes 1 second. Which would mean the database would end up being wrong, with the data from RequestA being the last version saved. How can we make sure that the final state persisted in the database is actually the current state, and not the last request that happened to complete?

A number of options were thrown on the table, including implementing a client and/or server-side queue, or building logic to verify that the current state in the client matches the persisted state. While mulling this over, one of my colleagues noticed an interesting line in the LCDS documentation:

Channels also impose an order to the flow of messages sent to the server and the order of corresponding responses. Order is important to ensure that interactions between the client and server occur in a consistent, predictable fashion.

It's rather vague, but we read that to say "even though you think your calls to the channel are asynchronous, they actually aren't." Which, even though it is not what I thought was going on at all, would mean that the problem I mentioned earlier actually isn't a problem at all.

Tom Jordahl was kind enough to respond to an email and discuss this. I then ran a number of tests locally to confirm the behavior. It turns out that calls to Messaging Channels are totally asynchronous, but calls by the same client to the same RPC Channel are synchronous. Which means if you send RequestA then RequestB, they will be processed in that order and the results will come back in that order. Regardless of how long either of them take to complete.

You can still run asynchronous RPC calls from the same client, but they would have to call different Channels. So the option is there if you need it.

I wanted to blog this because I've been using remoting for a long time and never knew this. In fact, I always assumed the opposite was true. So, this is a big deal for two reasons: if you need to ensure the order of your RPC calls, you can. And conversely, if you think your RPC calls to the same Channel are running asynchronously, they actually are not! And this applies whether you're using a Java back end with BlazeDS/LCDS, or using ColdFusion with its BlazeDS integration.

Comments Comments (3) | del.ico.us del.icio.us | Digg It! Digg It! | Linking Blogs Linking Blogs | 6279 Views

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)

  • # Posted By Alex Glosband | 9/14/11 10:08 AM

    Nice post.

    You might also want to take a look at the reliable messaging feature in LCDS.

    http://help.adobe.com/en_US/LiveCycleDataServicesE...

    Reliable messaging ensures ordered delivery of messages and also can prevent/avoid message loss.

    In your test scenario it sounds like messages should get delivered in order, but what happens if the connection between the client and server drops in the middle of your long running RPC call. . . say due to a firewall or proxy timing out the connection?

    With standard messaging you would get a fault on the client. With reliable messaging, the client should seamlessly connect up again to the server and receive the result from the RPC call.

    Disclaimer: I work for Adobe.

  • # Posted By paulH | 9/14/11 2:48 PM

    not sure if this applies to LCDS on the back-end but i've seen non-LCDS remoting calls get batched together & if one call failed, all the subsequent calls in that batch fail as well (which i guess is more evidence that the remoting calls are synchronous--not that you needed it).

  • # Posted By Luther | 10/3/11 8:18 PM

    I am looking for a Cold Fusion programmer to help fix error in an existing code.