|
copyright The Portico Project 2008. | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.portico.lrc.LRC
public class LRC
This class represents the core the Portico local runtime component. It contains the various message sinks that process incoming and outgoing messages, in addition to all the state data regarding a particular federate and the communications binding connection over which it can send messages so that they reach the RTI.
Messaging and Behaviour The LRC includes twoMessageSink
s that perform processing on messages that are travelling
to and from the RTI. These sinks are briefly described below:
RTIambassador
and are destined to be sent to the RTI. The various
handler in the lrc-request sink generally perform validation logic on the requests, ensuring
that any messages that contain obvious errors are stopped before they are sent to the RTI via
a potentially expensive I/O call. These checks include things like making sure handles are
valid and ensuring that the LRC is in the appropriate state to call the message (can't request
a time advance when one is already pending). Not all validation can be done on the client
side however, and in some cases, no validation can be done at all. The lrc-request sink has
a default handler that will automatically send the message over the LRCConnection
to
the RTI if there are no handlers for it. Once a handler has done all the checks, it can access
the LRCConnection
and send the request to the RTI. The response message is eventually
turned into the return value for the RTIambassador
call, although generally all
that is being checked for is the absence of an error (as most return values are void).
ISpecHelper
) is quite small, and creating a bunch
of separate classes to do a relatively small amount of work seemed like overkill.
LRC
includes an instance of the LRCQueue
class. As callback messages are
received from the RTI, they are placed on this queue. The LRCQueue
imeplements special
release semantics depending on the status of the message (TSO/RO) and the current status of the
federate. When a federate starts evoking callbacks, these messages are retrieved and passed to
the lrc-callback sink for processing (note: callbacks are not processed as they are received).
As such, the LRC should generally only require a single thread. This is the same thread that is
running the federate. When the federate invokes RTIambassador calls, the messages are created
and dropped into the lrc-request sink where they can be processed and sent to the RTI. The
federate then blocks until the RTI responds (not a callback). When the federate is ready for
callbacks to be received, they invoke tick() (or evokeCallbacks(), or whatever) and the tick
method will take messages from the LRCQueue
and pass them to the lrc-callback sink which
in turn should see them delivered to the federate. This all happens while the federate is blocked
on the tick call.
While the main processing of the RTI does not require a thread of its own (it just uses the
federate thread), depending on the communications binding and active plugins that have been
deployed, other threads may be started. Fore example, the JSOP bindings need a separate thread
to service the socket connection, listening all the time for incoming callback messages. When it
received one, it puts it on the LRCQueue
, thus populating it without disturbing the main
thread. There may also be plugins that start other services that themselves require additional
threads. The important thing to note is that you cannot guarantee that the LRC will only use a
certain amount of threads without knowing the threading requirements of the binding in question
and any additional plugins that will be deployed.
LRC State
All LRC state data is stored in the LRCState
instance that is contained within every
LRC
. Rather than pollute the LRC
class with a bunch of state data, it was
factored out into a dedicated data-object. The LRCState
also includes links to other
data storing entities such as the LRCInstanceRepository
which contains a cache of all
object related information that a particular federate knows about. See the LRCState
javadoc for more information.
LRC Connection
The communications portion of Portico is communications binding neutral. As such, the actual
classes that perform the communications between an LRC and the RTI (and the protocol they
implement) are totally hidden from the LRC
. When the LRCConfigurator
configures
an LRC
instance, it consults a number of potential sources to determine the
fully-qualified name of the LRCConnection
subclass that should be used to perform the
communications with the RTI. The LRC
stores a reference to this instance and it is used
to send/receive messages from the RTI in its own implementation-specific manner.
Specification Difference Handling
The various HLA specifications contain a large amount of incompatible elements (primarily,
exception types). For whatever reason, actual API compatibility does not appear to have been
considered during the specification process. To get around this, the LRC, like the rest of
Portico, uses a special "compatibility" layer. These classes are housed within the
org.portico.shared.compat
package and constitute a general group of exception types and
other related classes. Throughout all the handlers and other components within Portico, these
types, and ONLY these types should be used. At the very last minute they are mapped onto the
appropriate specification-specific equivalents.
To help with some other specification-specific tasks, each LRC has an ISpecHelper
implemenation. There is an implementation for each specification and it maintains a bunch of
specification dependant entities and tasks.
Nested Class Summary | |
---|---|
private class |
LRC.LRCDefaultCallbackHandler
This class will act as the default handler for the lrc-callback message sink. |
private class |
LRC.LRCDefaultRequestHandler
This will act as the default handler for the lrc-request MessageSink . |
Field Summary | |
---|---|
protected org.apache.log4j.Logger |
callbackLogger
|
protected LRCQueue |
callbackQueue
|
protected com.lbf.commons.messaging.MessageSink |
callbackSink
|
protected LRCConnection |
connection
|
protected ISpecHelper |
helper
|
static String |
KEY_LRC
When the LRC is put in Bags/Maps, this is the key that should be used to identify it |
protected org.apache.log4j.Logger |
logger
|
protected com.lbf.commons.messaging.MessageSink |
requestSink
|
protected LRCState |
state
|
protected HLAVersion |
version
|
Constructor Summary | |
---|---|
LRC(HLAVersion version,
ISpecHelper helper)
Create a new instance of the LRC that is targeted at the given HLAVersion
and that should use the provided ISpecHelper . |
Method Summary | |
---|---|
org.apache.log4j.Logger |
getCallbackLogger()
|
LRCQueue |
getCallbackQueue()
|
com.lbf.commons.messaging.MessageSink |
getCallbackSink()
|
HLAVersion |
getHLAVersion()
|
LRCConnection |
getLRCConnection()
|
org.apache.log4j.Logger |
getLRCLogger()
|
LRCState |
getLRCState()
|
com.lbf.commons.messaging.MessageSink |
getRequestSink()
|
ISpecHelper |
getSpecHelper()
Fetches the current specification-specific helper. |
void |
reinitialize()
Cleans the entire LRC of all state and sets it up as new. |
void |
setLRCConnection(LRCConnection connection)
|
void |
setSpecHelper(ISpecHelper helper)
|
void |
tick()
This method will take some time to poll for any messages waiting to be processed in the LRC. |
boolean |
tick(double min,
double max)
Process the callback queue for the given amount of time (in seconds). |
private boolean |
tickNanos(long nanos)
Do some tick processing at least the given amount of time (in nanoseconds). |
private boolean |
tickNanosSingle(long timeout)
This tick() implementation is meant to support the 1516-style evoke single callback facility. |
private void |
tickProcess(FED_CallbackMessage message)
Passes the given message to the callback sink (wrapped up in a context) |
boolean |
tickSingle(double wait)
Try and process a single callback. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final String KEY_LRC
protected com.lbf.commons.messaging.MessageSink requestSink
protected com.lbf.commons.messaging.MessageSink callbackSink
protected LRCQueue callbackQueue
protected LRCState state
protected HLAVersion version
protected ISpecHelper helper
protected LRCConnection connection
protected org.apache.log4j.Logger logger
protected org.apache.log4j.Logger callbackLogger
Constructor Detail |
---|
public LRC(HLAVersion version, ISpecHelper helper) throws JRTIinternalError
LRC
that is targeted at the given HLAVersion
and that should use the provided ISpecHelper
. This method will call
reinitialize()
before it returns in order to set up and configure the LRC. If there
is a problem with this process (for example, the configuration file contains an error) then
a JRTIinternalError
will be thrown.
JRTIinternalError
Method Detail |
---|
public void reinitialize() throws JRTIinternalError
LRC
is first being constructed, and when it has resigned from a federation
(so that when it rejoins, it can do so with a clean state).
This method will first wipe clean all the information in the linked LRCState
instance
before creating new instances of the various message sinks and the LRCQueue
(to
ensure that there are no left-over callbacks left for processing).
After this, the LRC
is passed to the LRCConfigurator
where the configuration
file is applied to it, along with the configurations from the various plugins that have been
deployed. If any of this causes an error, a JRTIinternalError
will be thrown.
JRTIinternalError
public void tick() throws JRTIinternalError, JConcurrentAccessAttempted
LRCProperties.LRC_TICK_TIMEOUT
if there is nothing to process
JRTIinternalError
JConcurrentAccessAttempted
public boolean tick(double min, double max) throws JRTIinternalError, JConcurrentAccessAttempted
JRTIinternalError
JConcurrentAccessAttempted
public boolean tickSingle(double wait) throws JRTIinternalError, JConcurrentAccessAttempted
wait
- The time to wait for a single message to be received (in seconds)
JRTIinternalError
JConcurrentAccessAttempted
private boolean tickNanos(long nanos) throws JRTIinternalError
JRTIinternalError
private boolean tickNanosSingle(long timeout) throws JRTIinternalError
timeout
- The time in nanoseconds to wait for a callback if there is not currently
one available.
JRTIinternalError
- If there is a problem processing the callbacksprivate void tickProcess(FED_CallbackMessage message) throws JRTIinternalError
JRTIinternalError
public LRCConnection getLRCConnection()
public void setLRCConnection(LRCConnection connection)
public LRCState getLRCState()
public HLAVersion getHLAVersion()
public com.lbf.commons.messaging.MessageSink getRequestSink()
public com.lbf.commons.messaging.MessageSink getCallbackSink()
public LRCQueue getCallbackQueue()
public org.apache.log4j.Logger getLRCLogger()
public org.apache.log4j.Logger getCallbackLogger()
public ISpecHelper getSpecHelper()
public void setSpecHelper(ISpecHelper helper)
|
copyright The Portico Project 2008. | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |