gr.uoa.di.madgik.grs.proxy.tcp.mirror
Class TCPReaderMirror

java.lang.Object
  extended by java.lang.Thread
      extended by gr.uoa.di.madgik.grs.proxy.tcp.mirror.TCPReaderMirror
All Implemented Interfaces:
IMirror, java.lang.Runnable

public class TCPReaderMirror
extends java.lang.Thread
implements IMirror

This implementation of the IMirror interface specializes the mirroring procedure that needs to be performed from the reader side of the mirroring procedure. The technology employed is communication over raw TCP sockets. The communication protocol is coupled with the one implemented by the TCPWriterMirror which is the writer side counterpart of this class

Author:
gpapanikos

Nested Class Summary
 
Nested classes/interfaces inherited from class java.lang.Thread
java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
 
Nested classes/interfaces inherited from interface gr.uoa.di.madgik.grs.proxy.mirror.IMirror
IMirror.MirroringState
 
Field Summary
static long LongMirrorPeriod
          The default max period of communication inactivity time span.
static long ShortMirrorPeriod
          The default min period of communication inactivity time span.
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
TCPReaderMirror()
           
 
Method Summary
 void dispose()
          Dispose the resources employed by the mirroring implementations
 void dispose(boolean purge)
          This method disposes the resources that are used by the instance but does so in two phases.
 IBuffer getBuffer()
          Retrieves the IBuffer that is managed by the IMirror implementation.
 GRS2ProxyMirrorProtocolErrorException getInitializationError()
          In case the initialization was not successful, and the call to waitInitialization() returned false, this method will return the error that was recorded during the initialization.
 void handle()
          This invocation of this method starts a new execution thread where the mirroring procedure is executed.
 void overrideBufferCapacity(int capacity)
          Instructs the mirror to use a different buffer capacity than that transmitted by the respective TCPWriterMirror.
 boolean pollPartial(long recordIndex, int fieldIndex)
          
 long requestPartial(long recordIndex, int fieldIndex, IBuffer.TransportOverride override, java.lang.Object notify)
          This method is used by the reader side mirror to request payload that belongs to an IBuffer item that has been transfered only partially and more data is requested by the reader client
 void run()
          
 void setHostname(java.lang.String hostname)
          Sets the name of the host where the respective TCPWriterMirror instance is running
 void setKey(java.lang.String key)
          Sets the key on the remote registry that holds the IBuffer this mirror is interested in consuming
 void setPort(int port)
          Sets the port in the remote host where the respective TCPWriterMirror is listening
 boolean waitInitialization()
          This method can be used by TCPReaderMirror clients, that want to be sure that the initialization procedure of the protocol is completed before they continue their operation.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

LongMirrorPeriod

public static final long LongMirrorPeriod
The default max period of communication inactivity time span. Depending on the previous communication exchange this or the respective ShortMirrorPeriod is used. Currently this value is set to 100 milliseconds

See Also:
Constant Field Values

ShortMirrorPeriod

public static final long ShortMirrorPeriod
The default min period of communication inactivity time span. Depending on the previous communication exchange this or the respective LongMirrorPeriod is used. Currently this value is set to 50 milliseconds

See Also:
Constant Field Values
Constructor Detail

TCPReaderMirror

public TCPReaderMirror()
Method Detail

setHostname

public void setHostname(java.lang.String hostname)
Sets the name of the host where the respective TCPWriterMirror instance is running

Parameters:
hostname - the name of the host

setPort

public void setPort(int port)
Sets the port in the remote host where the respective TCPWriterMirror is listening

Parameters:
port - the port number

setKey

public void setKey(java.lang.String key)
Sets the key on the remote registry that holds the IBuffer this mirror is interested in consuming

Parameters:
key - the registry key of the IBuffer to consume

overrideBufferCapacity

public void overrideBufferCapacity(int capacity)
Instructs the mirror to use a different buffer capacity than that transmitted by the respective TCPWriterMirror. Capacity overriding only takes place if the requested capacity is smaller than the one specified by the respective TCPWriterMirror, otherwise the latter is used

Parameters:
capacity - The buffer capacity

getBuffer

public IBuffer getBuffer()
Retrieves the IBuffer that is managed by the IMirror implementation. Depending on the mirror side, this instance is either the one the writer is authoring, or the one the reader is accessing.

Specified by:
getBuffer in interface IMirror
Returns:
the IBuffer that is managed by the IMirror implementation
See Also:
IMirror.getBuffer()

handle

public void handle()
            throws GRS2ProxyMirrorInvalidOperationException
This invocation of this method starts a new execution thread where the mirroring procedure is executed. The created thread of execution is executed in the background and as a daemon service.

Throws:
GRS2ProxyMirrorInvalidOperationException - if the mirroring state does not allow the operation to be executed

dispose

public void dispose()
Dispose the resources employed by the mirroring implementations

This method actually invokes the respective dispose(boolean) with an argument of false. This is because the actual disposing needs to take place when the mirroring thread is prepared to gracefully exit its execution

Specified by:
dispose in interface IMirror
See Also:
IMirror.dispose()

dispose

public void dispose(boolean purge)
This method disposes the resources that are used by the instance but does so in two phases. One can request the disposal passing an argument of false which puts the mirroring thread in a state where the needed actions are taken to gracefully exit this part of the protocol but also notify the respective TCPWriterMirror to stop the mirroring procedure gracefully. When the method in again invoked with a true argument from the protocol implementing thread, all resources are disposed.

Parameters:
purge - whether the resources need to be immediately disposed, or this need to wait until the protocol thread is ready to purge the involved resources

waitInitialization

public boolean waitInitialization()
This method can be used by TCPReaderMirror clients, that want to be sure that the initialization procedure of the protocol is completed before they continue their operation. If someone invokes this method before communication has been successfully been established with the remote TCPWriterMirror, and the involved IBuffer information including the RecordDefinitions are exchanged and the IBuffer is initialized, the method will block him. After this operation is completed, and for any later invocation, the method will return control immediately

Returns:
true if the initialization was successful, false if there was an error during initialization

getInitializationError

public GRS2ProxyMirrorProtocolErrorException getInitializationError()
In case the initialization was not successful, and the call to waitInitialization() returned false, this method will return the error that was recorded during the initialization. If no error was recorded, null is returned

Returns:
the initialization error or null if no error was recorded

pollPartial

public boolean pollPartial(long recordIndex,
                           int fieldIndex)
                    throws GRS2ProxyMirrorDisposedException

the management of the partial requests is performed using PartialRequestManager

Specified by:
pollPartial in interface IMirror
Parameters:
recordIndex - The record index / id, for which the requester has requested data to be delivered
fieldIndex - The field index of the specific record for which data are requested
Returns:
false if the requester needs to wait again until data is returned false otherwise. In case true is returned, the data have either been retrieved, or no more data is expected to be send, possibly because of a closed connection
Throws:
GRS2ProxyMirrorDisposedException - the mirror is already disposed
See Also:
IMirror.pollPartial(long, int)

requestPartial

public long requestPartial(long recordIndex,
                           int fieldIndex,
                           IBuffer.TransportOverride override,
                           java.lang.Object notify)
                    throws GRS2ProxyMirrorInvalidOperationException,
                           GRS2ProxyMirrorDisposedException
This method is used by the reader side mirror to request payload that belongs to an IBuffer item that has been transfered only partially and more data is requested by the reader client

The indicative time returned for the next poll operation is the amount defined as ShortMirrorPeriod

Specified by:
requestPartial in interface IMirror
Parameters:
recordIndex - The index of the record whose payload is requested. As described in Record, this index coincides with the record id.
fieldIndex - The index of the field belonging to the defined record for which additional data is requested
override - whether or not the field's IBuffer.TransportDirective should be overridden as explained in IBuffer
notify - A synchronization object that can be used for the requester to block on until the required data is provided
Returns:
An indicative amount of time that the requester can wait before the data is available. This value is only indicative and it does not imply that after this period the data will be available. For this. the IMirror.pollPartial(long, int) should be used
Throws:
GRS2ProxyMirrorDisposedException - the mirror is already disposed
GRS2ProxyMirrorInvalidOperationException - if the PartialRequestManager has not been initialized
See Also:
IMirror.requestPartial(long, int, gr.uoa.di.madgik.grs.buffer.IBuffer.TransportOverride, java.lang.Object)

run

public void run()

In the context of the mirroring procedure, the execution of this thread includes the following actions.
Initially, a connection to the remote TCPWriterMirror is established, the details of the employed IBuffer are retrieved, as well as the RecordDefinitions that describe the Records that will be retrieved. The appropriate IBuffer implementation is instantiated, configured and set with all the retrieved information.
After the initialization is completed, any blocked clients waiting to be notified on initialization completion are notified.
The main protocol loop is then initialized. On every iteration, a request is send to the remote TCPWriterMirror with the number of records that could be added to the local IBuffer, any partial data requests, as well as the status of the consumption procedure.
In the next step, any event emitted from the reader is send over to the writer
The next step is to retrieve from the TCPWriterMirror any Records send as well as partial data from the requested ones. The respective information is used to either populate new Records and add them to the local IBuffer, or to locate and enhance the Fields for which additional data have been received.
Any events that are send from the writer are also received
The remote status is also retrieved and the protocol loop continues unless it should be teardown based on the remote status.
If the remote mirror has responded with the information requested, then the period of the next protocol loop is defined as the minimum defined in ShortMirrorPeriod while in case no needed information was received the period is set to the maximum defined in LongMirrorPeriod

Specified by:
run in interface java.lang.Runnable
Overrides:
run in class java.lang.Thread
See Also:
Thread.run()