cz.cuni.pogamut.communication
Class Mediator

java.lang.Object
  extended by cz.cuni.pogamut.communication.Mediator

public class Mediator
extends java.lang.Object

Serves as the men in the middle between client and gb sending messages Client <--> Parser (Gb).

Is configured with three classes which implements methods for receiving / sending messages

1) MediatorClientInterface
-> allows to send message to the client (MessageObject) from parser
-> allows to receive message for GameBots (commands in the form of String)

2) MediatorParserInterface -> allows to receive parsed message (MessageObject) for the client

3) MediatorGBInterface
-> allows to send message to GameBots (commands in the form of String)


Usage: instantiate ... run ... if done / exception destroy it and create a new instance (another runParser() won't work).

Note:
It can be used to transfer messages between various source, shouldn't be really Parser and Client. For instance, RemoteParser is also using this class for passing the messages from Parser to the "Client" which is in fact another mediator on (possibly) another machine.

Schema - Client (Agent) using LocalParser:

Client < --- > Mediator < --- > Parser < --- > GB

Schema - Client (Agent) using RemoteParser:

Machine 1 | Machine 2
Client < --- > Mediator < -- TCP/IP -- > Mediator < --- > Parser < --- > GB

So 'Parser' means somebody in the way to the Parser and GB, 'Client' means somebody in the way to Client.

Note about synchronizations:

Before starting / terminating the mediator threads, the Mediator object is synchronizing access to threadClientParser and threadParserClient. Therefore don't use this object as a monitor for 'synchronized' statement.


Field Summary
private  MediatorClientInterface client
          Client's interface (for sending, receiving messages).
private  boolean clientParserPause
          When the agent is using LocalParser it doesn't need the Client->Parser thread, so it will pause it.
private  Flag<java.lang.Boolean> communicationAlive
          Flag which tells you whether both threads Client <--> Parser is working.
private  java.util.concurrent.CountDownLatch communicationEndLatch
          Latch which is raised when one of the parser's thread dies.
private  java.util.concurrent.CountDownLatch communicationLatch
          Latch for Parser <--> Client threads to initialize.
private  java.util.concurrent.CountDownLatch communicationLatchPublic
          Latch for Parser <--> Client threads to initialize.
private  java.util.concurrent.CountDownLatch dummy
          Dummy for pausing Client->Parser thread.
private  boolean fatalExceptionOccured
          Tells you whether fatal exception occured which prevents the communication from running -> if raised, drops both communication threads.
private  MediatorGBInterface gb
          Interface to the GB for bypassing the Client->Parser thread if needed (used by Agent who is using LocalParser).
private  java.util.logging.Logger log
          Where to log the messages.
private  MediatorParserInterface parser
          Parser's interface (for sending, receiving messages).
private  boolean shouldRun
          Internal flag which is used to terminate the communication threads if dropped by stopParser().
private  java.lang.Thread threadClientParser
          Thread which takes messages from client and passes them to parser (e.g.
private  Flag<java.lang.Boolean> threadClientParserAlive
          Client --> Parser communication thread alive flag.
private  java.lang.Thread threadParserClient
          Thread which takes messages from client and passes them to client (e.g.
private  Flag<java.lang.Boolean> threadParserClientAlive
          Parser --> Client communication thread alive flag.
 
Constructor Summary
Mediator(MediatorClientInterface client, MediatorParserInterface parser, MediatorGBInterface gb)
           
Mediator(MediatorClientInterface client, MediatorParserInterface parser, MediatorGBInterface gb, java.util.logging.Logger log)
           
 
Method Summary
private  void aboutToDieClientParserCommunicationThread()
          Clien->Thread thread is about to die: Setting various properties (e.g. this.communicationAlive flag, etc.) after terminating the thread (or right before it).
private  void aboutToDieParserClientCommunicationThread()
          Parser->Client thread is about to die: setting various properties (e.g. this.communicationAlive flag, etc.) after terminating the thread (or right before it).
private  void clientParserCommunicationIteration()
          One iteration of Client --> Parser communication ... process one message from Client to Parser.
 Flag<java.lang.Boolean> getCommunicationAliveFlag()
           
 java.util.logging.Logger getLog()
           
 Flag<java.lang.Boolean> getThreadClientParserAliveFlag()
           
 Flag<java.lang.Boolean> getThreadParserClientAliveFlag()
           
private  void initClientParserCommunication()
          Initialize the variables for Client --> Parser communication.
private  void initParserClientCommunication()
          Initialize the variables for Parser --> Client communication Currently doing nothing.
 boolean isCommunicationAlive()
          Returns state of the communication.
private  void parserClientCommunicationIteration()
          One iteration of Parser --> Client communication ... process one message from Parser to Client.
 void pauseClientParserThread()
          Used when agent runs local parser - the thread has no meaning then.
private  void raiseLatches()
          Called before the mediator dies out, it raises all latches and frees thread waiting there.
 void resumeClientParserThread()
          Resumes the Client->Parser thread (if paused).
protected  void runClientParserCommunicationThread()
          Body (run()) of the Client->Parser thread.
protected  void runParserClientCommunicationThread()
          Body (run()) of the Parser->Client thread.
 void sendMessageToGB(Command msg)
          This is shortcut for sending messages to GB for LocalParser.
protected  void startClientParserCommunicationThread()
          Creates new thread for Client->Parser communication and runs it.
 void startMediator()
          Starts the parser.
protected  void startParserClientCommunicationThread()
          Creates new thread for Parser->Client communication and runs it.
 void stopMediator()
          Hard kill of the communication.
protected  void terminateClientParserCommunicationThread()
          Unconditionally terminates the Client->Parser thread.
protected  void terminateParserClientCommunicationThread()
          Unconditionally terminates the Parser->Client thread.
 boolean waitForCommunication()
          This operation is guaranteed to block until communication is setted up.
 boolean waitForCommunication(long timeOut, java.util.concurrent.TimeUnit unit)
          This operation is guaranteed to block until communication is set up.
 void waitForCommunicationEnd()
          Waits until the communication dies out.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

threadClientParserAlive

private Flag<java.lang.Boolean> threadClientParserAlive
Client --> Parser communication thread alive flag. Tells you whether this type of communication thread is alive.


threadParserClientAlive

private Flag<java.lang.Boolean> threadParserClientAlive
Parser --> Client communication thread alive flag. Tells you whether this type of communication thread is alive.


communicationAlive

private Flag<java.lang.Boolean> communicationAlive
Flag which tells you whether both threads Client <--> Parser is working.


fatalExceptionOccured

private boolean fatalExceptionOccured
Tells you whether fatal exception occured which prevents the communication from running -> if raised, drops both communication threads.


shouldRun

private boolean shouldRun
Internal flag which is used to terminate the communication threads if dropped by stopParser().


communicationLatch

private java.util.concurrent.CountDownLatch communicationLatch
Latch for Parser <--> Client threads to initialize.


communicationLatchPublic

private java.util.concurrent.CountDownLatch communicationLatchPublic
Latch for Parser <--> Client threads to initialize. This is latch where waitForCommunication() request is waiting. We need two latches, one for threads to begin synchronously, second one for public.


communicationEndLatch

private java.util.concurrent.CountDownLatch communicationEndLatch
Latch which is raised when one of the parser's thread dies.


dummy

private java.util.concurrent.CountDownLatch dummy
Dummy for pausing Client->Parser thread.


threadClientParser

private java.lang.Thread threadClientParser
Thread which takes messages from client and passes them to parser (e.g. GB), Warning: not used when Agent is using Local Parser.


threadParserClient

private java.lang.Thread threadParserClient
Thread which takes messages from client and passes them to client (e.g. Agent),


log

private java.util.logging.Logger log
Where to log the messages.


client

private MediatorClientInterface client
Client's interface (for sending, receiving messages). Note: the client means Agent (or other object in the way where the Agent is)


parser

private MediatorParserInterface parser
Parser's interface (for sending, receiving messages). Note: the Parser means Parser (or other object in the way where the Parser is)


gb

private MediatorGBInterface gb
Interface to the GB for bypassing the Client->Parser thread if needed (used by Agent who is using LocalParser).


clientParserPause

private boolean clientParserPause
When the agent is using LocalParser it doesn't need the Client->Parser thread, so it will pause it. Here we store the state of the thread.

Constructor Detail

Mediator

public Mediator(MediatorClientInterface client,
                MediatorParserInterface parser,
                MediatorGBInterface gb)

Mediator

public Mediator(MediatorClientInterface client,
                MediatorParserInterface parser,
                MediatorGBInterface gb,
                java.util.logging.Logger log)
Method Detail

getLog

public java.util.logging.Logger getLog()

getThreadClientParserAliveFlag

public Flag<java.lang.Boolean> getThreadClientParserAliveFlag()

getThreadParserClientAliveFlag

public Flag<java.lang.Boolean> getThreadParserClientAliveFlag()

getCommunicationAliveFlag

public Flag<java.lang.Boolean> getCommunicationAliveFlag()

waitForCommunication

public boolean waitForCommunication()
This operation is guaranteed to block until communication is setted up. NOTE: when the method is finished (you pass through the latch) you still has to test isCommunicationAlive(), if not - call this method again! That's because you may be freed because of reinitialization of the latch or because of interrupt exception.


waitForCommunication

public boolean waitForCommunication(long timeOut,
                                    java.util.concurrent.TimeUnit unit)
This operation is guaranteed to block until communication is set up. NOTE: when the method is finished (you pass through the latch) you still has to test isCommunicationAlive(), if not - call this method again! That's because you may be freed because of reinitialization of the latch or because of interrupted exception.


isCommunicationAlive

public boolean isCommunicationAlive()
Returns state of the communication. (Anybody may check whether communication is OK.)

Returns:
communicationAlive flag

stopMediator

public void stopMediator()
Hard kill of the communication. Terminates the threads unconditionally. flag.


terminateParserClientCommunicationThread

protected void terminateParserClientCommunicationThread()
Unconditionally terminates the Parser->Client thread. Uses 'interrupt()' for the task. Synchronized on 'this' object.


terminateClientParserCommunicationThread

protected void terminateClientParserCommunicationThread()
Unconditionally terminates the Client->Parser thread. Uses 'interrupt()' for the task.


raiseLatches

private void raiseLatches()
Called before the mediator dies out, it raises all latches and frees thread waiting there.


aboutToDieParserClientCommunicationThread

private void aboutToDieParserClientCommunicationThread()
Parser->Client thread is about to die: setting various properties (e.g. this.communicationAlive flag, etc.) after terminating the thread (or right before it). Called from terminateParserClientCommunicationThread() or when the communication should end normally (the flag shouldRun was dropped).


aboutToDieClientParserCommunicationThread

private void aboutToDieClientParserCommunicationThread()
Clien->Thread thread is about to die: Setting various properties (e.g. this.communicationAlive flag, etc.) after terminating the thread (or right before it). Called from terminateClientParserCommunicationThread() or when the communication should end normaly (the flag shouldRun was dropped).


startParserClientCommunicationThread

protected void startParserClientCommunicationThread()
Creates new thread for Parser->Client communication and runs it. The thread will do: runParserClientCommunicationThread()


startClientParserCommunicationThread

protected void startClientParserCommunicationThread()
Creates new thread for Client->Parser communication and runs it. The thread will do: runClientParserCommunicationThread()


runParserClientCommunicationThread

protected void runParserClientCommunicationThread()
Body (run()) of the Parser->Client thread. It will wait for Client->Parser thread to become active and then inits the communication. After that it will start taking messages from the Parser and pass them to the Client while shouldRun flag is raised or exception occures.


runClientParserCommunicationThread

protected void runClientParserCommunicationThread()
Body (run()) of the Client->Parser thread. It will wait for Parser->Client thread to become active and then inits the communication. After that it will start taking messages from the Client and pass them to the Parser while shouldRun flag is raised or exception occures.


startMediator

public void startMediator()
Starts the parser. Initialize two threads which manage the Parser <--> Client communication.


waitForCommunicationEnd

public void waitForCommunicationEnd()
Waits until the communication dies out.


initParserClientCommunication

private void initParserClientCommunication()
Initialize the variables for Parser --> Client communication Currently doing nothing. Reserved for future use.


initClientParserCommunication

private void initClientParserCommunication()
Initialize the variables for Client --> Parser communication. Currently doing nothing. Reserved for future use.


parserClientCommunicationIteration

private void parserClientCommunicationIteration()
                                         throws CantReadException,
                                                CantWriteException
One iteration of Parser --> Client communication ... process one message from Parser to Client. May block. When message with type MessageType.MAP_FINISHED is received, the Mediator will stop itself to prevent the exceptions caused by closed socket (GB closes the socket after sending such message).

Throws:
CantReadException
CantWriteException

clientParserCommunicationIteration

private void clientParserCommunicationIteration()
                                         throws CantWriteException,
                                                CantReadException
One iteration of Client --> Parser communication ... process one message from Client to Parser. May block.

Throws:
CantWriteException
CantReadException

sendMessageToGB

public void sendMessageToGB(Command msg)
                     throws CantWriteException
This is shortcut for sending messages to GB for LocalParser.

Parameters:
msg -
Throws:
CantWriteException

pauseClientParserThread

public void pauseClientParserThread()
Used when agent runs local parser - the thread has no meaning then.


resumeClientParserThread

public void resumeClientParserThread()
Resumes the Client->Parser thread (if paused).