One of the fun aspects of this project with Flex front end and Java backend is that I have a client who is paying me to learn something new. I know what the pieces are that I need to have, but I've never actually played with hooking up Flash to remote backends, or any of this "java remoting" stuff before. I know enough to manage a project, but have no previously developed skill at implementing something like this using this particular set of tools and technologies. But I've been wanting to try this.
So what is the first thing to do before learning how to do this? Of course! Find a deep pocket, uh patron, uh, I mean client, to sell on some idea that they want so badly that they get desparate to have me do this for them. Viola, full scholarship, plus a stipend, to attend the Rube Goldberg School of majoring in "I think this might work software architecture" with a minor in "on the job hacking with new technologies I've never tried before".
Don Lancaster and Wayne Green should both me proud of me. You know composers in the ancient times did this via their patrons. "I've got this idea for something that I think will sound nice at your next dinner party, will you pay me a bunch of money to go off and write it down?"
|
Do you realize how much music those guys like Mozart, Bach, Beethoven, etc. wrote? Bach wrote hundreds of Cantatas, Masses, Chorales, suites, organ works, keyboard works, Goldberg variations, chamber works, Concertos, Sonatas, "complete works" on 153 CD's, Dvorak the 40 CD's of masterwork, Chopin the 17 CD collection, Berlioz 11 CDs worth, Pachelbel 10 CDs, Gershwin 8 CDs..... Now I understand the Star Trek episode where Commander Data was in his quarters, and Geordi comes in to his quarters and hears this racous din of music, and Data explains he is listening to 8 different pieces of classical music at the same time, (while of course also computing a new dilithium crystal matrix to improve efficiency by 0.0053%). Even at light speed, there isn't enough time to listen to all the stuff those guys cranked out for their patrons. Imagine how many more CD's there would be if anyone cared to record the drinking ditties of the peasants? I know, they just sang because they were drunk and were trying to forget about how little they were being paid because the Lord of the manor was giving so much to some guy wearing funny clothes and a white wig to write music that the Lord could use to impress his paramours. So do I write Java because I am patronized, drunk, or poor? And what does this have to do with remote objects in Java? |
"Actually, I'm capable of distinguishing over 150 simultaneous compositions. But in order to analyze the aesthetics, I try to keep it to ten or less" |
Well, lets talk about why I am creating a project with an Air/Flex/Flash front end, and a java back end.
Flash/Flex/Air is a single threaded language. Within Flash you can't have multiple threads. However you can do things asynchronously. That is different than synchronously which is the way most programming you are familiar with does things. Synchronously is doing something directly like calling a file open, and your program is blocked until the operation finishes, at which point the line in your code after the file open executes. Whether the file open succeeded or failed, your program doesn't get control back from the file open call until the result is known. This is also known as "blocking", or program is blocked until the call finishes.
Asynchronous calling is different. It is driven by event handlers. Instead of just opening a file and going on about your program logic, instead you setup one or more event handlers to handlers to get triggered based on the results of the file open. You then call the open, and the call returns immediately to your code before its even known if the file is available. Your code can continue doing other things. Meanwhile something somewhere else (in the operating system, or in a runtime library), is figuring out if it can open the file. If it can, your success routine is triggered. If it fails, the failure routine is triggered. Note that the success and fail routines might be the same routine, maybe the routine receives a success/fail parameter let it know whether the operation triggering the event was successful or not.
Now typically, when you're working with your own machine, synchronous programming is just fine. Things like file opens will happen instantaneously, and it's your own processor doing all the work anyhow (except for some waiting on things like the I/O subsystem in your hard drive to respond), so there isn't really much idle time for your program to do something else, and there is no reason not to just wait for the result.
Network I/O is probably the first exposure a programmer has to asynchronous, or non-blocking, I/O. You setup everything needed to connect to some resource, you make a call to connect to it with causes your program to eventually calls the sockets library. The sockets library gets the info about what you want to connect to, then returns control to your program, while the sockets library does whatever is necessary to open a connection with some remote resource. This operation might take 10's of milliseconds. Your program does other stuff, like handling screen I/O, moving characters in a game, updating an animation, whatever, while waiting to know if it is a winner or not in getting a connection to the remote resource. Eventually your event handler is triggered, and your program that figures out what to do next.
One of the issues in doing windows programming is that the I/O to the screen and from the user via mouse keyboard etc., is all event driven. Messages are passed into an event loop in your program that tells your program what to the user is doing. Your program processes a message (mouse moved to the right), your program figures out what it wants to do with the message (hmmm, mouse now over a button, lets change the visual state of the button to invite the user to click it), then goes and gets the next message (mouse clicked), and your program figures out what it wants to do with it (hmmm, they clicked the button, ok call the eventhandler for that button to handle the click), then get the next message, process it, etc.
When there are no mesages to be processed, your program can do some "idle" time processing. Whatever item time processing your program does, or whatever work it does in response to messages, needs to be short and quick, so that the message queue can be checked again for the next message. If you have long running operations in between checks of the message loop, the UI will feel laggy. You'll do things, and the program will respond in fits and jerks. The top priority of a GUI program needs to be responding to the user interactions.
In most programming systems, if you need to do a long running task, like render a page for printing, when the user hits OK to the print dialog, your program spawns a background thread to handle the processing for that. Meanwhile your foreground thread goes back to handling the message loop. Sometime later that thread asynchronously notifies your foreground thread, by putting a message in it's message loop queue, that the printing operation has completed. Your programming code that handles the UI can then figure out what it needs to do in response to that.
By keeping the long running tasks off the main thread that handles the message loop, your program will be much more responsive to the user. Your program is also much more complicated in that there needs to be synchronization between the main thread and other threads. They can't simultanously access the same status variables, for example. And in Windows, background threads should never interact with the UI directly. They can't use a pointer to a text box and directly call windows to put text in the text box. That used to cause big problems. Environments like .NET make sure that only the UI thread gets to call UI objects and tell them what to do. The other threads must pass messages to the UI thread.
For Seymour's project I need to do a lot of heavy duty text parsing, and also setup and handle multiple simultanous web connections. Flash can handle the multiple web connections, via asynchronous network operations. But it doesn't have multiple threads, and can't spawn a thread to handle the parsing of the incoming data. I could figure out how to make a queue of the pages coming in, and setup a routine that picks a page to work on, parses part of it, then returns, then gets called against by the message loop when there is nothing else to do to parse a little more, returns, gets called again, etc. By breaking the parsing into little slices, it could get done without pausing the event handling for long lengths of time, and causing the UI to freeze. Since a Flash program is single threaded, all the UI interactions, network interactions of getting web pages, etc, is all happening via messages passed to it's one message loop.
In the Websleuth project I wrote for Seymour, it was written in C++ and had the advantage of multiple threads. I could create threads to handle their own message queue of dealing with the network, so those events didn't need to get dispatched by the main message loop. I could have other threads working on processing documents that had arrived, working from their own queue of work to do.
But I still had to be careful on the UI thread. Loading a tree control, or a list box, with thousands of items, might cause a noticable pause in the UI. I would have to do part of the task, return control to the event loop, and then on a timer tick event sent to the message loop (or on an idle handler), get control again, do a little more of the task, return control, etc. In order to get things done quicker when the user wasn't interacting with the UI, I would do things like peek in the message queue for UI events, and if there were none, I would do a little more work on the task (add 50 of the 10000 items, instead of just doing 10 before returning) to get the operation done quicker.
For Flash, I dont want to get into this level of complexity. It is a slower language, and I dont know if it gives me the same abiltiy to peek into message loop queues, and it is single threaded. Flash gives a higher level abstraction, so generally I dont have control of the message loop, I probably dont want that. There is a lot of complexity. For example, for things like UI messages, they "bubble" around the hierarchy of UI objects in my program ("Oh this item doesn't want the event, ok, lets check if it's parent wants the event, nope it doesn't want it, lets check these children, those parents" ad nauseum...)
Also I want the front end for Seymour's program to be able to do it's processing on a server, instead of the client. Since ActionScript (the language of Flash), isn't really available to run on a server (some third parties have setup systems to run actionscript on a server), I need to use a more conventional server language. I decided against C# because I dont want to require a Windows server to be used. (Yes, I know Mono is available to run C# in a linux environment, but I dont want to hassle with someone's imperfect dialect of C#.NET). So I decided to choose Java.
One of the things I do want for Seymour's project is that it can run in a stand alone mode, not requiring a server. Which means all the server code needs to also be able to run on the clients computer. The Flash UI code would, instead of calling a remote server, just use localhost to call the same code running on the users own machine.
I decided to use java. The java code can have multiple threads, do all kinds of complicated processing, some time consuming, and not affect the UI of the user. The same code could run on the users machine, or on a remote server, or even on several remote VM's in the cloud, all working together, to process results and send them back to the user's UI.
So I packaging my java code in Tomcat java container so that it can interact with the internet, receiving commands from the internet, and sending its responses back on the internet. The tomcat package containing my java code can be on a server, or on the users own machine.
Adobe provides an open source library called BlazeDS that lets Flash/Flex/Air programs easily make calls into java objects and routines. BlazeDS is added to tomcat, and intercepts all the specially formatted communication urls, handling all the logic to deal with them, figure out what java objects the Flash program wanted to deal with, creating those objects, translating parameters from Flash and then passing them to routines on the object, then getting the results, serializing and sending them back to Flash, some Flex code on the flash side turing those responses back to Flash objects, etc. It's a lot of layers for me in my flash code to call "About.getInfo()" and have that routine within a remote java object get executed.
Here's the new problem I am having that I haven't seen talked about in any of the books or blogs I've been reading about all this......
So far I have two projects:
- 1. Front end Flash code for UI
- 2. Back end Java code to run in the server
I can set breakpoints in the java code.
I've setup the Flash code to call the Java objects to do things. I can set breakpoints on the java objects. I'm having lots of fun stepping through the java code I wrote. Eventually, my routine is ready to return its result. I click "Run -> Continue" to let the result return to Flash.
Meanwhile, the Flash UI has already timed out. It got tired of waiting for me.
oooops....
So I found a requestTimeout that can be configured in Flash to zero, which means no timeout. Yeah! So lets add this to my code:
// When debugging, prevent timeout _remObj.requestTimeout = 0;
Recompiled my front end, ran it, let it call java, I played in java, let the results return, and got this into my failure handler: "error: NetConnection.Call.Failed: HTTP: Failed"
Great.
Wonder how long I am getting... I set my UI where I could see it, and moved my java debugging windows away from it, and decided to time this. Click the button in my UI to make the call, thne I'm in java, stepping around, waiting to see what happens in the UI. 30 seconds later, while I am still debugigng the java remote object, my Flash fault handler is called "error: NetConnection.Call.Failed: HTTP: Failed".
So even if I verify my java routine is ready to return the right results, now it's too late, the UI no longer cares.
So this is not just debugging. It's more like safecracking....
lovely... just lovely....
![]()
// When debugging, prevent timeout _remObj.requestTimeout = 0;
Here's the documentation for that field:
"mx.rpc.AbstractService.requestTimeout(value:int):void Provides access to the request timeout in seconds for sent messages. A value less than or equal to zero prevents request timeout"
So what part of "prevents request timeout" is flash not understanding?
I just realized it might not be Flash's problem. There are other places that could be setting a timeout. Maybe something in Tomcat pounced on this request. Or something in BlazeDS. Who knows.... Hope it wont cost too much to find out.
Sure glad I'm not doing this as a fixed price project.....
Do you think Mozart had to spend time debugging his piano? Maybe that's a thought more tools developers should have in mind....
1 Comment
comments.show.hide-
- Solution for RemoteObject Timeouts while debugging Java Remote Objects From Flash Flex Air Applications
-
Permalink
Add CommentJun 09, 2011
Garnet Chaney
Hooray! A solution!