Thomas Kijftenbelt

Ranch Hand
+ Follow
since Feb 13, 2002
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 Thomas Kijftenbelt

Hi guys,

I actually took the following approach:

- I use a static hashmap to implement the record locking

- I implemented my data class as singleton; in that way I avoid that multiple data instances are trying to manipulate the same file.

Although I am using NIO (FileChannel) I am still a bit worried about dirty reads; therefore I synchronize on the FileChannel when reading / writing, i.e.



and




Greetings,

TK
[ October 23, 2004: Message edited by: Thomas Kijftenbelt ]
Hi,
I have a question about exception handling at the network layer:
Should you always catch specific exceptions (instead of Exception)? At my network layer I catch Exception and wrap it in a subclass of runtime exception. If it is not OK to just catch Exception, I have to catch RemoteException, MalformedURLException, etc. separately - although I handle them in the same way.
At the client side I display messages based on the various causes...
Greetings,
TK
Hi,
I also use a plugin for resin that works very good!
greetings,
TK
Jim,
Correct: the recordnumber is the key, the cookie the value. In the update / delete, I get the cookie from the Map (using the recordNo key), and check if it equals the supplied cookie...
You're correct when you say that the chance is small that you'll get two the same random numbers, but checking was quite easy to implement... and better safe than sorry
Greetings,
TK
Check,
I have the DuplicateKeyException in the create() as well... and I don't see any use for it either.
TK
Hi Nitti,
You're welcome... one remark however: I checked my spec. (also home contractor), and the signature for the find is as follows:

That's why I decided to wrap all my IOExceptions in RuntimeExceptions, which I catch at the client side.
Maybe your assignment is different, so make sure to check if the signature in your assignment is the same.
Good luck,
TK
Although I am not Jim, I'll try to give you a hint: what I do is create a random long nr.; I maintain a Map with record numbers and the corresponding cookie numbers; before returning a cookie to the client, I check if it is present in my Map...
Hopefully this helps...
TK
Hi Jim,
Sounds good. The FileChannel is used as private member of the Data class, and active during the life of a Data class... That's the same approach I took -> the trick however seems to be to have the various remote clients point to the one data instance... In case of the local configuration this is not a problem as there is one client and one server.
I am not completely into RMI, but I'll have a look at it and do some tests... the approach however looks good.
Regarding your question:

Note - if my second paragraph above makes no sense, it may be that I'm misinterpreting the assignment, so let me run this part by you. I see in the spec, "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..." OK, the latter part is handled by command line arguments defined elsewhere. But does "location of the database" mean "where's the server?" Or does it mean "once we've found the server (or localhost, which ought to be pretty easy if that's what requested) - what's the path to the DB file?" I'm assuming it's the latter, and this this means different clients may connect to different DB files through the same server. But I may be way off here; please let me know.


In fact rhere are a number of options which must the user must be able to specify:
- standalone mode -> database name
- server mode -> database name / rmi server port
- client mode -> server host name / rmi client port
Based on the mode in which the app. is running, I present the user with a dialog box, where he / she can enter the appropriate options. these are then written into a properties file, and retrieved when needed.
e.g. when started in server mode, the user can enter database name / rmi server port -> this is written into the properties; then an instance of the data class is created and the database name property is retrieved.
In either case the remote client cannot be used to specify the db location (as this client has probably no knowledge of the server machine).
Does this answer the question.
TK
Jim,

I still prefer the single FileChannel


Do you mean a single FileChannel per Data() instance or a single FileChannel which is shared by all Data() instances.
TK
Hi,
A small addition:

As for the latter, the only thing you have to do is lock down the entire db when a create or delete is taking place, say by using a lock(-1). Otherwise, all's well.


I would say you only have to lock the entire database in case of a create; in case of a delete, the actual file size does not change (only a delete flag is modified) -> so locking that particular record should be enough.
TK
Hi Billy,
To be honest: I am not sure anymore whether it is OK to leave them blank...
Maybe Max has an answer to this question...
TK
Hi Billy,
Initially I also did not plan to implement create / delete (just throw operationnotsupported exception); however if you have your update method, the create and delete methods can be implemented within half an hour...
I implemented them now, and it is very helpful for testing purposes. I'll probably leave them in...
Greetings,
TK
Hi Jim,
Based on the above my solution is to synchronize on the FileChannel:

Greetings,
TK
PS Discussing these topics at this level is good fun; I'll now finish my JUnit tests and look how the whole thing performs...
[ June 01, 2003: Message edited by: Thomas Kijftenbelt ]
Hi Jim,

File channels are safe for use by multiple concurrent threads. The close method may be invoked at any time, as specified by the Channel interface. Only one operation that involves the channel's position or can change its file's size may be in progress at any given time; attempts to initiate a second such operation while the first is still in progress will block until the first operation completes. Other operations, in particular those that take an explicit position, may proceed concurrently; whether they in fact do so is dependent upon the underlying implementation and is therefore unspecified.


OK, I read this part of the specification as well, and based on the last sentence I thougth that it depends on the underlying implementation whether proceeds atomically?!

Note that read(ByteBuffer, long) really needs to be called in a loop to ensure that the desired number of bytes is filled - but this isn't a problem.


I use another aproach: I create a ByteBuffer with the size of a record, and read fill the ByteBuffer in one step:

Greetings,
TK
Nitti,
Look through the post Jim suggests... I initially also thought of wrapping everything into RecordNotFound Exceptions; however you run into problemes with for example the FindByCriteria (which does not throw any exception).
I changed it, and wrap my IOExceptions into RuntimeExceptions, which I catch at the client side.
Greetings,
TK