• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

NX: Assignment - some design questions

 
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,

OK, client crash can leave locked record...I'm agree.
How "WeekReference" can store references to clients?


This thread may help you.
Best,
Phil.
 
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Philippe, thanks a lot for your help!
I have got a couple of questions, if you was so kindness to answer all previous, may by you have a lot of time to answer else ...
1.)
I try to make my project as simple as allowed.
And reading Max's book I did not find any attempts to avoid
deadlock as result of clients crash.
Is it enough to make assumption ".. that clients will not attempt to release a DVD that they did not lock" ?
Is it so important for the ptoject to track all client's life?
What you think?
2.)
page 129 of Max's book, at the bottom:
"...Suppouse that there are two DVDDatabase objects db1, db2......"
How we can "suppouse that there are two DVDDatabase objects " when
RMI in Max's realization provide only one db object shared by all clients?
I did exact copy of this project and see that only 1 time new DBobject created when RMI registers this object on remote computer.
All clients use the same object.
I try to keep things simple and don't create connection factories, additional objects and so on, and ask you : is it generally enough for the project if I'll build the model as Max showed ih his book?
Thank you for your helpful answers!
My best regards.
Peter.
 
Ranch Hand
Posts: 555
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,
1.
You DON'T HAVE to implement dead-lock handling. At least, I didn't... Mentioning the problem and possible solution in choices.txt is Ok.
2. Max describied ConnectionFactory, which creates remote object per client, but didn't implement it in the sample projects. So, he comments his ideas in the book and then the sample project. So, be carefull and read first his book and then the sample.
I think you can skip connection factory. I personally beleive it is easy and usefull pattern, but it is no way any requirement or so.

Best,
Vlad
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,

Originally posted by Philippe Maquet:
When you think "db", just think "db" : the interface you were provided and its comments. Don't think how you will use that interface, but how anyone reading it could use it.
You need [to track owners] IMO. While you have no specific comments for update() and delete() as I have, your provided lock() method comment is clear enough :
"Locks a record so that it can only be updated or deleted by this client.
How could you ensure this if you don't track lock owners ?

Originally posted by Peter Kovgan:
Cause while client "B" has the lock, client "A" inside the while loop,
periodically call vector.wait and do nothing.
Only client, which has the lock can do unlock, cause
lock() and unlock() called from the same method book().
Client "A" can't exit from while loop, while client "B" has the lock.


You are half right - in your usage of Data class in your server you are safe.
However any other programmer who comes along and decides to use your data class directly will be in trouble - they expect that the contract of the interface has been fulfilled, when it hasn't. Sun didn't just give you a data file and tell you to work with it, they gave you an explicit contract to fulfill in the form of the interface. This to me implies that they intend to have other applications written to use that interface.

And reading Max's book I did not find any attempts to avoid deadlock as result of clients crash.


Max believes that we only have to deal with problems that can occur in normal operations - so ensuring your code does not cause deadlock, that sort of thing. He believes we do not have to worry about intangible problems - network crash, computer crash etc. I can understand this perspective, and certainly people have passed with very good scores without worrying about handling crashed clients. However I think handling client crashes can be done easily (if required by the server you are writing), and doing so makes the code more robust.
If you have your book() method on the server side (which you must since you are not tracking owners of locks) then you should be safe: if you are writing a Sockets solution, your code can unlock records if the client crashes; if you are writing an RMI solution, then the book() method should run to completion, which will result in the record being unlocked anyway.

I try to keep things simple and don't create connection factories, additional objects and so on, and ask you : is it generally enough for the project if I'll build the model as Max showed ih his book?


What you should be concerned about is whether you meet the criteria of your assignment. I know of three major assignment types, each of which has multiple versions, with each version having minor differences. There is no way Max could write his DVD application in such a way that it exactly matches the requirements of any assignment, let alone all of them.
Which is a round about way of saying that I think you can follow the general concepts Max used, but you will have to verify for yourself that your solution will be acceptable, and you will have to adapt Max's sample code to meet your requirements (or throw out Max's code where it just doesn't fit your requirements).
Regards, Andrew

 
Peter Kovgan
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Vlad.
Good answers, thank you.
I suppoused I'll hear somthing like this.
Thank you VERY MUCH!
Can you send me private message to clear my doubt from where you are?

Andrew!
My "Contractors" has very idiotic interface and I started to
think about clien't side locking to make things simple.
I started to think this interface are more preferable to use on client side too.
Have you some thread or link which can help me to make fat client?
If you have, send me please, if not - any problem.
Thank you for help.
Peter.
 
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Phillipe, Andrew et al,
Thanks for opinions so far. I feel like I'm slowly getting to understand the issues. For that thanks a lot!
Whilst I like Andrews Server side Buisness tier logic ensuring that any Client side crashes will not cause record lock, I still have a nagging feeling when reading the instructions.
It does explicity say in the db interface that the interface needs to be

// Locks a record so that it can only be updated or deleted by this client.


which to me means that my Data classs must ensure this. Else any programmer that in the future comes along and just reads the interface and notices that the data class implements this will assume that contract is met by the data class. Hence Phillipe comments look very important, and we can't leave it up to the BuisnessTier (which I like!)
Therefore I guess that the Data Class would need a LockManager (or something), which would ensure this. Now if each Client instantiated a new Data class on connection then I guess we could use the Data instance as the value in a WeakHashMap with the recNo as the key to ensure this.
I am (slowly getting there??)
My head hurts!
Thanks you guys, I'd be more lost without this forum!
Steve.
 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
oops Sorry! Philippe
 
Vlad Rabkin
Ranch Hand
Posts: 555
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Stephen,
You are on the right track.
There were many topics discussing possible deadlock handling. Your idea is correct.
Don't forget: if a WeakHashMap releases an object, none of the waiting thread will be notified. If you decide for WeakHashMap , think how you handle this.
Best,
Vlad
 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Vlad,
thanks for the confirmation that I'm on the correct track.
I've seen a few examples of how the release of the lock may be resolved on Client crash. I think I follow having 2 collections in the DataClass, one static for Locks and one to keep track of which ones the current instance is using. Hence if the Object stored in the local one is garbage collected then the ref in the WeakHashMap will also go.
But that's where my understanding stops. I am thinking that the situation you are alluding to is where Client A has the lock, Client B waits, Client A crashes (and hence the lock is released). Now how does the Client B get the notify? I guess it's not sufficient to just let Client B wait around until Client C comes in and calls notifyAll!
I'm also a bit confused about this mutex stuff (the confused status will come as no surprise to thise that have read my other posts!), making calls to notify unnecessary. Does this help in this situation or not?
Sorry for my ignorance, but I guess that's part of the reason to do this exam - to improve my knowledge and in that respect thanks to you all so far!
Steve.
 
Vlad Rabkin
Ranch Hand
Posts: 555
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Stephen,

Client A has the lock, Client B waits, Client A crashes (and hence the lock is released). Now how does the Client B get the notify? I guess it's not sufficient to just let Client B wait around until Client C comes in and calls notifyAll!


Correct. That is what I don't like in WeakHashMap solution. I personally, implemented client-crash handling with Unreferenced interface. The advantage there is that you explicitely unlock the record. It is probably less elegant than WeakHashMap, but much more understandable to a developer.
However, at latter time, I through it away, since the problem of Unreferenced interface is that my Connection object (remote object) must have a state (contain a collection, holding all locks of the client, referencing the remote object). My strategy is always to avoid statefull remote objects, because they are not flexible and require MUCH more care.
In the real project, if I had to have lock/unlock on the client, I would solve the problem with the locking time-out (like DB2 does). Unfortunatelly, this solution violates the assignment requirement and will lead you to fail. Thus, if I would want to implement client-crash handling in this assignment at any price, I would do it with Unreferenced interface.
I must admit I didn't think how to notify waiting threads in case of WeakHashMap (since I never considered this solution). Phil, Andrew could you please help Stephen?


I'm also a bit confused about this mutex stuff


I don't understand what makes you confused? Could you specify what is not clear to you?
Best,
Vlad
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Peter,

Originally posted by Peter Kovgan:
My "Contractors" has very idiotic interface



In an ideal world we would probably change a lot of things in this assignment - not just with the interface that Sun provided.
But one of the things that Sun (and employers in general) like is that an employee can follow directions. Where possible, as professionals we should be able to discuss other options with our superiors, however there may be other factors that we are unaware of that are guiding the specifications, so we cannot just ignore some of the specifications because we don't like them. (And unfortunately we cannot talk to our supervisors in this case - they are not available).

Originally posted by Peter Kovgan:
Have you some thread or link which can help me to make fat client?


I am not sure what you are after here. The main difference between the thin client and the fat client is where the logic of calling the lock(), update() and other methods go. There is nothing special about that per se.
I suspect you are asking what unique object can you use to identify the client with. In which case the answer depends on whether you are writing a Sockets or an RMI solution. If Sockets, then you can probably use the thread that you create for each connection. If RMI you might want to have a ConnectionFactory that creates a new remote object for each connected client - in which case the instance of the class becomes your unique identifier (if you search for "ConnectionFactory" in this forum you will find out more about it).
Regards, Andrew
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Phil,
Did you see this:

Originally posted by Stephen Galbraith:
Whilst I like Andrews Server side Buisness tier logic ensuring that any Client side crashes will not cause record lock, I still have a nagging feeling when reading the instructions.
...
Hence Phillipe comments look very important, and we can't leave it up to the BuisnessTier (which I like!)


Did we start arguing for each others position accidentally?

Regards, Andrew
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Stephen,

Originally posted by Stephen Galbraith:
[The instructions] explicity say in the db interface that the interface needs to be

which to me means that my Data classs must ensure this. Else any programmer that in the future comes along and just reads the interface and notices that the data class implements this will assume that contract is met by the data class.


I agree. I also believe that we should enable the client GUI to call the lock() method itself (this is my interpretation of the instructions - not necessarily my idea of what is a good idea in real life). You can read more about why I interpret the instructions that way in the long topic "Should lock methods be callable by the client".

Originally posted by Stephen Galbraith:
if each Client instantiated a new Data class on connection then I guess we could use the Data instance as the value in a WeakHashMap with the recNo as the key to ensure this.


Sounds good to me.

Originally posted by Stephen Galbraith:
I am thinking that the situation [Vlad is] alluding to is where Client A has the lock, Client B waits, Client A crashes (and hence the lock is released). Now how does the Client B get the notify? I guess it's not sufficient to just let Client B wait around until Client C comes in and calls notifyAll!
Originally posted by Vlad Rabkin:
I must admit I didn't think how to notify waiting threads in case of WeakHashMap (since I never considered this solution).


One way to do it is to keep a track of how many items you believe should be in the WeakHashMap. Then in a separate (daemon) thread, do a regular check to see if the number of objects you believe should be in the collection does match the number of objects really in there. If they do not match, you update your count and call notifyAll(). You might be interested in reading the topic "Single table / Simple Locking - WeakHashMap vs WeakReferences".
As Vlad suggested, an alternative to using a WeakHashMap or WeakReferences is (if you are using RMI) to use the Unreferenced interface so that your program gets notified when a client has become disconnected - you can then do any clean up you need to do.
Regards, Andrew
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew,


[Stephen:]
Whilst I like Andrews Server side Buisness tier logic ensuring that any Client side crashes will not cause record lock, I still have a nagging feeling when reading the instructions.
[Andrew:]
Did we start arguing for each others position accidentally?


It looks like, but I didn't notice where we did !

If they do not match, you update your count and call notifyAll(). You might be interested in reading the topic "Single table / Simple Locking - WeakHashMap vs WeakReferences".


That's the same link I posted at the top of this page. Andrew, I noticed that in my code example I had forgotten to update the count. It's now corrected.
Best,
Phil.
 
Peter Kovgan
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


....I suspect you are asking what unique object can you use to identify the client with. In which case the answer depends on whether you are writing a Sockets or an RMI solution. If Sockets, then you can probably use the thread that you create for each connection. If RMI you might want to have a ConnectionFactory that creates a new remote object for each connected client - in which case the instance of the class becomes your unique identifier (if you search for "ConnectionFactory" in this forum you will find out more about it).


Andrew ,you are right !!!
Exactly this question I have to ask.
Thank you.
 
Stephen Galbraith
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot everyone.
The daemon thread thing looks like a pain! I'm thinking about just taking the risk of documenting the potential for problems and then say something along the lines of "I can't be bothered to make this robust - especially if your instructions are pants!" (not really!)
Again, I'm getting more and more knowledge on this and for that I thank you all!
PS
Andrew and Phil - oopps! It would appear it's easier to get names wrong than I thought! (or did I just try to get the discussion going again )
 
I have a knack for fixing things like this ... um ... sorry ... here is a consilitory tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic