• 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
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

Locking timeout

 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

Thank you guys for helpening me out in other threads.

I have a doubt about one method from the DB interface:

// 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;


The question is: Is it a design issue whether to time out OR should I block the client until he can access the record?

Sun says I must implement the DB as described. That means I cannot just time out, does it?

Regards,

Eva
 
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The DB interface doesn't handle timeouts but that doesn't mean you can't have them.

I chose to implement a Timer based timeout mechanism. Mainly I did this to prevent locks being retained in case of clients that disconnect and terminate in the middle of a transaction leaving stale locks in place (and potential programming errors by 3rd party clients that fail to properly unlock records).
As a nice bonus, it also prevents deadlocks (which shouldn't happen even without timeouts, but a client waiting forever because a resource is locked by a client that's no longer capable of releasing it is effectively if maybe not technically a deadlock situation as well) as any lock can never be held forever.

It says nowhere you must do so, but it's also written nowhere that you can't.
 
Ranch Hand
Posts: 284
Netbeans IDE Firefox Browser Debian
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Eva,
you can think in two kind of timeouts:
a) Waiting timeout: A client waiting more than a specified interval is compel to give up the competition for the lock
b) Owning timeout: A client lock is released automatically after a specified interval
IMO option b is compatible with the supplied interface.

Regards
 
Eva Van Shtock
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the discussion everybody!
I was wondering, what is a good period to wait for a lock?
I was thinking 48 hours, but I think that is too long. Is it again a design issue?

By the way, for those of you who are doing URLyBird: when a client asks for a set of records (using search), do you send only the rooms that can be rented or you send every room maching the criteria? Do we need to worry about this?

Regards,
Eva
 
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

Originally posted by Jeroen T Wenting:
I chose to implement a Timer based timeout mechanism. Mainly I did this to prevent locks being retained in case of clients that disconnect and terminate in the middle of a transaction leaving stale locks in place (and potential programming errors by 3rd party clients that fail to properly unlock records).

I believe it would be a mistake to do this if that was your only reason for having timeouts. There are plenty of other ways to handle clients disconnecting while owning a lock. While there is nothing explicitly forbidding a timeout on owning a lock, there is nothing (in my opinion) that indicates that this would be desirable either.

Notice that I had 1 "I believe" and 1 "my opinion" in there? That's because these are my opinions - not statements of fact. It is my understanding that several people have passed while using timeouts, so it does appear to be a valid choice, no matter my beliefs.

It would also be possible to implement timeouts at a server level (not at the Data class level) and meet my self-imposed restrictions on not using a timeout in the Data class. However if you did that, then I would be interested to know why you chose that instead of one of the more standard ways of handling a client disconnection.

For what it's worth, my two biggest arguments against timeouts are:
  • My reading of the interface provided is that once I own a lock, it is mine as long as I am connected. It does not say anywhere in the interface (or elsewhere in the document) that I can only own a lock for a certain amount of time. Since I can handle client disconnections without creating a restriction on how long a lock can be owned, I see no reason to add a restriction not originally in the document.
  • If I was to add a time limit, how would I pick a valid time?


  • If we were to assume that the sequence lock-verify-modify-unlock are all performed in a single method, then a valid timeout might be in milliseconds.

    Alternatively if we were to assume that a valid sequence might be to lock multiple records, verify that they are all available, modify them all, then unlock them all; then a valid timeout might have to be considered in hours.Personally I dont think the benefits outweigh the problems I could be causing myself.

    Regards, Andrew
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I pretty much took my inspiration from web application session handling.
    The server has no knowledge of connected clients at all, it just knows it gets a request to lock a record and hands back a cookie.
     
    Oricio Ocle
    Ranch Hand
    Posts: 284
    Netbeans IDE Firefox Browser Debian
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Regarding owning timeouts my design is:

    - Time limit can be specified at server start up. After a successfully start up, this value is persisted for future executions
    - A zero time limit means 'timeout disabled'
    - Default value is zero.

    I.e, defining timeout value is up to the server admin

    Suggestions?

    NOTE: Of course, my scenario is cookie-based
    [ June 06, 2006: Message edited by: Oricio Ocle ]
     
    Ranch Hand
    Posts: 531
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Eva Van Shtock:
    Hello,

    Thank you guys for helpening me out in other threads.

    I have a doubt about one method from the DB interface:

    // 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;


    The question is: Is it a design issue whether to time out OR should I block the client until he can access the record?

    Sun says I must implement the DB as described. That means I cannot just time out, does it?

    Regards,

    Eva



    My advice would be to not implement the lock timeout. If you do the locking right, you will never have to worry about locked records if your locking resides on the server. I do not advise you to put your locking code in a client - it will complicate things.

    You should block the client from accessing a record using a queue. If you just use wait/notifyAll you are not really complying with design specs (although you might pass.) Use a queue and call wait on objects in the queue.
     
    Eva Van Shtock
    Greenhorn
    Posts: 28
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    and how can you queue requests Anton?
    there is nothing in RMI which allows you to do so.
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    How would the server detect whether a client has disconnected?
    RMI doesn't AFAIK have a system to silently track existing connections, and I'm not to eager to build an elaborate session management system (though it is certainly possible).
    And even if you have a session handling system, you can still have stale sessions, so you're just moving the ball up a notch from timing out stale locks to timing out stale sessions (including any locks they hold).
     
    Oricio Ocle
    Ranch Hand
    Posts: 284
    Netbeans IDE Firefox Browser Debian
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    IMO the cookie imposition is an implicit way for telling that our server must not keep track of connected clients, since in other case cookies are unnecessary.
    In that case, timeouts are the only way for ensuring a stable locking environment.

    In other assignments, I agree with you Andrew and Anton, there are better and more elegant solutions: sockets-based, connection factories, weakHashMaps, Unreferenced interfaces ....

    well, have i reopened the Pandora's box?

    Regards
    [ June 07, 2006: Message edited by: Oricio Ocle ]
     
    Anton Golovin
    Ranch Hand
    Posts: 531
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Eva Van Shtock:
    and how can you queue requests Anton?
    there is nothing in RMI which allows you to do so.



    This would not be in the RMI but rather in the code you write. Every client request on the server has a cookie to uniquely identify it. This is necessary because RMI assigns random threads to handle requests after they are interrupted by locking, among other things. You cannot rely on the thread handling a client request to be the same thread before and after waiting. The cookie is the way, if I remember correctly, to identify a request.

    The reason the stuff above is important is because it allows you to see the method for correctly handling client requests, based on the method RMI handles them. (RMI has the option of using one thread per request all the way or using a pool of threads, actually, but the end result is that you cannot assume anything about which thread is handling which request.)

    My advice is that you associate an object (of type Object) with a request. Once you have done so, you can queue these Objects in a queue and call wait on them. Once a request is done with its task, another request (a waiting request) can resume its execution. How is it accomplished? You would pop an Object from the queue and call notify on it. The request which called wait on this object then resumes running. This way you are losing no cycles, and the requirement is met.

    It's a good method of handling concurrency to learn, so I would do it myself if I had to take the exam the second time. I passed with notifyAll() but notifyAll() is not really the way they want you to handle this.

    [ June 07, 2006: Message edited by: Anton Golovin ]
    [ June 07, 2006: Message edited by: Anton Golovin ]
     
    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

    Originally posted by Jeroen T Wenting:
    How would the server detect whether a client has disconnected?
    RMI doesn't AFAIK have a system to silently track existing connections...

    Oricio mentioned the two common ways: Unreferenced (the easier way) and WeakHashMaps.

    Here's an example of using Unreferenced.

    Regards, Andrew
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    As I understand it Unreferenced won't tell you WHICH client has disconnected though, in fact it will only fire when there are no more clients connected at all.
    To be helpful to detect specific clients disconnecting (and take action accordingly) it would need to fire whenever a client disconnects and have knowledge of which client it was.

    My locking system anyway doesn't know which client holds which lock(s), just that they're being held (though if on an RMI call that information could be retrieved the locking system could be changed to take that into account in some way).

    In other words my architecture doesn't lend itself to that approach as there's not a single Remote per client but rather a single Remote for the entire server (which essentially IS the server).
    [ June 10, 2006: Message edited by: Jeroen T Wenting ]
     
    Greenhorn
    Posts: 14
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Jeroen, Unreferenced should do the trick for bad locking. Just think about it!
    However, what can one do when a client wants to lock a record and many clients accessing the database and/or map. This may be long time.
    Should I be worried about this? Meaning, should I be worried about the time it takes the server to respond (negatively or positively) to client request.
    I haven't started gui yet, but I imaging the user selects a record and hits "rent room". The client tries to lock the record by contacting the server for a cookie. Now if it takes long time to have exclusive access to the synchronised elements (file, map, etc.)
    should the user just wait and the system freezes???

    What can I do to fix this? From the discussions, I don't implement biz logic on server, but rather use lock-modify-unlock requests from client to server.

    Any thoughts from the gurus are welcome!
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I don't actually lock the record until the client chooses to confirm his booking (in the actionPerformed for the OK button).
    That method is synchronised on the connection (just for safety) and calls lock, read, update, unlock.
    If the read data differs from the original (before modification), another popup is shown asking to confirm the changes first.
     
    Poop goes in a willow feeder. Wipe with this tiny ad:
    We need your help - Coderanch server fundraiser
    https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
    reply
      Bookmark Topic Watch Topic
    • New Topic