File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Defence using current thread as client's ID Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Defence using current thread as client Watch "Defence using current thread as client New topic
Author

Defence using current thread as client's ID

Yuqing Zhu
Greenhorn

Joined: Jan 17, 2002
Posts: 8
Here is my design:
Define an interface DataAccess that contains all public method in supplied Data class, including lock and unlock.
Modify supplied Data class to implements DataAccess, implement lock and unlock method. The implementation uses a Hashtable, key is Integer object of record number, value is the current thread reference (more on this later).
Define a server side facade call ClientService, which provide functions that are called by client through RMI to get, search and book seat. ClientService implementation calls methods in DataAccess to do its jobs. ClientService is a remote object registries on the server and it has only one instance per server. This facade is the most important point in my design.
Now, let me defence my choice of using current thread reference as client identity. As mentioned in RMI specification, there is no guarantee on how RMI runtime will handle the incoming client request,it may one, create a new thread for each client request, or second, run all client requests to a remote object instance in one single thread, i.e. no concurrency.
In the second case, I don't even need to lock the record before booking a seat, but it does no harm if I do. Lock method will alway succeed without waiting other client as no other client is running. So does unlock, it wouldn't be possible to unlock other client's lock as no that kind of lock exist.
In the first case, things are easy, RMI handles everything for me and each client can be sure identified by its new thread reference.
Do you think this reasoning is fine enough? Any incoming comment will be appreciated.
Lots thanks
[ April 11, 2002: Message edited by: Yuqing Zhu ]
[ April 11, 2002: Message edited by: Yuqing Zhu ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Yuqing Zhu:
Modify supplied Data class to implements DataAccess, implement lock and unlock method. The implementation uses a Hashtable, key is Integer object of record number, value is the current thread reference (more on this later).
I would argue that Data should not implement locking... in another thread I said:
For example, do not assume that lock() and unlock() need to be implemented on Data. They are fine as they are. Yes, that means empty methods. Really! If you want to, you can flesh them out a bit by adding validation code for the record number, but the lock() and unlock() methods in Data do not need to implement locking at all.
Why not? Well, think a bit about what Data represents. It represents a local database that can only be used from a single JVM. It is a single-user database object that consequently should not try to implement any of the multi-user features, such as locking. Locking is part of a network-enabled, multi-user layer that is built on top of Data.
With a layered architecture such as this, you achieve clear separation of responsibilities, maximum ease of use (a developer only needs to deal with the multi-user networked stuff when (s)he needs a multi-user networked database) and the highest level of reusability.
But, to be honest, no-one is going to be really worked up about this point, least of all the Sun assessors.
Now, let me defence my choice of using current thread reference as client identity. As mentioned in RMI specification, there is no guarantee on how RMI runtime will handle the incoming client request,it may one, create a new thread for each client request, or second, run all client requests to a remote object instance in one single thread, i.e. no concurrency.
In the second case, I don't even need to lock the record before booking a seat
Oh yes you do! In that hypothetical case, the client requests are serialized in that no more than one method call is handled any given time. But the calls can be interleaved and bookings can still clobber each other:
  • Client #1 locks the record (it thinks).
  • Client #2 locks the same record (it thinks).
  • Client #1 reads the record: 1 seat free.
  • Client #2 reads the record: 1 seat free.
  • Client #1 updates the record: 0 seats free.
  • Client #2 updates the record: 0 seats free.
  • Client #1 unlocks the record.
  • Client #2 unlocks the record.
  • You've just sold your seat twice. Oops.
    In the first case, things are easy, RMI handles everything for me and each client can be sure identified by its new thread reference.
    It certainly can not. RMI gives you no guarantees whatsoever that the same thread will be used for the same client every time! It may maintain a thread pool of 2, 3, maybe 10 threads and a client may get a different thread for every method call it makes.
    Do you think this reasoning is fine enough? Any incoming comment will be appreciated.
    Duck, quickly
    There is no way you can identify the clients by thread. RMI simply does not give you enough guarantees.
    - Peter
    [ April 11, 2002: Message edited by: Peter den Haan ]
    Yuqing Zhu
    Greenhorn

    Joined: Jan 17, 2002
    Posts: 8
    Thanks Peter, quick response! Would like to defence my design further.

    I would argue that Data should not implement locking... in another thread I said:
    ......
    Why not? Well, think a bit about what Data represents. It represents a local database that can only be used from a single JVM. It is a single-user database object that consequently should not try to implement any of the multi-user features, such as locking. Locking is part of a network-enabled, multi-user layer that is built on top of Data.

    Quite agree on the ideas behind your desgin, highest level of reusability is always welcomed. But as my focus here is using thread as client's ID, so please allow me to implement lock/unlock in Data class for a while.

    Oh yes you do! In that hypothetical case, the client requests are serialized in that no more than one method call is handled any given time. But the calls can be interleaved and bookings can still clobber each other:

    Yes, that's the point why we can't use thread as client's id when we put the facade in the client side. If the facade is in client side, a bookSeat method actually is a serial of RMI requests which may be interleaved by RMI runtime. Butif we use a server side facade, bookSeat is a single request from the client to our remote object. It will run in a single thread without being interleaved as the other bookSeat(or other methods) requests from the others clients are serialized with this one. So if facade is on server side, which is in my design, we can have a threadsafe booking either with or without locking.

    It certainly can not. RMI gives you no guarantees whatsoever that the same thread will be used for the same client every time! It may maintain a thread pool of 2, 3, maybe 10 threads and a client may get a different thread for every method call it makes.

    Same as above, if we use server side facade, that's bookSeat as one RMI request, every bookSeat will run in one thread from the begining to the end, i.e., from lock to unlock, they all run in a single thread. Thread pool doesn't matter to this, as any thread in a thread pool can only server one request at a time. When the request finishs, lock has been unlocked.
    Two keys to decide whether we can use thread as client's id are one, if the lock and unlock will run in a same thread, if they do, we can tell who locked a record when we try to unlock it, so to prevent a lock from being unlocked by a non-lock-owner. two, if a thread will accommodate 2+ requests to lock 2+ different records at the same time, if it doesn't, we can be sure every records locked by a thread is locked by a same client.
    Thanks
    [ April 11, 2002: Message edited by: Yuqing Zhu ]
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Originally posted by Yuqing Zhu:
    Yes, that's the point why we can't use thread as client's id when we put the facade in the client side.
    Ah, that wasn't clear to me. If you put a session facade on the server, your scheme makes sense.
    There are two problems with this approach though.
  • It makes nonsense of the requirement (assuming it is still there) to have a client-side object that implements all the Data methods. In your approach, you have no use for such an object, full stop. Or, put differently, this is in fact an implicit requirement that the business logic reside on the client, and not on the server.
  • The database server code that you write is no longer reusable as-is. At best, you have a reusable "server kit" which forces you to put the business logic at the server side. This does not sit entirely comfortably with the reusability aims of the project.
  • Having said that, if you argue for your approach as strongly in your design documentation as you do here, I have little doubt that it will be approved of.
    - Peter
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Defence using current thread as client's ID
     
    Similar Threads
    Locking Issues
    About server auto release
    Design Question ( Data Access )
    To M Spritzler - Client Thread ID change
    Passed 364/400