• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

NX:URLyBird1.3.2, Please comments on the Locking. Thanks!!

 
Joe J. Wang
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear all,
First need to thank you all who argue/comment on all kinds of topics for the assignment, Andrew, Mark, Max, Vlad, Bharat, Sun......, it is just a great forum. I can learn a lot here. Thank you guys!
After I asked several questions and read the replies, I thought I need to read more posts here. And I found a lot of them are just like good tutorials. And I also found that the book of Max is mentioned by many people. I got one and read it. It really gave me a big help on the project. After reading the book, I went through the instructions of my assignment. I found that all the designs (mainly on locking) in the book can be applied to the project. But I am not sure if there is something can potentially do damage to the final score. So it will be great if I can hear some comments from you.
For the locking, (if nothing wrong) I am going to do,
1) Multithreaded Data objects. (One per client, as suggested by Max's book)
2) The book() method is implemented at the server end, (with lock(), update(), and unlock() together) in order to avoid the need to track the ownership of the lockedRecord. I just want to make my solution simple. There is no Lock Manager, just a static vector to keep the locked record(the same as the one in Max's book, I am not sure why someone said a HashMap is better here). But I think that is enough for the locking implementation, although I don't know if there is some potential risks to use it, since SUN replaced the assignment with this new one.
3) For the Database read/write, I will not do cache. I think a syncronized File for read and write from/to database is simple and can prevent dirty read. I think the difference of the performance on cache or reading/writing DB directly is not a big deal for the assignment.
Am I right?
Thanks a lot!
Joe
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Joe,
This looks quite reasonable so far. Good luck with it.
With respect to "someone said a HashMap is better here" - this is not a case of one collection is best for everyone. (Personally I used Sets for my locking.) It all depends on how you are tracking ownership of your locks.
Since it appears that you are not tracking ownership of locks, perferring to ensure that clients cannot call the unlock method themselves, you can probably get away with a simpler collection.
Regards, Andrew
 
Joe J. Wang
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Andrew,
Thanks a lot for your reply and comments!!
I know you are very busy, but if you have some time, would you please see another question about the GUI? Thanks!!
My GUI question
Best,
Joe
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Joe,
I have EARLy Bird 1.3.1, and I started coding my locking strategy same as you are doing. In the meantime Max/Andrew explained to me patiently why that wasn't enough and appropriate for this project. I ended up using a WeakHashMap. If you go through the following two threads, you should be able to see and work through, how I went about developing this strategy. I have to caution you though, I am not familiar with what variation Sun has put in for URLy Bird 1.3.2. If you post your interface (DBMain or DBAcess or whatever it is called), we should be in a better position to advice you.
Here are the two threads that I mentioned above:
NX: URLy Bird 1.3.1 Hashmap (or Hashtable)
About data consistent
Actually, the second thread was initiated by Davidd Smith, I sort of stayed with it. This should be a good thread for you to follow through.
Regards.
Bharat
 
Joe J. Wang
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat.
Thank you very much for the reply!
The following is the DBMain interface of my assignment.
package suncertify.db;
public interface DBMain {
// Reads a record from the file. Returns an array where each
// element is a record value.
public String [] read(int recNo) throws RecordNotFoundException;
// Modifies the fields of a record. The new value for field n
// appears in data[n].
public void update(int recNo, String [] data)
throws RecordNotFoundException;
// Deletes a record, making the record number and associated disk
// storage available for reuse.
public void delete(int recNo) throws RecordNotFoundException;
// Returns an array of record numbers that match the specified
// criteria. Field n in the database file is described by
// criteria[n]. A null value in criteria[n] matches any field
// value. A non-null value in criteria[n] matches any field
// value that begins with criteria[n]. (For example, "Fred"
// matches "Fred" or "Freddy".)
public int [] find(String [] criteria)
throws RecordNotFoundException;
// Creates a new record in the database (possibly reusing a
// deleted entry). Inserts the given data, and returns the record
// number of the new record.
public int create(String [] data) throws DuplicateKeyException;
// Locks a record so that it can only be updated or deleted by this client.
// If the specified record is already locked, the current thread gives up
// the CPU and consumes no CPU cycles until the record is unlocked.
public void lock(int recNo) throws RecordNotFoundException;
// Releases the lock on a record.
public void unlock(int recNo) throws RecordNotFoundException;
// Determines if a record is currenly locked. Returns true if the
// record is locked, false otherwise.
public boolean isLocked(int recNo)
throws RecordNotFoundException;
}

I read those two threads. They are very helpful! But I have a question for you. You said
I have EARLy Bird 1.3.1, and I started coding my locking strategy same as you are doing .

And finally you ended up using a WeakHashMap. I guess that means you will let the client call lock, read, update, and unlock. Is that right? If so, would you please explain a little bit on why you choose to let the client call those methods to do a BOOKing. It seems calling the lock/unlock on the server end is not as good as calling them on the client side, but I don't know why, to reduce the load of server? But I think it increase the network traffic and make the solution more complex.
Best,
Joe
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Joe,
I have the same DBMain interface for URLy Bird 1.3.1.
You wrote:

I guess that means you will let the client call lock, read, update, and unlock. Is that right? If so, would you please explain a little bit on why you choose to let the client call those methods to do a BOOKing. It seems calling the lock/unlock on the server end is not as good as calling them on the client side, but I don't know why, to reduce the load of server? But I think it increase the network traffic and make the solution more complex.

Quite correct! Let us define what a client is within this context. I have the Data Class that implements the DBMain interface which has a reference to DataSchma class. Therefore, the Data class is said to be the user of the DataSchema class. Similarly, I have a DataAdapter class which holds a reference to and instantiates an instance of the Data class. This instance of the data class is a private instance variable in the DataAdapter class. Therefore, DataAdapter is the CLIENT for the Data class and they both still live on the Server. There is an RMI implementation class that holds a reference to the DataAdapter class. For each client connection from the other side, i.e., the GUI client side, a unique instance of the connection class will be created which will hold a unique instance of the DataAdapter class which will hold a unique instance of the data class.
Therefore when we say that the client is calling the lock, read, update, unlock methods; we really mean the DataAdapter class calls these methods on the instance of the Data class that it holds a reference to. But this is entirely server side locking. The term CLIENT is quite polymorphic and it is best understood within the context it is used in. Another complicating factor is that a number of us (not you and I) obviously are doing the Contractor or the oder FBN assignment which call for the Client from the other side of the network to do the locking, this makes it doubly confusing. I am quite clear on the fact that I am doing the Server side locking. If I am wrong, may be Andrew will correct me?
Cheers.
Bharat
 
Joe J. Wang
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat,
For the "client", what I mean is the Client site in the Network mode(I will choose RMI to do the network), I mean another Java VM different from the server.
I am not sure if there is Book method in your DataAdapter class or not. If there is, I guess in it you call lock, update, and unlock methods, right? If it is true, I think there is no need to use a Map structure in order to keep track of the ownership of the LockedRecord and to handle the client crash. Am I right? Andrew, Max .... please help us out...
Thanks,
Joe
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Joe,
You wrote:

For the "client", what I mean is the Client site in the Network mode(I will choose RMI to do the network), I mean another Java VM different from the server.
I am not sure if there is Book method in your DataAdapter class or not. If there is, I guess in it you call lock, update, and unlock methods, right? If it is true, I think there is no need to use a Map structure in order to keep track of the ownership of the LockedRecord and to handle the client crash. Am I right? Andrew, Max .... please help us out...

I understood what you said correctly. In the client/server mode we have client in a separate JVM connecting via RMI (I am doing that too) to the server JVM. There indeed is a book method in my DataAdapter class which calls the lock, read, update, unlock methods on the Data class. If you don't use a Map structure how will you keep track of the fact which instance of Data ->DataAdapter -> and here is the key --- corresponding instance of RoomDatabaseImpl class which is a proxy for the client on the server side when using RMI, and the calling client class (for example GUIController). Now when a remote client (GUIController) crashes, it will invalidate the RoomDatabaseImpl (you can call it anything that you want, but this is the class that people are calling the connection class on this forum). This class implements the RoomDatabaseRemote interface in my design. Now, RoomDatabaseRemote interface extends both Remote and DBClient Interfaces. The DBClient Interface defines business methods such as book, findRooms etc. This is an interface defined by me, the assignment doesn't provide one or require one. But this sort of design is a good thing since my DataAdapter class also implements this interface. I am assured of the fact that the business methods will exist both in local and server mode. Note that the program directly instantiates a DataAdapter class instance when working in local mode.
This design is well explained in Max's book. Perhaps I am not doing a good job of explaining this to you. Time to call the experts - Andrew, Max, Jim, Phil anybody.
Joe, if you have a specific question on any of my comments, I will be happy to answer it anytime.
Regards.
Bharat
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Joe & Bharat,
For a start, you should be aware that there are 3 major assignments (airline, contractor, and hotel) and that each of these have multiple versions with minor differences. So it is often difficult at a very high level to work out what will work for one person compared to another - their instructions could be different. Now that we are down to the detail of what is in the interface, we can be a bit more specific in the answers.
I am not sure if there is Book method in your DataAdapter class or not. If there is, I guess in it you call lock, update, and unlock methods, right? If it is true, I think there is no need to use a Map structure in order to keep track of the ownership of the LockedRecord and to handle the client crash.

It depends on how you interpret the comment given for the lock method "Locks a record so that it can only be updated or deleted by this client.".
If you interpret that as meaning that the Data class has to track ownership of the lock, then you will almost certainly want to use a Map structure within the Data class to track ownership.
Personally I suspect that this is the correct interpretation. The instructions specify that automated testing may occur. The only place where that can occur is with the Data class which implements the specified interface. So if there was an automated testing tool that simulated multiple users modifying records, then you would have to have your Data class tracking ownership.
Regards, Andrew
 
Joe J. Wang
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat & Andrew,
Thanks a lot for the replies! Finally, I see your points, why there is a need to use the map structure.
I have another question on the DB read/write. I noticed that Max said dirty read is not a problem for the Hotel assignment in a previous thread. As long as the locking system can prevent multi-writes on the same record happened, (there can be the situation that multi-clients write to different records in the same time) the design is OK. I am not sure in comparison with a syncronized File which allow only one read or write at one time(the performance is poor), which one is reasonable for the assignment? (The instruction doesn't tell the requirements of either the performance or the dirty read.) Do you have any suggestion on it?
Thanks,
Joe
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Joe,
In general if you have to make a choice between simplicity and performance, go for simplicity. This is quite often true in real life, not just this assignment: it is all too easy to start trying to improve performance in areas that are not real bottlenecks.
The instructions tell you this with the statement:
A clear design, such as will be readily understood by junior programmers, will be preferred to a complex one, even if the complex one is a little more efficient.

So go with whatever is simplest to code that does protect you from two clients writing at the same time.
Regards, Andrew
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic