com.ibm.tspaces
Class TSCmdSocketImpl

java.lang.Object
  |
  +--com.ibm.tspaces.TSCmdSocketImpl

public class TSCmdSocketImpl
extends java.lang.Object
implements TSCmd

This is the socket implementation of the TSCmd interface. When the client calls the TupleSpace constructor, it will obtain an instance of TSCmd which will be used to send commands to the Server and receive the Tuple responses. The TupleSpace instance will communicate with the server by calling TSCmd.command() (*) The communication protocol: The current communication strategy is to have one connection between each client virt mach to each unique server. A server is identified by its hostname and port (This leads to more than one name per server since a hostname can take on many forms, but the communication protocol can actually handle more than one connection between client and server so we ignore this issue). The TupleSpace class contains static methods for managing the communication between the client machine and the different servers. For every connection there is a "CallbackThread" running that manages the responses that come from the server. Here is the algorithm for sending a request and getting a response: 1. The basic command like read or write calls the command method 2. command calls the static method talkToAServer with the hostname and port # of the server that identifies this particular tuple space's server. 3. TalkToAServer checks whether there is already a connection open to this server. if not, it opens one creating the input and output streams from it. Then, it creates a CallbackThread, handing it the input stream and sets it running. 3a At this point the userid and password are sent to the server for authentication. if the client has not specified a userid then DEFAALT_USER (anonymous) is used as the userid. 4. TalkToAServer creates a unique integer identifier for this request. 5. TalkToAServer "registers" this request with the CallbackThread using the unique identifier and a "callback" method. The callback method is actually supplied by the command method and its code looks something like: call( SuperTuple retValue, String status, Integer seq#) { myTuple = retValue; myStatus = status; mySemaphore.incr(); } // end call The command method is blocking on "mySemaphore" and when it is incremented, will wake up, grab its tuple and return the tuple to the user. Of course if the tuple is actually an exception, that exception will get thrown at the user. Back to TalkToAServer 6. TalkToAServer creates the transportTuple which looks like: ( SequenceNumber, ( tsName, command, dataTuple)) 7. TalkToAServer sends this to the server. 8. TalkToAServer is done so it returns 9. command executes a mySemaphore.decr() and waits for the reply. (*) Let's look at CallbackThread. CallbackThread manages all responses from a particular server connection. Each request is queued up using a unique sequence number. A response is handled by calling a method that the requester provided to talkToAServer which gave the method to CallbackThread along with the sequence #. CallbackThread also takes the tuple space name, and command name of the request because when the response is to an Event that the client registered for rather than an individual command, it is nice for the user to be provided with the sequence #, tsName, command, and responseTuple. CallbackThread continually waits on its ObjectInputStream for a response from the server and then grabs the sequence # from the response. The sequence # is used to grab the method, tsName, and commandName from 3 hashtables and then the call method is invoked. If an IO error occurs either on the input (in CallbackThread) or output (in TupleSpace) end of a connection, TupleSpace.killConnection is called to clean up the mess. The mess involves throwing exceptions at all the client threads that were waiting for commands to the tuple space whose connection had a problem.

Author:
John Thomas
See Also:
CallbackThread, Waiter, Semaphore, TSIOHandler

Field Summary
protected  boolean _connectionOK
          A flag that indicates if the connection to server can be established.
static java.lang.String _DEFAULT_PASSWORD
           
static java.lang.String _DEFAULT_USER
          This is what is used if no user/password is specified
protected  java.lang.String _keyName
          The key used to access the ServerConnection object
protected  java.lang.String _password
          The password for this TSCmdImpl.
protected  int _tsPort
          The port for this space's server.
protected  java.lang.String _tsServer
          The name of the machine running the TupleSpace server
protected  java.lang.String _userName
          The username for this TSCmdImpl .
static int CLI_ID
           
static int CMD_FLAG
           
static int CMD_TUP
           
static int EVENT_ACTION_FLD
           
static int EVENT_COMMAND_FLD
          the fields of an event tuple, keep with the making of the event templates until things stabilize pw.
static int EVENT_EAT_FLD
           
static int EVENT_SEQ_FLD
           
static int EVENT_TUPLE_FLD
           
static int SEQ_NUM
          The top level tuple sent to the server has four fields ( Seq #, CmdTuple, clientID, Flag)
static int TS_ARG
           
static int TS_CMD
           
static int TS_NAME
           
static int TS_RETURN_VALUE
           
static int TS_STATUS_CODE
           
 
Constructor Summary
TSCmdSocketImpl(java.lang.String tsServer_, java.lang.Integer tsPort_, java.lang.String userName_, java.lang.String password_)
           
 
Method Summary
static void cleanup()
          this method is used to close the current connections to the server.
 void close()
          this method is used to close the current connection to the server.
 SuperTuple command(java.lang.String cmdString_, SuperTuple argTuple_, java.lang.String tsName_, Transaction enclosingTransaction_)
          Issue a command to the TupleSpace galaxy tuple space and pass along a Tuple as an argument.
 SuperTuple command(java.lang.String cmdString_, SuperTuple argTuple_, java.lang.String tsName_, Transaction enclosingTransaction_, long timeout_)
          Issue a command to the TupleSpace galaxy tuple space and pass along a Tuple as an argument.
 void eventDeRegister(int seqNum)
          DeRegister for an event on the server.
 void eventRegister(int seqNum, Callback callback_, java.lang.String commandName_, java.lang.String tsName_, boolean newThread_)
          Register for an event on the server.
 int getPort()
          Return the number of the port.
 java.lang.String getServer()
          Return the name of the server.
static void killConnection(java.lang.String key_, java.lang.Exception ioe_)
          this method is used to close the current connection to the server.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SEQ_NUM

public static final int SEQ_NUM
The top level tuple sent to the server has four fields ( Seq #, CmdTuple, clientID, Flag)

CMD_TUP

public static final int CMD_TUP

CLI_ID

public static final int CLI_ID

CMD_FLAG

public static final int CMD_FLAG

EVENT_COMMAND_FLD

public static final int EVENT_COMMAND_FLD
the fields of an event tuple, keep with the making of the event templates until things stabilize pw. The 0th field is TupleSpace.ANEVENT

EVENT_TUPLE_FLD

public static final int EVENT_TUPLE_FLD

EVENT_SEQ_FLD

public static final int EVENT_SEQ_FLD

EVENT_ACTION_FLD

public static final int EVENT_ACTION_FLD

EVENT_EAT_FLD

public static final int EVENT_EAT_FLD

_DEFAULT_USER

public static final java.lang.String _DEFAULT_USER
This is what is used if no user/password is specified

_DEFAULT_PASSWORD

public static final java.lang.String _DEFAULT_PASSWORD

TS_NAME

public static final int TS_NAME

TS_CMD

public static final int TS_CMD

TS_ARG

public static final int TS_ARG

TS_STATUS_CODE

public static final int TS_STATUS_CODE

TS_RETURN_VALUE

public static final int TS_RETURN_VALUE

_tsServer

protected java.lang.String _tsServer
The name of the machine running the TupleSpace server

_tsPort

protected int _tsPort
The port for this space's server.

_userName

protected java.lang.String _userName
The username for this TSCmdImpl .

_password

protected java.lang.String _password
The password for this TSCmdImpl.

_connectionOK

protected boolean _connectionOK
A flag that indicates if the connection to server can be established. It is set true when the TSCmdSocketImpl is setup and the username and password are passed. It is set false when a connection is broken for any reason.

_keyName

protected java.lang.String _keyName
The key used to access the ServerConnection object
Constructor Detail

TSCmdSocketImpl

public TSCmdSocketImpl(java.lang.String tsServer_,
                       java.lang.Integer tsPort_,
                       java.lang.String userName_,
                       java.lang.String password_)
                throws TupleSpaceException
Parameters:
tsServer_ - A string that identifies the TupleSpaceServer that manages the TupleSpace. May be of form host:port
tsPort_ - The specific port that the TupleSpaceServer uses to listen for connections from TupleSpace clients. This parameter will be ignored if the port is specified as part of the tsServer_ parameter.
userName_ - the user's tspaces name
password_ - the user's tspaces password
Throws:
TupleSpaceException - If there is a problem creating the space on the server or communicating with the server or there is a problem with the TupleSpaceName.
Method Detail

close

public void close()
this method is used to close the current connection to the server. The method closes down the streams connecting the client to the server. This way the server can tell that this is a normal termination.
Specified by:
close in interface TSCmd

command

public SuperTuple command(java.lang.String cmdString_,
                          SuperTuple argTuple_,
                          java.lang.String tsName_,
                          Transaction enclosingTransaction_)
                   throws TupleSpaceCommunicationException,
                          TupleSpaceClientException,
                          TupleSpaceServerException
Issue a command to the TupleSpace galaxy tuple space and pass along a Tuple as an argument. The command is a text string that is recongized by the TupleSpace. The results of the command, if any, are returned as a tuple. This just calls the following command() method with a 0 timeout value specified.
Specified by:
command in interface TSCmd
Parameters:
server_ - the server to send the command to
port_ - the port for that server
userName_ - the Username to associate with this connection.
password_ - the password for the above user.
cmdString_ - The String that names the command.
argTuple_ - The argument Tuple, can be null.
tsName_ - The tuple space the command is acting on
enclosingTransaction_ - Transaction object that issued this command enclosingTransaction_ == null ---> standAlone transaction '' <> null ---> part of enclosingTransaction_
Returns:
A result Tuple, the format of which depends upon the command.
Throws:
TupleSpaceCommunicationException - There are problems connecting to the TupleSpace Server
TupleSpaceServerException - There was a problem executing the command on the server.
TupleSpaceClientException - There were problems preparing the command to be sent to the server.
See Also:
Waiter, CallbackThread

command

public SuperTuple command(java.lang.String cmdString_,
                          SuperTuple argTuple_,
                          java.lang.String tsName_,
                          Transaction enclosingTransaction_,
                          long timeout_)
                   throws TupleSpaceCommunicationException,
                          TupleSpaceClientException,
                          TupleSpaceServerException
Issue a command to the TupleSpace galaxy tuple space and pass along a Tuple as an argument. The command is a text string that is recongized by the TupleSpace. The results of the command, if any, are returned as a tuple. A time value (in ms) can be specified if the command should be aborted after the specified time. This thread of control will handle sending this command request to the server, but another thread a CallbackThread will be getting the response from the server for this request. The Waiter class allows us and the Callback thread to in some sense synchronize. The Waiter has 2 key methods that look like this:
   waitFor(timeout) {  
     mySemaphore.decr(timeout);
   }
 
   call(SuperTuple retValue, some other irrelevent junk) {
   myTuple = retValue;  
   mySemaphore.incr();
   }
 

So the command method will send the command and then call "waitFor() which blocks. When the command is complete, the callbackThread will get the response and call waiter.call(retValue) which will unblock this code. This code will then get the returned Tuple from the Waiter instance and return it to the caller. in case it isn't obvious, the methods in Waiter had better *not* be synchronized since the waitFor would then block with the lock held and call would block waiting on the lock.

Specified by:
command in interface TSCmd
Parameters:
server_ - the server to send the command to
port_ - the port for that server
userName_ - the Username to associate with this connection.
password_ - the password for the above user.
cmdString_ - The String that names the command.
argTuple_ - The argument Tuple, can be null.
tsName_ - The tuple space the command is acting on
enclosingTransaction_ - Transaction object that issued this command enclosingTransaction_ == null ---> standAlone transaction '' <> null ---> part of enclosingTransaction_
timeout_ - Time (in ms) that command shuld wait for a response.
Returns:
A result SuperTuple, the format of which depends upon the command.
Throws:
TupleSpaceCommunicationException - There are problems connecting to the TupleSpace Server
TupleSpaceServerException - There was a problem executing the command on the server.
TupleSpaceClientException - There were problems preparing the command to be sent to the server.
See Also:
Waiter, CallbackThread

eventRegister

public void eventRegister(int seqNum,
                          Callback callback_,
                          java.lang.String commandName_,
                          java.lang.String tsName_,
                          boolean newThread_)
Register for an event on the server.

The eventRegister method for the TSCmd instance is called to warn it to expect an event to arrive. The client can then send the eventRegister command to the server

Specified by:
eventRegister in interface TSCmd
Parameters:
seqNum - The sequence number assigned to the event
callback_ - what class object contains the call() method that will be called when the event happens.
commandName_ - the operation "WRITE" or "DELETE" to be on the watch for!
tsName_ - the Tuple Space name
newThread_ - If true, a new thread will be started for the callback

eventDeRegister

public void eventDeRegister(int seqNum)
DeRegister for an event on the server.

The eventRegister command is then sent to the server. he TSCmd instance is called to tell it not to expect any more events to arrive.

Specified by:
eventDeRegister in interface TSCmd
Parameters:
seqNum - The sequence number assigned to the event

killConnection

public static void killConnection(java.lang.String key_,
                                  java.lang.Exception ioe_)
this method is used to close the current connection to the server. It is called by CallbackThread and talkToAServer if they get an io error on the input end of the socket connection to the server which indicates that this socket is probably bad so instead of fooling around with the socket let's just close the streams and reopen a new socket.
Parameters:
key_ - the hostname and port catted together
ioe_ - the ioexception that occured.
See Also:
run

cleanup

public static void cleanup()
this method is used to close the current connections to the server. By default, the TupleSpace sets it up so the VM runs finalizers on exit and thus, the CallbackThread and ServerConnection classes finalizers are called and cleanup is performed that way. But, if the user did not want this, they can set _closingDownByForcingFinalizers to false and then just call this method when they are done with TupleSpace. The method closes down the streams connecting the client to the server. This way the server can tell that this is a normal termination.

getServer

public java.lang.String getServer()
Return the name of the server. Cool for debugging.
Returns:
String - the name of the server

getPort

public int getPort()
Return the number of the port. Cool for debugging.
Returns:
int - the number of the port