File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes synchronization of serialized object between application instances Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "synchronization of serialized object between application instances" Watch "synchronization of serialized object between application instances" New topic
Author

synchronization of serialized object between application instances

Chrissy Simpson
Greenhorn

Joined: Jul 17, 2002
Posts: 22
Hey everyone. I have a singleton class that reads a serialized object and also writes the object back to disk throughout the execution of the app. My problem is that I want to run multiple instances of this application and have any changes made to the serialized object by one instance realized as quickly as possibly by the other instances. I could accomplish this using brute force and implementing a thread which reloaded the file from disk all the time but this solution would slow down the execution of the program and I don't want that. The best solution that I could think of would be to share the instance between virtual machines but I have no idea if that is possible. Anyway, does anyone have any suggestions?
Vin Kris
Ranch Hand

Joined: Jun 17, 2002
Posts: 154
Well, hmmm... I just thought this out and have no idea about the feasibility. You may use RMI to achieve the notification between your multiple applications when the serialized object is modified.
Here goes,
1) Every instance of the application binds an RMI object on the registry with an incrementing counter. You can use Naming.list() to get the number of existing objects available and then register an RMI object with name as (say) "RMIObject" + (Naming.list().length() + 1).
2) The value of the number(counter) at the end can be stored as a global varaiable in each application instance. Therefore, if you have 3 instances of your application, you'd have 3 objects bound in the registry with names RMIObject1, RMIObject2, RMIObject3 and each application instance would have global variables having values 1,2 & 3 respectively.
3) Your singleton class should have a lock mechanism, which if set, will put the threads accessing the singleton class in a wait state. This lock indicates that the serialized object is in the process of being modified. This modification shouldn't take too long.
4) Say you application instance 1 modifies the serialized data, then it can write the data back into the file, or better, send the serialized object data to the other application instances through RMI. This application would again do Naming.list() and get the list of objects bound in the registry that do NOT end with number stored by this application. Then a RMI call would update the data in each of the other applications with the modified serialized object.
5) The other application, say instance 2, would have a RMI thread spawned when a request is sent from application instance 1. This thread should reconstruct the serialized object - either from the object obtained thru the RMI call or by reading the file. This re-constructed object should be stored as a temporary variable. Then you'd have to set the lock on the singleton class, update the serialized object, and then release the lock.
BUT, I have to question your requirement since the other application instances may have threads already executing with a reference to the singleton object. If you update the serialized object in the singleton, then you'd have a scenario where few threads would execute partially with a modified serialized object. This can ofcourse be circumvented but do you really need to do this?
Another problem I can immediately forsee is the concurrent modification of the serialized object by multiple application instances. This would just make the logic of maintaining the integrity of data between applications more messy - which modifed object would you choose? Like i said, do you really need this?
Let's see what others have to say.
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
The easiest thing to do is to check the timestamp on the file before you do anything - if it has changed then re-read it.
Or, if you don't mind a tiny bit of latency you can use a background daemon thread to check every few seconds for timestamp (or checksum or whatever) changes on the file - trigger a reread when something changes.
If the applications are updating the file often, then I think the main problem here is preventing collisions when two applications try to write at the same time. The classic way to do this is to use a second file whose existence signals that the main file is "locked". But even that can probably get messed up.
Chrissy Simpson
Greenhorn

Joined: Jul 17, 2002
Posts: 22
hmmm, both very good ideas. Here is some more information and also my thoughts on the problem.
To give you some more specifics, the object that I am serializing is a hashmap containing strings for both key and value so it is not really a requirement that I use serialization, I could just save strings to disk. I don't think that really simplifies the problem but it may make the problem domain a little clearer. Also, the singleton class is in charge of managing access to a repository and, as you probably expected, the hashmap contains items that are in the repository and the repository is shared throughout instances of the application. So, there will only be two operations that happen on the hashmap: an addition or removal of an element.
I was thinking last night that I might be able to use sockets. Since I am not all that familiar with RMI but have done a bit of socket programming, this was the only solution I could think of. If sockets were used then each instance of the application could have a server and a client. If an update is made to the repository in "instance 1" then the server on "instance 1" would write the change to the socket. All listening clients (other instances) would receive the the change from the socket and update their own repository. Once "instance 1" had successfully sent the request, it could write the file to disk for any new applications that may start up. I would just need to use a locking mechanism on the file from the time the change is sent to when the file is finished being written. I would also need to ensure, that no other instance repository tries to update at the same time as "instance 1". I could do this by only performing an update if the file is not locked. If it is locked then the registry waits for the lock to be removed before it writes the change to the socket. Does anyone see any problems with this?
If this does seem to work, then what should I write to the socket? I could do something cheezy like write a string put;key=value and remove;key=value and then have the client parse the string. I dunno.
Is this easier to do with RMI? Maybe RMI alleviates the previous question because you could invoke different methods...
This doesn't have to be completely robust although I would like it to be... As is usually goes in this industry, I don't have a lot of time to do this so I am trying to keep it as simple as possible.
Anyhow, any suggestions are welcome.
Vin Kris
Ranch Hand

Joined: Jun 17, 2002
Posts: 154
hmm.. your solution using sockets is very similar to the solution using RMI. I had just done some test programming using sockets when I was in the learning stage... so I cannot give you a suggestion based on comparison. But implementing this is pretty simple in RMI.
The method of monitoring the file modification timestamp is definitely classic... but I wasn't able to get to a satisfactory solution to ensure concurrent modification wouldn't fail. So I ended up with a rather elaborate process of using RMI, but it seemed dependable. Using RMI, a singleton lock manager could be maintained in any one of the instances which could indicate that the file is in the process of being modified.
Maybe, if you sit down and whack your brains you can implement the solution suggested by Dave... but it sure is gonna be tricky. and fun.
Dave Landers
Ranch Hand

Joined: Jul 24, 2002
Posts: 401
To do this using sockets, I'd probably have a well-known (to your app) port number. When you start an app, check that port, and if there's no server running, then that app becomes the server. All subsequent clients would connect to that server. The server is the only one that can read/write the file - everyone else gets their copy from the server. If the server goes away, then one of the clients would have to assume that role.
The implementation with RMI would essentially be the same. Some of the details change, but the concept is the same. Main difference with RMI is you would not have to invent a protocol - just make method calls.
Another option is to have a background daemon program (not one of the apps) to be the server. You have to arrange for how to get that thing running, but then the ownership of the file is easier (not passed from app to app).
Chrissy Simpson
Greenhorn

Joined: Jul 17, 2002
Posts: 22
Thanks for your help guys... I think that RMI seems to be more fit for this situation than sockets. I think I should be able to come up with a cleaner solution using RMI. And, since I like learning new things, I think I am going to give it a try. I have some more things that are higher priority so I won't be doing it right away but I think I can take both of your suggestions and come up with something that'll work. Thanks again....
Chrissy.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: synchronization of serialized object between application instances