This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Terminating the server Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Terminating the server" Watch "Terminating the server" New topic
Author

Terminating the server

Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi,
my question is about: What do you do on the server with the threads that are currently processing client request when the server is to be closed?
It could leave the database in an inconsistent state (in de middle of a create or update operation..., with half of the record updated or created)
my server has:
A window (main thread of execution)
A NetworkServer (started as a thread when the server app. starts)
NetworkServerThread (Started by NetworkServer to process a request)
NetworkServerThread (Started by NetworkServer to process a request)
NetworkServerThread (Started by NetworkServer to process a request)
NetworkServerThread (Started by NetworkServer to process a request)
NetworkServerThread (Started by NetworkServer to process a request)
NetworkServerThread (Started by NetworkServer to process a request)
I was thinking about keeping a list of the NetworkServerTread that are currently running. The NetworkServerThreads add themselves to the list when they start and remove themselves when they finish. (this section will have to be synchronized)
When the user asks for the server to stop, I do networkServer.interrupt()
to stop the NetworkServer from spawning new NetworkServerThread(s)... And scan the list of NetworkServerThread, doing thread1.join(),thread2.join(), etc...
This way, the server will terminate, but not before all the tasks already started are finished...
What do you think? Is it too much for the assignment?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

Hi Yanick,
I think it is an excellent idea to ensure that you do not stop your server in the middle of a write operation.
Rather than tracking every single thread that is running on your server, you could consider that the only things you are worried about are write operations. So you only need to track whether threads are currently in a method which does a write operation.
You would probably also want to set some sort of flag so that threads do not start write operations while you are trying to shut down.
You might also want to consider removing your service from the registry so that no new clients can connect while you are in the process of shutting down.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi, yes, it would be more simple to use a flag. I was thinking, all data acess methods of my instance of the Data class are synchronized. So, if I could obtain the monitor on this object, it would mean that no write operation is taking place right now:
synchronized(data)
{
System.exit(0);
}
As for the flag, I could set it to a value when I want the server to shut down, the NetworkServer thread should check this flag and refuse new connections if the flag is set.
For the registry, I think that you are talking about RMI, I use sockets.
Thanks for the support! (and please correct me if something seems wrong in what I said!)
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi Yanick
Originally posted by Yanick Labelle:
Hi, yes, it would be more simple to use a flag. I was thinking, all data acess methods of my instance of the Data class are synchronized.

Just curios, do you mean synchronizing of Data in adapter class which access Data methods? Or do you mean synchronizing on RAF in Data itself? If its latter case, I am not sure of how it works as you said.

So, if I could obtain the monitor on this object, it would mean that no write operation is taking place right now:
synchronized(data)
{
System.exit(0);
}
As for the flag, I could set it to a value when I want the server to shut down, the NetworkServer thread should check this flag and refuse new connections if the flag is set.
For the registry, I think that you are talking about RMI, I use sockets.
Thanks for the support! (and please correct me if something seems wrong in what I said!)
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi, yes, I synchronize on the Data class, in the adapter class. The data access methods of the data class (read,create,update,delete,find) are all marked as synchronized. If I'm not wrong, when I call one of these methods on my data object, it automaticly synchronize on the data object. I nead the monitor on the data object to call one of these methods.
That was the reason for the
synchronized (data)
{
...
}
on my main thead of exection, if I can obtain the monitor on the data object with this command in the main thread, it means that no other thread is accessing the data access methods of the data object right now, also, no thread will enter one of these methods while I'm in this synchronized block because they also need the monitor on the data object to do that. It leaves me with enough time to close the data file and terminate the server.
As always, correct me if I'm wrong... Threads and synchronizing are not an easy subject for me even if I had a good score at the programmer certification exam.
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi Yanick
Originally posted by Yanick Labelle:
Hi, yes, I synchronize on the Data class, in the adapter class. The data access methods of the data class (read,create,update,delete,find) are all marked as synchronized. If I'm not wrong, when I call one of these methods on my data object, it automaticly synchronize on the data object. I nead the monitor on the data object to call one of these methods.
That was the reason for the
synchronized (data)
{
...
}
on my main thead of exection, if I can obtain the monitor on the data object with this command in the main thread, it means that no other thread is accessing the data access methods of the data object right now, also, no thread will enter one of these methods while I'm in this synchronized block because they also need the monitor on the data object to do that. It leaves me with enough time to close the data file and terminate the server.
As always, correct me if I'm wrong... Threads and synchronizing are not an easy subject for me even if I had a good score at the programmer certification exam.

Thanks for clarifying. I see a case where I don't know think if it satisfies the "let current threads complete their work and then shutdown server".
Case I: When you booking record, I suppose you do a read and compare the record in the database with what CSR think is there. Reason for this is another client may have changed the record between CSR seeing results and booking. So in book method in your adapter, you might have something like this:

So what I was thinking is if the client has read the record and between the time he checks as above and your server shuts down then you are not allowing the current client to complete the operation, is'nt it? Because this client releases lock after read() and will be checking and meanwhile your server shutdown will obtain lock on Data and shutsdown right? Then it will not be allowing the complete operation of client, I think.
If this is not the case, please ignore it. And sorry for the confusion.
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Yes, you are right, but I tought that the only operation that needs to be atomic is the update(), not the entire booking procedure. If the server stops in a book operation, there are 2 senarios, the room is not booked and the user gets an error because the server didn't send back any response. The second senario is when the room is booked, but the customer doesn't get any response from the server. In both cases, the database left in a healty state. The client gets a strange response from the application, but this is also the case in real life when you shutdown the database (using an option like "shutdown immediate").
Of course, this is only an opinion, if you think that it doesn't make any sence, let me know, and I will continue to reflect on another solution than that.
Anna Hays
Ranch Hand

Joined: Nov 09, 2003
Posts: 131
Why not have a flag in the Data.java, say static boolean serverShutDown
and when claiming the lock to do a write operation, also check if serverShutDown == true?
Then on the other hand, if the lock collection is empty (assuming you keep your locks on a collection) then it is safe to shut down.
This allows the current write operation to finish and does not allows new operations before shutting down. What do you think?
[ April 16, 2004: Message edited by: Anna Kafei ]
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi,
Yes, I could have a variable that telling the server to refuse new connections. I could also have a requestCount variable which indicates me how many client requests are currently in process. When the serverStop flag is set, I'm sure that the requestCount variable will never be incremented, it will only decrement as the current requests terminate. And when the count is 0, then we close the server.
The problem with that is the following code, which I don't like much:
while requestCount greater than 0
{
sleep 1 second (or less...)
}
// Ok, shutdown now
close data file
exit server
The problem with that, to me, is the sleep. I think that this is a really horrible way to wait for an event to happen.
I like the event model (awt/swing) a lot, if someone could tell me how to implement it in a non graphic context, what I would do is:
We keep the serverStop flag from the example above, and also the requestCount. NetworkServerThreads would increment this counter by one when they start, and decrement it by one when finished... I could add a test after decrementing in each NetworkServerThread:
if (serverStop == true && requestCount == 0) fire the serverShutdown event...
In my main thread of execution on the server, I could have the serverShutdown event ready and waiting... When it is fired, it will close the data file and shutdown the server.
Questions: should I synchronize the access to the requestCount (which should be an Integer,not a primitive, I want all threads to work with references to the same counter... not a local copy). My concern was, what if two threads try to increment/decrement the counter at the same time?
Damn, I talk too much... what is your opinion? (on the main subject of the post, not the last sentence)
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Oups, this awt/swing event thing is quite stupid, I could shutdown the server directly in the NetworkServerThread:
increment requestCount
process client's request...
decrement requestCount
if serverStop is true and requestCount is zero
{
close data file
terminate server
}
Anna Hays
Ranch Hand

Joined: Nov 09, 2003
Posts: 131
Hmm I dont get why you still need to have a request count if you have the flag...
This is what I am thinking of doing
on the serverStop() method, check if the lock list is empty, if it is, shut down, if not, sleep.
On the other hand, I will stop any clients claiming any locks base on the flag. So on the old connection, when it release the lock, it will notify any thread that is waiting, the serverStop() and unlock() will have the chance for the lock while unlock() wont. So serverStop() will only get the lock IF and ONLY IF the lock list is empty and get the notification.
Anything wrong with my approach??
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi, the main problem in my application is that the lock mecanism is deeply encapsulated in the Data class, (in fact, it's in a class called LockManager, which can only be accessed by the Data class. The only interface for the outside world to the lock mecanism is the lock() and unlock() functions of the Data class (as specified by the DB interface). I think that there are 2 levels of operation on the server, the request level (a transaction), and the DB io level. The Data class represent the db io, a kind of adapter represent the request level, it will process the request by calling multiple io operations... on the Data class. The best place to control the server shutdown is at the request level, because there, you can stop new requests from entering, and let the current requests finish. You don't have that control at the Data level, which is only concerned with single IO operations like read, lock, update... So if I implement the server shutdown at the request level, I don't really have access to the lock internal structure (a collection..., private...), because it is encapsulated at the Data level.
This is why I suggested that the threads that each process a client request could increment and decrement the requestCount, and shutdown the whole server when a shutdown as been asked for and the current thread is the last one to end.
Anna Hays
Ranch Hand

Joined: Nov 09, 2003
Posts: 131
Ah I totally get it now... I was thinking of doing it in the Data.java class, but your reply made my change my mind...
Umm I am thinking of doing the counting at the remote client object tho...not the adapter, because the remote access is the only concern. So it should be separated from the local DB stuff. Any opinions?
[ April 20, 2004: Message edited by: Anna Kafei ]
Yanick Labelle
Ranch Hand

Joined: Dec 29, 2003
Posts: 50
Hi, I think that you are right, I was talking about the adapter, but here are the layers of my server:
Network server
--Network server threads
----data adapter (each network server thread share the same data adapter...)
-------Data class (the data adapter contains a Data object...)
The count is not made in the data adapter, but the network server threads.
Anna Hays
Ranch Hand

Joined: Nov 09, 2003
Posts: 131
Ah we are talking about the same thing then. I was refering to implement the code on the db adapter for the network, except I didn't call it adapter...cos I have another adapter that is used by both network and standlone, the network one is just a proxy.
Just implmemneted it, works! Here's my log...

Thanks for the wonderful discussion!
 
 
subject: Terminating the server
 
Similar Threads
Cancel request mechanism
The Server
Exam success but probably a design failure
Closing the database.
the availabilty of request object