com.ibm.etill.framework.io
Class ReconnectableClientSocket

java.lang.Object
  |
  +--com.ibm.etill.framework.io.ReconnectableClientSocket
All Implemented Interfaces:
SocketDownInterface

public class ReconnectableClientSocket
extends Object
implements SocketDownInterface

A class that encapsulates a reconnectable TCP socket that diagnoses whether the socket is down or not when function are called to get/put data to the socket. A user of this class must verify on their own, that they are writing to the proper connection (virtual socket) and that it has not gone down and come up between writing to the socket. This check is made for reading from this socket by providing the expected virtual socket number on the read method. This socket is designed to be used by multiple threads, and as such, it is possible to have numerous threads all blocked on connecting to a host. N-1 of the threads are blocked because of locking on this socket (synchronized methods) while the other 1 thread is waiting for the connection to occur. If the host is down, 1 thread will block for about 30 seconds, while the others wait. The others threads, will successively incur a similar wait of 30 seconds since the host will likely still be down once they get their time to connect. This is not good because the delay to the thread doing the connection is not predictable as it is based on how many other threads are ahead of it trying to connect to the same host using this same socket. Because of this unpredictable delay, there exists the capability of "shortcutting connection failures" using a "last failed connection timestamp". That is, if the user is trying to make a connection, and the last connection attempt failed within some reasonable amount of time (say 1 second), one can ask the socket to not try the connection and rather report the last failing connection status since the failing connection occurred so shortly ago. The virtual socket number is used in a couple different ways. 1) When it is odd, the socket connection is down. When it is even the connection is up. Each time a socket connection is made (reconnected) it is changed to the next higher even number. Each time a socket connection is found to be down, it is changed to the next higher odd number. 2) A user of this object may get this "virtual socket number" and use it to tell whether the connection currently up (or down) is the same connection that data was sent on earlier. We use this method in our VisaNet retransmitter to know if a retransmital is necessary.


Field Summary
static int READBYTE_NO_DATA
          no data available to read on connection, but connection is still up
 
Constructor Summary
ReconnectableClientSocket(TcpipHost targetHost, int shortcutConnectionPeriodInMilliseconds)
           
ReconnectableClientSocket(TcpipHost targetHost, TcpipHost socksHost, int shortcutConnectionPeriodInMilliseconds)
           
 
Method Summary
 int available(int expectingToReadFromVirtualSocketNumber)
           
 void close()
          Closes the socket and amy also flush bufferd output data.
 void flush()
          Flushes buffered data for the socket's OutputStream to written to the destination.
 InetAddress getInetAddress()
          Gets the socket's internet address
 InetAddress getLocalAddress()
          Gets the socket's local internet address
 int getLocalPort()
          Gets the socket's local port number
 int getPort()
          Gets the socket's port number
 int getSoLinger()
          Returns setting for SO_LINGER.
 int getSoTimeout()
          Returns the socket timeout setting
 boolean getTcpNoDelay()
          Returns whether Nagle's Algorithm is disabled or not
 int getVirtualSocketNumber()
           
 boolean isUp()
          Determines if the socket is up
 int read(int expectingToReadFromVirtualSocketNumber, byte[] ba, int offset, int maxLengthToRead)
          Reads a set of bytes from the socket Same args (after the first one) and return values as InputStream.read(byte[], int, int)
 int readByte(int expectingToReadFromVirtualSocketNumber)
          Reads a byte from the socket
 boolean reconnectIfKnownDown()
          Reconnects the socket if it is known to be down.
 void setSoLinger(boolean lingervalue, int val)
          Enable/disable SO_LINGER with the specified linger time in seconds.
 void setSoTimeout(int milliseconds)
          Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.
 void setTcpNoDelay(boolean on)
          Disable Nagle's Algorithm if you supply true.
 String toString()
          Gets the socket in a string format If the socket has not be connected, "socket not connected" will be returned
 void write(byte thebyte)
          Writes a byte to the socket.
 void write(byte[] bytes)
          Writes a set of bytes to the socket.
 void yourSocketIsDown()
          This function gets called if our socket is used and found to be down ...
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

READBYTE_NO_DATA

public static final int READBYTE_NO_DATA
no data available to read on connection, but connection is still up
Constructor Detail

ReconnectableClientSocket

public ReconnectableClientSocket(TcpipHost targetHost,
                                 int shortcutConnectionPeriodInMilliseconds)

ReconnectableClientSocket

public ReconnectableClientSocket(TcpipHost targetHost,
                                 TcpipHost socksHost,
                                 int shortcutConnectionPeriodInMilliseconds)
Method Detail

getVirtualSocketNumber

public int getVirtualSocketNumber()

yourSocketIsDown

public void yourSocketIsDown()
This function gets called if our socket is used and found to be down ...
Specified by:
yourSocketIsDown in interface SocketDownInterface

isUp

public boolean isUp()
Determines if the socket is up
Returns:
true if the socket is up

reconnectIfKnownDown

public boolean reconnectIfKnownDown()
                             throws IOException
Reconnects the socket if it is known to be down.
Returns:
true if we brought up a new connection, false if we thought the socket was still up and no new connection was needed
Throws:
IOException - if the socket connection can not be made If the user wants us to shortcut connection failures and the most recent connection was a failure and it occurred not long ago.

available

public int available(int expectingToReadFromVirtualSocketNumber)
              throws IOException

readByte

public int readByte(int expectingToReadFromVirtualSocketNumber)
             throws IOException
Reads a byte from the socket
Returns:
READBYTE_NO_DATA if no data available to be read on the socket 0 to 255 byte value if a byte was read
Throws:
IOException - if the expected (or current) connection is down

read

public int read(int expectingToReadFromVirtualSocketNumber,
                byte[] ba,
                int offset,
                int maxLengthToRead)
         throws IOException
Reads a set of bytes from the socket Same args (after the first one) and return values as InputStream.read(byte[], int, int)
Parameters:
ba - the array in to which the set bytes will be placed
offset - the starting offset in ba where the bytes will be placed
maxLengthToRead - the maximum number of bytes to read
Returns:
the number of bytes that was actually read.
Throws:
IOException - if the connection has gone down or an error occurs reading from the socket.

write

public void write(byte[] bytes)
           throws IOException
Writes a set of bytes to the socket. A user of this class must verify on their own, that they are writing to the proper connection (virtual socket) and that it has not gone down and come up between writing to the socket.
Throws:
IOException - if an I/O error occurs.

write

public void write(byte thebyte)
           throws IOException
Writes a byte to the socket. A user of this class must verify on their own, that they are writing to the proper connection (virtual socket) and that it has not gone down and come up between writing to the socket.
Throws:
IOException - if an I/O error occurs.

flush

public void flush()
           throws IOException
Flushes buffered data for the socket's OutputStream to written to the destination. A user of this class must verify on their own, that they are writing to the proper connection (virtual socket) and that it has not gone down and come up between writing to the socket.
Throws:
IOException - if an I/O error occurs.

close

public void close()
Closes the socket and amy also flush bufferd output data.

setSoTimeout

public void setSoTimeout(int milliseconds)
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. Does the best it can at setting the timeout without signalling exceptions. The value is set and maintained across the all later connections made by this object. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.io.InterruptedIOException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be greater than 0. A timeout of zero is interpreted as an infinite timeout.
Parameters:
timeout - the socket timeout value in milliseconds.

setTcpNoDelay

public void setTcpNoDelay(boolean on)
Disable Nagle's Algorithm if you supply true. By setting this to true on a socket, the TCP/IP stack does not wait for ACKs when sending "small" packets of data. See TCP/IP Illustrated Volume 1 for more discussion on Nagle's algorithm.
Parameters:
on - true if NODELAY algorithm is to be disabled

setSoLinger

public void setSoLinger(boolean lingervalue,
                        int val)
                 throws SocketException
Enable/disable SO_LINGER with the specified linger time in seconds. If the specified timeout value exceeds 65,535 it will be reduced to 65,535.
Parameters:
on - true indicates the socket should linger on.
val - the linger time in seconds.

getInetAddress

public InetAddress getInetAddress()
Gets the socket's internet address
Returns:
an InetAddress representing the IP address of the target host

getLocalAddress

public InetAddress getLocalAddress()
Gets the socket's local internet address
Returns:
an InetAddress representing the IP address of the local host

getLocalPort

public int getLocalPort()
Gets the socket's local port number
Returns:
the port number of the local host

getPort

public int getPort()
Gets the socket's port number
Returns:
a port number

getTcpNoDelay

public boolean getTcpNoDelay()
                      throws IOException
Returns whether Nagle's Algorithm is disabled or not
Returns:
true if TCP_NODELAY is enabled

getSoTimeout

public int getSoTimeout()
                 throws IOException
Returns the socket timeout setting
Returns:
0 indicates the timeout option is disabled (a timeout of infinity) Other values returned are the timeout setting in milliseconds
Throws:
IOException - if a error occurs obtaining the timeout value.

getSoLinger

public int getSoLinger()
                throws IOException
Returns setting for SO_LINGER. -1 implies that the option is disabled.
Returns:
the linger timeout in seconds or -1 if the linger option is disabled.
Throws:
IOException - if the linger setting can not be obtained.

toString

public String toString()
Gets the socket in a string format If the socket has not be connected, "socket not connected" will be returned
Overrides:
toString in class Object
Returns:
the socket in a string format