Perry Board

Greenhorn
+ Follow
since May 03, 2003
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Perry Board

Thanks for the reply. I'll read up a bit more on JMS.
With a J2EE app server, would I be correct to use JMS if I want to notify a group of clients when data on the server has been changed?

For example, 10 Java application clients (or applet clients) simultaneously connect to the app server using EJB and get a view of the current data. If the data is changed by another client, it would be nice to send a message directly to all the clients, notifying them of the change so they can get refreshed data. This keeps the client from needing to continuously contact the server over and over again to see if the data has changed.

So let's say a Session Bean performed the data-changing operation on the client's behalf. It would then create a new message and send it to the app server for a message topic. All the clients would be message consumers who listen to the app server to receive messages of this type. So there's no Message-Driven bean here, right? I'm just using the messaging services of the app server?

Isn't the client, as an asynchronous message consumer, still continuously (or periodically, depending on frequency) contacting the server to check for messages? Would having a high number of clients then have a heavy burden on the server? Would it be better for the client to somehow send a reference to itself via RMI so an EJB on the server can directly contact the clients who are "logged in?" How would you store this list of Remote objects?

Thanks for any tips.

(I deleted my message from the distributed java forum and posted here.)
Thanks, everyone, for such great discussion. I passed with a 350/400 (new Urlybird hotel assignment). Some details:

Obviously, I don't have any details of WHY I missed points in GUI and locking. I'm trying to think of some controversial topics in these areas that I might report my choices...
I used worker threads in the GUI and popped up a modal dialog during lengthy search operations. I allowed simple sorting of records by clicking the header column of each field. I allowed a checkbox for "bookable only" that filters out records not in the 48 hour time window for booking or already booked.
For locking, I stored locks in a single static Map associated with the data file used and handed out new instances of Data to each client, storing a unique ID number and record number pair in the static collection. I also used an auto-timeout method (TimerTask) for automatically unlocking records after a few minutes.
Thanks again. Good luck to others.
21 years ago
In my testing I also had some connection exceptions but it appeared to be simply a result of rapid repeated connection attempts (loop that spawns 100 threads all trying to contact the RMI registry for a connection). If I put the thread to sleep for a fraction of a second in between connection attempts, it appeared to work ok.
I can relate to this. My decision was to provide an interface that the database or client could query for information about the schema. Since the field names and positions can be parsed from the data file header, you can return a list to the GUI so it knows which columns contain which fields. This allows it to be flexible in case the data file adds additional fields later.
I wrote a specific implementation of this interface for the UrlyBird schema, which implements the methods that the database or client might use to get information about the file format (number of fields, record length, etc). The database doesn't care what fields are in the schema, and the GUI can work with any data file that has its minimum set of fields ("city", "hotel", etc.)
[ June 26, 2003: Message edited by: Perry Board ]

In the example you cite, the user can find the exact match of "Fred" - it just happens to be returned along with the inexact match of "Freddy". I don't see a problem with this; the requirements are vague enough IMO that this should be acceptable.


I disagree with this. The requirements may be vague, but "exact-match" seems to me to be mutually exclusive to "nonexact-match." If your GUI shows "Freddy" which is NOT an exact match, then it is failing in that requirement. I think the concept of additional filtering is necessary in order to meet both requirements of the interface (begins-with) and GUI specification (exact).
I have 19 classes/interfaces, not counting inner classes. I've kept them all in suncertify.db, not really thinking about separating into subpackages. Are other people using different packages?
I can't imagine doing this with only 5.
Thanks Max, but maybe I wasn't clear on my question:
I have a method that runs in a worker thread. Something like:

So the method that creates that new thread has already returned. If doLengthySearch() gets an exception, it has to either store the error in a variable somewhere or explicitly call a method on the gui controller to say there was a problem. It can't throw the exception because there is no one to catch it.
So my question was whether this is a common thing in a multi-threaded application, having to store an error flag that marks a task as failed.
I know people have said to strictly follow Sun's coding standards, but this one is just hard for me to completely comply with:
"Don't wait to declare variables until their first use..."
I completely agree for MOST methods, but when you are creating Swing gui's, I feel like it makes much more sense to keep the declaration close to the use.
For example, in creating a menu bar, you might have three different menus, each with several menu items. By Sun's standard, you declare all of those swing components at the top of your method, then manipulate/add them later. This has the effect of jumbling up everything so that if you want to remove a single menu item you have to scour the entire method and carefully extract it from the declaration section like picking fishbones out of your dinner. "Which JMenuItem was that? [scroll, scroll...] Oh, you want to change the color of that JLabel? Now you'll have to declare it at the top of your method so you can hold it in a variable temporarily."
Ugg. Anyone have a comment? I hate to break the standard, but I think it also breaks the rule of code clarity to do it the "correct" way.
Why do you want to circumnavigate this dependency on unreferenced to unlock the record? Since unreferenced is indeed called (not sure why yours isn't), you can unlock there and be protected from the most dangerous case of records being locked for days at a time.
The reason I'm not worrying about this is that for my assignment (hotels), I lock, update, and unlock in sequential statements. I don't have the client locking a record, then waiting for user input, which could be indefinite and offer time for crashes. The odds of a crash in between the locking and unlocking calls AND another user requesting a lock inside that unreferenced timeout period is so small that it's not worth the added complexity to worry about it much.
If in your assignment, you lock and pause for input or something that could provide a greater chance of a crash, and you don't want the user to ever have to wait very long for a record, one option might be to check if a record is already locked before attempting to lock it. Your gui could inform the user that the record is currently being modified by another client and the user can try again in a few minutes or can select a different record. This puts the power in your client, which offers more control. You could automatically retry after a few seconds to check if it's still locked. You could offer an option to cancel. Etc.
I just think all of that is not asked for in the assignment and adds to the complexity of the project.
[ June 04, 2003: Message edited by: Perry Board ]
In my client MVC model, the Model object does its busy work in a separate thread because it can potentially take a long time. My question is how to let the gui Controller know that an exception occurred (such as the server being shut down and getting a remote exception) so it can display an appropriate dialog ("connection lost" or "search failed" or whatever). I can't throw it back to the calling method, because the whole point of the worker thread is that the calling method returns immediately so the gui stays responsive.
Right now I'm using sort of an error code, where I store a flag that marks an operation as failed, and the controller checks the error code to ensure success. It just seems like checking error codes is an old programming habit. But I thought it would encapsulate the Model a little better if it didn't have to explicitly contact the Controller to say something's wrong.
What have other people done in this regard?
Yes, I tested with unreferenced and it gets called after about fifteen minutes or so. I think someone has posted a way to adjust this timeout period, but I don't recall how it's done.
When you say, "all the while checking if HashMap.containsValue(recordNum)" I assume you mean that after this check, your thread uses wait() to allow the cpu do other things until another thread calls notifyAll(), right? In my implementation, any time any thread unlocks a record, it notifies all waiting threads so they can check and see if their locked record is now available. If it's still locked, they wait again.
I probably won't fool with adjusting the timeout period of when unreferenced gets called. I'll just document and say, if a client crashes while holding a lock, the record should become available again after twenty minutes. How often will it happen that two clients want to lock the same record at nearly the same time and one of them crashes?
What happens after a client has a lock? If you don't know who owns what lock, how can you authorize an update/delete?
Ahh. I can't say I know the proper way to use an InterruptedException, but that sounds like a decent plan.
How about this idea, too (new scenario here, I have hotel assignment, by the way):
1. Client performs a search but leaves search criteria blank to retreive all records.
2. Search indicates that 20,000 records were found. They begin to be retrieved one by one (progress bar creeps along).
3. User says, ugg, I don't want that many records. Clicks cancel, which sends InterruptedException to his own client thread that is downloading each record.
4. User adds search criteria to perform a new, limited search.
I had a similar thought but didn't know how to do a "cancel" so I haven't implemented it. (probably won't anyway, but am curious.) I was figuring the way it would work is:
1. Client A holds a record lock and forgets about it (goes out to lunch) or his computer crashes, leaving the record in a locked state.
2. Client B tries to acquire the same record lock. The thread blocks while waiting for that lock, which could be indefinitely, so the client's RMI method call is "frozen" while waiting for a response.
3. Client B's gui (which runs in a different thread than RMI calls) has a cancel button to give up trying to get that record.
The question is, what does the cancel button do? How can an RMI call be canceled? Seems like it might need to sort of "terminate" a thread. Is this even possible?