• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Connection Factory pls explain

 
Ranch Hand
Posts: 704
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am tring to understand the point of the connection factory. The way I have solved things is like this:
I have a server which creates one instance of the Data class in its constructor but wraps everything into a data interface object using the following:
DataInterface db = new RemoteServerDataImpl(args[0]);
This means that only one instance of the database is registered and that all clients will communicate with the same database object.

Please explain what I am missing here because I just don't get the reasoning for designing the connection fatory class/es.
 
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the requirements that you have been given is that a client should be able to call lock() on the same record more than once; if it already owns the lock, a duplicate lock() call will simply return straightaway. To implement that, you need some way of associating a lock with the client that owns the lock. There are a number of ways to do that, and the Connection object is one of them.
A Connection is a server-side object, implementing the Data interface, which is associated with exactly one client. Because of this 1:1 association, the Connection object represents the client identity that you need as outlined above.
So how does the client get its Connection? You cannot bind it in the RMI registry -- after all, every client would get the same Connection object and that's exactly what you don't want. Factory pattern to the rescue! Instead of a Connection, you bind a ConnectionFactory in the RMI registry. The client retrieves this factory, then calls createConnection() to obtain its very own database connection. The server creates the Connection object for that client and returns it. Then the client starts talking to the Connection object to access the actual database.
Note that the Connection itself is never registered in the RMI registry.
Does that help?
- Peter
 
Nigel Browne
Ranch Hand
Posts: 704
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your reply however I am still confused you wrote

Originally posted by Peter den Haan:
One of the requirements that you have been given is that a client should be able to call lock() on the same record more than once; if it already owns the lock, a duplicate lock() call will simply return straightaway. To implement that, you need some way of associating a lock with the client that owns the lock. There are a number of ways to do that, and the Connection object is one of them.


I just don't read this as a requirement.
I have the version of FBN that requires a Conversion Tool. What it says about locking is this:

The lock method should block until the requested lock can be applied. The integer argument indicates the record to be locked.


So I have solved the locking by changing the signature of the lock/unlock methods so that they are synchronized. The lock calls are placed in a HashMap which has the record number as key and a null Object as value. I see this as a revelately simple way of modifing the Data class. Ok so locking happens in local mode but where is the harm in this?
[ April 15, 2002: Message edited by: Nigel Browne ]
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Nigel Browne:
[...] I just don't read this as a requirement.

I just checked and I'm only slightly off; it's the unlock method where this requirement comes up, in the javadoc:You cannot implement this functionality without tracking client identity.

So I have solved the locking by changing the signature of the lock/unlock methods so that they are synchronized.

<pedantic>Terminology alert: synchronization is not part of the method signature, i.e. adding the "synchronized" keyword does not change the signature.</pedantic>

The lock calls are placed in a HashMap which has the record number as key and a null Object as value.

If you're not mapping to anything anyway, wouldn't a HashSet make much more sense?
- Peter
 
Nigel Browne
Ranch Hand
Posts: 704
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Peter,
Thankyou for your comments. My requirements state

If an attempt is made to unlock a record that has been locked by this connection , then no action is to be taken


So I do need to monitor which connection has locked which record. Now I am completely lost, because I do not understand how to record the record number and the connection in a HashMap without rewritting my whole locking mechanism.
 
Peter den Haan
author
Posts: 3252
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can use the HashMap to map the record number to an object identifying the client that holds the record lock.
As to that identifier, there are a number of different approaches:
  • Modify the lock() and unlock() signature to include an identifier. If you're not comfortable changing the signature, use a client-side adapter that adds the identifier in its call to the server.
  • Give each client its own server-side Connection object to talk to (see the many other discussions about this).
  • Forget about tracking client identity in the lock manager -- instead of that, use a client-side adapter that keeps track of the locks held by that client and prevents duplicate calls from reaching the server.
  • Decide that this feature isn't worth the hassle of implementing it, document this decision as such, and simply ignore the requirement.
  • I have seen people pass this exam, with reasonable scores, with all of these approaches (yes, even the last one).
    - Peter
     
    Nigel Browne
    Ranch Hand
    Posts: 704
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Peter,
    Bare with me. You explainations so far have cleared things up alot, however I can only see a use for lock/unlock in the bookFlights method. The requirements state that the lock should be a write only lock. The application in the future may implement add, modify, delete in the future but doesn't require that for this stage of development.
    So having argued that point, the bookFlights method is required to lock, read, modify, write and then unlock before it is finished. When is a client asking another client to yield? I don't see it. If I synchronize my bookFlights method it has to complete its full cycle before the next method can perform the bookFlights method.
    I may of course want to unlock rows, locked by clients that have lost connection, but that is not stated as a requirement either.
    I am leaning towards arguing this point and not implementing the connection tracking within lock/unlock.
     
    Peter den Haan
    author
    Posts: 3252
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Nigel Browne:
    [...] however I can only see a use for lock/unlock in the bookFlights method.

    Whoa, halt right there. You are being asked to develop for reuse. Reading the requirements, the (IMHO) inescapable conclusion is that you're going to write a simple, generic client/server database. You have already been given the core of this database.
    The use of lock/unlock is thereby completely unspecified. It's a generic database engine and lock/unlock is simply part of the infrastructure.

    The requirements state that the lock should be a write only lock. The application in the future may implement add, modify, delete in the future but doesn't require that for this stage of development.

    I think the requirements mean "write only lock" as opposed to "read/write lock". A read lock would be a lock that could be shared by many readers simultaneously, but which would block any client from acquiring a write lock.

    So having argued that point, the bookFlights method is required to lock, read, modify, write and then unlock before it is finished. When is a client asking another client to yield? I don't see it. If I synchronize my bookFlights method it has to complete its full cycle before the next method can perform the bookFlights method.

    Acquiring the locks mean you don't have to synchronize bookFlights. Also I think, for a number of different reasons, that the requirements mean that bookFlights must reside on the client.
    The most important reasons are (a) a bookFlight on the server makes nonsense of the requirement to have a client-side object implementing all the Data methods and (b) application-specific functionality on the server inhibits reuse of the server code you develop -- you are being asked to code for reuse.
    - Peter
     
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    hi, just read your interesting discussion and have a question. Say if I implement a Connection and the client need to get the Connection before make any other request, well the server can identify the client. But the lock and unlock methods only take in record number, so how does the LockManager knows that which client or Connection calls the lock or unlock?
     
    Nigel Browne
    Ranch Hand
    Posts: 704
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I think I get it now. I have been reading through old threads and the light has finally gone on. Can you please comment on the following design.
    I have a ConnectionFactory class that extends UnicastRemoteObject. This class has a constructor that calls super() and then creates an instance of the Data class. In the main method of this class I bind the class to the registry. The class also has a method getConnection which returns a RemoteDataImpl object.
    My RemoteDataImpl has my wrapping of DataInterface and forwards remote calls to the server.
    On the client side I have a RemoteDataClient which creates a ConnectionFactory instance and then calls the getConnection method to recieve a DataInterface object.
    Is this correct logic?
    How does the getConnection metohd know about the Data instance on the server or should there be a constructor in RemoteDataImpl which takes the position of the db.db file as an argument.
     
    Nigel Browne
    Ranch Hand
    Posts: 704
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by kaedy_muro:
    But the lock and unlock methods only take in record number, so how does the LockManager knows that which client or Connection calls the lock or unlock?


    I will try to explain, and I hope that Peter will correct me if I am wrong. By creating a factory object that is bound to the registry and then creating via that factory connection objects, we ensure that all call to the database are held within the seperate connection objects.
    This means that each connection object will hold its own version of a HashSet. If the connection tries to unlock a row which isn't in its HashSet then that attempt is simply ignored.
     
    Nigel Browne
    Ranch Hand
    Posts: 704
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thankyou Peter for spending the time to drum this into my head. I have managed to get my connection factory and locking mechanism to work now.
    What is even more amazing is I finally understand why my original design didn't fulfill the requirement. I was trusting clients to behave themselves i.e lock, read, modify, write, unlock. Even though this may not be the case when future enhancements are added.
     
    The only thing that kept the leeches off of me was this tiny ad:
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic