Stephen Patrick

Greenhorn
+ Follow
since Jun 15, 2004
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Stephen Patrick

Thanks Charlie, Satish

Ok my instructions has the following that I can see relating to configuration settings:

B]Network Approaches
Your choice of RMI or serialized objects will not affect your grade, but no other approach is acceptable. In either case, the program must allow the user to specify the location of the database, and it must also accept an indication that a local database is to be used, in which case, the networking must be bypassed entirely. No authentication is required for database access.
[/B]



I take this as meaning if in server mode using either sockets or rmi the user must allow the user to specify the database location, meaning host address and port. It says nothing about configuration of the database in local model which implies the only configuration is the server. I kind of think this makes sense as how would the user using the client GUI now the file system of the server it is using. Also my package structure requires
the db file to be in the package root.

But as you say what harm can it do.
[ July 11, 2004: Message edited by: Stephen Patrick ]
Hi Mike, I am by no means an expert, but my opinion on the process.



What happens when a client wants to book a room?
They see that the room is unbooked, book it, but they can't because some one has dashed in and beat them to it. how does your update method inform them of that?




I think either way the record should always be re read when performing the book operation. Consider when a client, client A performs a search and receives a number of rooms that are displayed in the gui. Now while Client a is reading these records, Client B updates the record or books the record. Now client A wishes to book the same record but it has being modified.

Whether locking on the client or server you should abstract away the locking mechanism from the client by introducing some from of Data Model Layer such as a DataAccessObject. In my case I had this on the server as I don't need to worry about the client locking a record and crashing. So my DataAccessObject has a book method that will re read the record if it is different than the one the client has it will throw a BookingException indicating this fact.


if the client controls the lock process they can guarantee they will book the record in the state they read it.




The only way a client can guarantee that the record has not being modified is if they locked it while reading it but this will stop all other clients from using the record while it is simply being displayed and also need a complicated unlocking mechanism.
Hi

In my implementation I allow the user to modify the hostname and port through the GUI for the server, when changed the changes are persisted in the suncertify.properties and requires a restart of the app for the new connection to be initiated, if running in server mode. I do not provide any means to allow the path to the data file to be modified it is static. Do I need to allow for this path to be changed in local model. Is it ok having the db file to always be located in the current working dir.

Any suggestions

Thanks
Hi Mike

I have UYB as well which is still in progress. For my delete and create methods in my data class i simply throw a UnsupportedMethodException.

]think i understand why the gui must lock and unklock - it is so it can be certain that before a modify, the record is as expected.



I chose not to lock on the client for the following reasons. I see the cookie as being an aid for the lock\unlock process and does not need to be exposed to the client. I have a Data access object that runs on the server and contains all of the data access logic including lock\unlock. IMO I feel that this is a better choice consider what will happen if a relational db is chosen other than a data file at some point in the future would you still want to expose a lock cookie. The DAO encapsulates all db access logic therefore the client will not be impacted by a change to a relational db.


Also I only throw an SecurityException if a record is locked by a different cookie, I don't do anything if a cookie is not found I simply return as there does not seem much point as it should throw a SecurityException before getting to this stage if the cookie is locked by another client.

Regards

Stephen
Hi Tim, my assignment is still in progress and I am not an expert and others will probably have far better solutions. This is what I have done so far - it may change. I opted for a thin client so I don't need to bother about a client locking a record and then crashing. I have a BookingDataMgr DAO that communicates with the data class it calls lock, unlock etc. The booking data mgr catches any exceptions thrown by the data class and throws a BookingException. On my client my LocalConnection class uses a
BookingDataMgr, if a problem occurs it catches a BookingException and throws a new ConnectionException. For remote mode my RemoteConnection class uses a RemoteBookingMgr object which is bound in the registry this object throws a remote exceptions as required by rmi and BookingExceptions as it simply acts as a proxy delegating calls onto a BookingDataMgr class. If the RemoteConnection object encounters a problem such as a RemoteException, BookingException it throws a new ConnectionException that takes the caught exception. So I have the following design


GUI (presentation)
controller throws ControllerException
ConnectionFactory(on client) - returns a LocalConnection object or RemoteConnection - throws ConnectionException
Server with Remote Booking Object object(Remote Mode only) throws RemoteException, Booking Exception
BookingDataMgr - throws BookingException
Data throws RecordNotFoundException etc

This works ok as my data class requires the use of cookies for locking. The only problem I have is I don't like the way I have a number of interfaces with similar method signatures that differ only in the Exception type they throw. I am not to sure if this is a good or a bad thing. IMO its good as each layer is encapsulated but to add a new bit of functionality will result in updating a couple of interfaces. I am currently looking at this, but am in a rush now to finish so may leave it.

Stephen
Thanks Javini for the advice. This is an interesting problem. I think I will throw a RunTimeException and document it, its not the best solution as you pointed out but at least I can catch it on the client and don't have to worry about breaking the contract in the db interface.

Yes all of my other methods in my interface throw exceptions see below.


Your data access class must be called "Data.java", must be in a package called "suncertify.db", and must implement the following interface:

package suncertify.db;
public interface DB
{
// 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]. Throws SecurityException
// if the record is locked with a cookie other than lockCookie.
public void update(int recNo, String[] data, long lockCookie)
throws RecordNotFoundException, SecurityException;
// Deletes a record, making the record number and associated disk
// storage available for reuse.
// Throws SecurityException if the record is locked with a cookie
// other than lockCookie.
public void delete(int recNo, long lockCookie)
throws RecordNotFoundException, SecurityException;
// 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);
// 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.
// Returned value is a cookie that must be used when the record is unlocked,
// updated, or deleted. If the specified record is already locked by a different
// client, the current thread gives up the CPU and consumes no CPU cycles until
// the record is unlocked.
public long lock(int recNo) throws RecordNotFoundException;
// Releases the lock on a record. Cookie must be the cookie
// returned when the record was locked; otherwise throws SecurityException.
public void unlock(int recNo, long cookie)
throws RecordNotFoundException, SecurityException;
}

Thanks again

Stephen
Hi there

I have just being looking over my code and just wondering how all you java guru's out there handled IOExceptions in your find method of your Data class. The find method I must implement has the following signature
public int[] find(String[] criteria); as you can see it does not throw any Exceptions . Due to this fact if an IOException occurs for instance in my find method I simply ignore it and return a 0 length array to the caller. It's not a real big problem as it is unlikely to happen but could. I think it would be better to return an Exception that alerted the client to the fact an IOException occurs rather than a empty array.

Cheers

Stephen
Hi Tim

Personally I wouldn't make RecordNotFoundException & DuplicateKeyException subclasses of IOException IMO I feel that this is a bad design choice, is a RecordNotFoundException & DuplicateKeyException really an IOException. In my implementation I sub classed Exception directly.

My idea was that I could simply use DatabaseInterface and if in local mode throw an IOException in local mode, and RemoteException in RMI mode. I belive this is possible as I can also throw the same or a narrower exception. For exampe with the read Interface method which throws RecordNotFoundException.



For this to work I think you will need to have RecordNotFoundException extend RemoteException.

In my design I use a Connection Factory on the client which returns a Connection object. I give this object to my GUI Controller which then uses it to make data related calls for the GUI. I have two classes that implement the Connection interface, LocalConnection and RemoteConnection. My Connection interface contains all the methods the controller will need to serve the GUI's needs and each method signature throws a ConnectionException that way the client does not need to worry what type of exception was thrown whether it be a RemoteException or RecordNotFoundExcption.
Hi Ranchers

I have the URLyBird assignment. This assignment has the business rule
that a hotel room can only be booked within 48 hours of the start of room occupancy. I understand this to mean 48 hours before the date when the room becomes available or could this be 48 hours after the date when the room becomes available? In my implementation I opted for a thin client and I have the
following search requirements :



Due to the above search requirement I allow rooms to be returned and displayed on the client even if the date a room available is not within 48 hours of the current time. Then when a booking is made I check the date and if the current date is within 48 hours I allow the booking otherwise I return an error message. It would seem to make more sense to only return bookings where the date is within 48 hours therefore the user can only see rooms that can be booked.

Anybody have any suggestions.


Thanks
Stephen

[ June 29, 2004: Message edited by: Stephen Patrick ]
[ June 29, 2004: Message edited by: Stephen Patrick ]
Thanks Anthony

I changed it to lock on a synchronized hashmap rather than an individual record as I need to get this finished at least this way is safer. I lock on this object in lock and unlock, don't have a need to lock on the hasmap in update,create, delete etc as it is already locked and these methods won't be called if the record is locked.

Stephen
Thanks guys

here's the updated lock method I tested it today with 10 client threads and it seemed to work fine. However the only place that I might see a problem is the second last line where a new RecordLock oject is created is it possible that a thread could prempt after its creation and another thread could take over create a new RecordLockObject place it in the hashmap then the previous thread could come back to life and overwrite the RecordLock object just inserted with the one it created before it prempted.



Thanks again
Hi All

I am not an expert in threading but maybe one of you experts can help. My assignment involves using cookies to unlock and lock a record I have being looking through the various threads and this is what i am intending to do.

I create a synchronized hashmap which uses the record number for a key and object that contains the cookie used to lock a record and the record number.


Within my lock method I check the hashmap to see if it contains an object for a particular record number. IF it does I retrieve this object and then lock on this object using a synchronized block.

For example within the method:


In my unlock method I would then remove the object from the
hasmap and call notify all

From my understanding using a synchronized hashmap means that only one thread can carry out an atomic operation at a time on the map.

Can anyone see any problems with this approach would I need to perform some kind of synchronization when I get the object from the hashmap

Thanks

Stephen

[Andrew: put the source code between [code] and [/code] UBB tags]
[ June 15, 2004: Message edited by: Andrew Monkhouse ]