Package emissary.core
Class MobileAgent
- java.lang.Object
-
- emissary.core.MobileAgent
-
- All Implemented Interfaces:
IMobileAgent
,MobileAgentMBean
,Serializable
,Runnable
- Direct Known Subclasses:
HDMobileAgent
public abstract class MobileAgent extends Object implements IMobileAgent, MobileAgentMBean
An autonomous hunk of software- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description static String
AGENT_THREAD
protected String
agentId
protected IServiceProviderPlace
arrivalPlace
static int
DEFAULT_MAX_ITINERARY_STEPS
static int
DEFAULT_MAX_MOVE_ERRORS
protected static String
DONE_FORM
protected static String
ERROR_FORM
protected AtomicBoolean
idle
protected String
lastPlaceProcessed
protected static org.slf4j.Logger
logger
protected int
maxItinerarySteps
protected int
maxMoveErrors
protected int
moveErrorsOccurred
protected Deque<DirectoryEntry>
nextKeyQueue
protected static String
NO_AGENT_ID
protected IBaseDataObject
payload
protected static org.slf4j.Logger
probeLogger
protected boolean
processFirstPlace
protected Thread
thread
protected boolean
timeToQuit
-
Constructor Summary
Constructors Constructor Description MobileAgent()
Still have an uncaught exception handler but not really in a true ThreadGroup with other agentsMobileAgent(ThreadGroup threadGroup, String threadName)
Create a new reusable Agent
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
addParallelTrackingInfo(String t)
protected void
agentControl(IServiceProviderPlace currentPlaceArg)
The main control loop to determine and go through an itinerary until the payload is finished (no where else to go)String
agentId()
Return the IDprotected void
agentReturn()
Clean up, idle, and return agent to poolvoid
arrive(Object dataObject, IServiceProviderPlace arrivalPlaceArg, int moveErrorCount, List<DirectoryEntry> queuedItineraryItems)
This is for an already in process agent arriving at a new place from a "moveTo".protected void
atPlace(IServiceProviderPlace place, IBaseDataObject payloadArg)
Do work now that we have arrived at the specified placeprotected void
checkInterrupt(IServiceProviderPlace place)
protected boolean
checkParallelTrackingFor(String type)
protected void
clear()
Clear out the payload and other private stuffprotected void
clearParallelTrackingInfo()
void
dumpPlaceStats()
DirectoryEntry[]
getItineraryQueueItems()
Provide access to the itinerary queue for the MoveAdapterint
getMaxItinerarySteps()
Get the maximum number of itinerary stepsint
getMaxMoveErrors()
Get the number of move errorsint
getMoveErrorCount()
Provide access to the move-error counter for the MoveAdapterString
getName()
Report this agents name for logging purposesprotected DirectoryEntry
getNextKey(IServiceProviderPlace place, IBaseDataObject payloadArg)
Get the next key from the directory with error handling Can return null if there is no place to handle the formIBaseDataObject
getPayload()
Return a reference to the payload of this agentprotected boolean
getProcessFirstPlace()
Getter for processFirstPlacevoid
go(Object payloadArg, IServiceProviderPlace arrivalPlaceArg)
A little more than the name implies, this method sets the things required for an idle agent to get moving again.protected void
go(Object dataObject, IServiceProviderPlace arrivalPlaceArg, boolean processAtFirstPlace)
Private implementation for both of the above arrive and go methods, uses the setProcessFirstPlace to communicate on which path we entered to the agent's threadboolean
isInUse()
Report whether we are busy or notprotected boolean
isParallelServiceType(int typeSetPosition)
Evaluate parallel attribute of specified type indexvoid
killAgent()
Call this method to permanently stop the running thread when we finish what we are doingvoid
killAgentAsync()
Kill asynchronouslyprotected void
logAgentCompletion(IBaseDataObject payloadArg)
Make a nice log message when we are done with the payloadprotected DirectoryEntry
nextKeyFromDirectory(String dataId, IServiceProviderPlace place, DirectoryEntry lastEntry, IBaseDataObject payloadArg)
Communicate with the directory through the current place to get the next place to go.protected static void
purgeNonFinalForms(IBaseDataObject payloadArg)
Delete all forms on the stack that are not final.protected void
recordHistory(DirectoryEntry placeEntry, IBaseDataObject payloadArg)
Record the processing history in the data objectprotected void
recordHistory(IServiceProviderPlace place, IBaseDataObject payloadArg)
Record the processing history in the data objectprotected TimedResource
resourceWatcherStart(IServiceProviderPlace place)
void
run()
Runnable interface, starts this agent running on its own thread.protected void
setAgentId(String theId)
Build the unique agent ID for carrying this payload around mostly used in error reportingprotected void
setArrivalPlace(IServiceProviderPlace p)
Set the current place we should kick off withvoid
setMaxItinerarySteps(int value)
Set the maximum number of itinerary steps before this instance will turn the workflow into an ERROR conditionvoid
setMaxMoveErrors(int value)
Set the maximum number of move attempts that can error out before this instance will quit trying and set the workflow to be an ERROR conditionprotected void
setPayload(IBaseDataObject p)
Set the payloadprotected void
setProcessFirstPlace(boolean arg)
Setter for processFirstPlacestatic int
typeLookup(String s)
Get index in typeSet for specified string, 0 if not found-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface emissary.core.IMobileAgent
getLastPlaceProcessed, getPayloadForTransport, interrupt, isZombie, payloadCount
-
-
-
-
Field Detail
-
logger
protected static final org.slf4j.Logger logger
-
probeLogger
protected static final org.slf4j.Logger probeLogger
-
thread
@Nullable protected transient Thread thread
-
AGENT_THREAD
public static final String AGENT_THREAD
- See Also:
- Constant Field Values
-
DEFAULT_MAX_MOVE_ERRORS
public static final int DEFAULT_MAX_MOVE_ERRORS
- See Also:
- Constant Field Values
-
maxMoveErrors
protected int maxMoveErrors
-
DEFAULT_MAX_ITINERARY_STEPS
public static final int DEFAULT_MAX_ITINERARY_STEPS
- See Also:
- Constant Field Values
-
maxItinerarySteps
protected int maxItinerarySteps
-
ERROR_FORM
protected static final String ERROR_FORM
- See Also:
- Constant Field Values
-
DONE_FORM
protected static final String DONE_FORM
- See Also:
- Constant Field Values
-
payload
@Nullable protected IBaseDataObject payload
-
idle
protected AtomicBoolean idle
-
arrivalPlace
@Nullable protected transient IServiceProviderPlace arrivalPlace
-
processFirstPlace
protected boolean processFirstPlace
-
lastPlaceProcessed
@Nullable protected String lastPlaceProcessed
-
NO_AGENT_ID
protected static final String NO_AGENT_ID
-
agentId
protected transient String agentId
-
timeToQuit
protected transient volatile boolean timeToQuit
-
nextKeyQueue
protected Deque<DirectoryEntry> nextKeyQueue
-
moveErrorsOccurred
protected int moveErrorsOccurred
-
-
Constructor Detail
-
MobileAgent
public MobileAgent()
Still have an uncaught exception handler but not really in a true ThreadGroup with other agents
-
MobileAgent
public MobileAgent(ThreadGroup threadGroup, String threadName)
Create a new reusable Agent- Parameters:
threadGroup
- group we operate itthreadName
- symbolic name for this agent thread
-
-
Method Detail
-
getName
public String getName()
Report this agents name for logging purposes- Specified by:
getName
in interfaceIMobileAgent
-
run
public void run()
Runnable interface, starts this agent running on its own thread. It will wait unless it has a payload and a place to start with. You can set both of these items at once using the go method, which will then notify us to come out of the wait state and process the payload
-
killAgent
public void killAgent()
Call this method to permanently stop the running thread when we finish what we are doing- Specified by:
killAgent
in interfaceIMobileAgent
-
killAgentAsync
public void killAgentAsync()
Kill asynchronously- Specified by:
killAgentAsync
in interfaceIMobileAgent
-
isInUse
public boolean isInUse()
Report whether we are busy or not- Specified by:
isInUse
in interfaceIMobileAgent
-
setArrivalPlace
protected void setArrivalPlace(@Nullable IServiceProviderPlace p)
Set the current place we should kick off with
-
setPayload
protected void setPayload(@Nullable IBaseDataObject p)
Set the payload
-
agentId
public String agentId()
Return the ID- Specified by:
agentId
in interfaceIMobileAgent
-
clear
protected void clear()
Clear out the payload and other private stuff
-
clearParallelTrackingInfo
protected void clearParallelTrackingInfo()
-
addParallelTrackingInfo
protected void addParallelTrackingInfo(String t)
-
checkParallelTrackingFor
protected boolean checkParallelTrackingFor(String type)
-
getPayload
public IBaseDataObject getPayload()
Return a reference to the payload of this agent- Specified by:
getPayload
in interfaceIMobileAgent
-
agentControl
protected void agentControl(IServiceProviderPlace currentPlaceArg)
The main control loop to determine and go through an itinerary until the payload is finished (no where else to go)- Parameters:
currentPlaceArg
- where we are now
-
atPlace
protected void atPlace(IServiceProviderPlace place, IBaseDataObject payloadArg)
Do work now that we have arrived at the specified place- Parameters:
place
- the place we are asking to work for uspayloadArg
- the data for the place to operate on
-
checkInterrupt
protected final void checkInterrupt(IServiceProviderPlace place)
-
resourceWatcherStart
protected TimedResource resourceWatcherStart(IServiceProviderPlace place)
-
agentReturn
protected void agentReturn()
Clean up, idle, and return agent to pool
-
getNextKey
@Nullable protected DirectoryEntry getNextKey(@Nullable IServiceProviderPlace place, @Nullable IBaseDataObject payloadArg)
Get the next key from the directory with error handling Can return null if there is no place to handle the form- Parameters:
place
- the place we will use to access the directorypayloadArg
- the current payload we care about- Returns:
- the SDE answer from the directory
-
isParallelServiceType
protected boolean isParallelServiceType(int typeSetPosition)
Evaluate parallel attribute of specified type index
-
typeLookup
public static int typeLookup(String s)
Get index in typeSet for specified string, 0 if not found
-
nextKeyFromDirectory
protected DirectoryEntry nextKeyFromDirectory(String dataId, IServiceProviderPlace place, DirectoryEntry lastEntry, IBaseDataObject payloadArg)
Communicate with the directory through the current place to get the next place to go. These are all local calls since all the local directories have all the information This call may cause several key entries to be returned from the directory. All will be put on an internal queue and the first one will be returned to the caller. Caller knows to look on the internal queue for additional entries before calling this method again.
-
setAgentId
protected void setAgentId(@Nullable String theId)
Build the unique agent ID for carrying this payload around mostly used in error reporting- Parameters:
theId
- usually comes from the shortName of the payload
-
go
public void go(Object payloadArg, IServiceProviderPlace arrivalPlaceArg)
A little more than the name implies, this method sets the things required for an idle agent to get moving again. This is to be used when starting the agent from a pickup place because although we start with an initial 'place' we don't use it for processing, just to get the nextKey from the directory there.- Specified by:
go
in interfaceIMobileAgent
- Parameters:
payloadArg
- the real payload, existing if any will be clearedarrivalPlaceArg
- the place we start at
-
go
protected void go(@Nullable Object dataObject, @Nullable IServiceProviderPlace arrivalPlaceArg, boolean processAtFirstPlace)
Private implementation for both of the above arrive and go methods, uses the setProcessFirstPlace to communicate on which path we entered to the agent's thread- Parameters:
dataObject
- the real payloadarrivalPlaceArg
- the place we start atprocessAtFirstPlace
- true if we should call process on arrivalPlaceArg
-
getMoveErrorCount
public int getMoveErrorCount()
Provide access to the move-error counter for the MoveAdapter- Specified by:
getMoveErrorCount
in interfaceIMobileAgent
-
getItineraryQueueItems
public DirectoryEntry[] getItineraryQueueItems()
Provide access to the itinerary queue for the MoveAdapter- Specified by:
getItineraryQueueItems
in interfaceIMobileAgent
- Returns:
- array of DirectoryEntry
-
arrive
public void arrive(Object dataObject, IServiceProviderPlace arrivalPlaceArg, int moveErrorCount, List<DirectoryEntry> queuedItineraryItems) throws Exception
This is for an already in process agent arriving at a new place from a "moveTo". This is different than the above method because we presume we have arrived at this place in order to do some processing here, not just because we got picked up by it. So we don't need to get a key first, just start processing.- Specified by:
arrive
in interfaceIMobileAgent
- Parameters:
dataObject
- the real payload, exisitng if any will be clearedarrivalPlaceArg
- the place we start atmoveErrorCount
- transported move error counterqueuedItineraryItems
- transported itinerary items list of DirectoryEntry- Throws:
Exception
-
purgeNonFinalForms
protected static void purgeNonFinalForms(IBaseDataObject payloadArg)
Delete all forms on the stack that are not final. This is called in error conditions to try and break out of loops or terminate other badness and zip to the end- Parameters:
payloadArg
- the dataobject to work on
-
logAgentCompletion
protected void logAgentCompletion(IBaseDataObject payloadArg)
Make a nice log message when we are done with the payload- Parameters:
payloadArg
- the one we just finished with
-
recordHistory
protected void recordHistory(IServiceProviderPlace place, IBaseDataObject payloadArg)
Record the processing history in the data object- Parameters:
place
- where the processing is taking placepayloadArg
- the dataobject that is being processed
-
recordHistory
protected void recordHistory(DirectoryEntry placeEntry, IBaseDataObject payloadArg)
Record the processing history in the data object- Parameters:
placeEntry
- where the processing is taking placepayloadArg
- the data object that is being processed
-
setProcessFirstPlace
protected void setProcessFirstPlace(boolean arg)
Setter for processFirstPlace- Parameters:
arg
- the new value for processFirstPlace
-
getProcessFirstPlace
protected boolean getProcessFirstPlace()
Getter for processFirstPlace- Returns:
- the value of processFirstPlace
-
dumpPlaceStats
public void dumpPlaceStats()
- Specified by:
dumpPlaceStats
in interfaceMobileAgentMBean
-
getMaxMoveErrors
public int getMaxMoveErrors()
Get the number of move errors- Specified by:
getMaxMoveErrors
in interfaceIMobileAgent
-
setMaxMoveErrors
public void setMaxMoveErrors(int value)
Set the maximum number of move attempts that can error out before this instance will quit trying and set the workflow to be an ERROR condition- Specified by:
setMaxMoveErrors
in interfaceIMobileAgent
- Parameters:
value
- the maximum number of move failures
-
getMaxItinerarySteps
public int getMaxItinerarySteps()
Get the maximum number of itinerary steps- Specified by:
getMaxItinerarySteps
in interfaceIMobileAgent
-
setMaxItinerarySteps
public void setMaxItinerarySteps(int value)
Set the maximum number of itinerary steps before this instance will turn the workflow into an ERROR condition- Specified by:
setMaxItinerarySteps
in interfaceIMobileAgent
- Parameters:
value
- the new maximum number of steps
-
-