osl.manager.basic
Class BasicActorManager

java.lang.Object
  |
  +--osl.manager.ActorManager
        |
        +--osl.manager.basic.BasicActorManager

public class BasicActorManager
extends ActorManager

This class defines the basic implementation of the ActorManager class. The purpose of this class is to serve as a reference implementation for operating the foundry. This class was designed with modularity in mind so that new implementations could be created simply by extending this class.

Version:
$Revision: 1.16 $ ($Date: 1999/03/06 21:18:37 $)
See Also:
BasicActorImpl, ActorManager, ActorImpl

Inner Class Summary
protected  class BasicActorManager.ActorEntry
          This class encapsulates an entry in the local managed_actors table.
protected  class BasicActorManager.ServiceThread
          This class defines a "service" thread, which is used to handle asynchronous tasks for the BasicActorManager.
 
Field Summary
protected  Scheduler actorScheduler
          The scheduler for this actor manager.
 java.lang.String AM_VERSION
          Version information for this actor manager implementation.
protected  ActorName defaultActorName
          The default actor name which is reserved for special use by this manager.
protected  java.util.Hashtable localServices
          This hashtable maintains the current set of registered services available to local actors.
protected  java.util.Hashtable managed_actors
          This field hashes ActorNames to the ActorImpl instances they are associated with.
protected  ActorManagerName managerName
          The name of this actor manager.
static int numServiceThreads
          The initial number of "service" threads to create in the manager.
protected  RequestHandler ourHandler
          The request handler implementation to use for creating request sessions for this manager.
protected  java.util.Hashtable remoteCreates
          This hashtable temporarily holds messages for actors which are being created remotely (that is, it hashes ActorNames to Vectors).
protected  java.util.Hashtable requestMap
          This table hashes RequestID's to the requests associated with the ID.
static long SERVICE_TIMEOUT
          The length of time that a service thread should wait before killing itself off (currently 5 minutes).
protected  Queue serviceQueue
          The queue of waiting "service" threads.
protected  RequestSession session
          The session used by this actor manager to interact with remote managers.
 
Constructor Summary
BasicActorManager()
          The default constructor.
 
Method Summary
protected  ActorName actorCreate(ActorImpl caller, ActorCreateRequest request)
          This method is called by a local actor to request the creation of a new actor.
 ActorName actorCreateAlias(ActorImpl caller)
          Create an alias for an actor.
protected  void actorFatalError(ActorImpl caller, java.lang.Exception e)
          This method is called by an actor implementation to report that it has encountered a fatal error.
 java.lang.Object actorInvokeService(ActorImpl caller, ServiceName serviceName, java.lang.String meth, java.lang.Object[] serviceArgs)
          This method is called by a local actor in order to access a locally provided node service.
 void actorMigrate(ActorImpl caller, ActorManagerName where)
          This method is called by a local actor that wishes to be migrated to another manager.
protected  void actorSend(ActorImpl caller, ActorMsgRequest message)
          This method is called by a local actor to send a message to another actor.
 void handlerException(RequestSession session, java.lang.Exception except, RequestID id)
          Called when an exception has been received for an asynchronous request sent on a particular session.
protected  void implDeliver(ActorImpl actor, ActorMsgRequest msg)
          This method simply calls ActorManager.implDeliver.
 ActorName managerCreate(ActorCreateRequest request, ActorName reqName)
          This method is called to request that a new local actor be created and managed by the target actor.
 void managerDeliver(ActorMsgRequest del)
          This method is called to indicate that a new message should be delivered to a local actor.
 ActorManagerName managerGetName()
          Returns the name of this actor manager.
 void managerInitialize(Scheduler S, RequestHandler R)
          Initialize a new actor manager.
 java.lang.Object managerInvokeService(ServiceName serviceName, java.lang.String meth, java.lang.Object[] serviceArgs)
          Called by other foundry modules (or remote managers) to invoke a local service.
 void managerMigrate(ActorMigrationStructure mig)
          This method is called to pass an actor migration request.
 void managerRegisterService(ServiceName sName, Service S)
          Called externally to register a new node service.
 void managerRemoveService(ServiceName sName)
          Called externally to remove a node service.
 
Methods inherited from class osl.manager.ActorManager
implGetName, implInitialize, implPostMigrateRebuild, implStamp
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

AM_VERSION

public java.lang.String AM_VERSION
Version information for this actor manager implementation.

numServiceThreads

public static final int numServiceThreads
The initial number of "service" threads to create in the manager. A service thread is used to hand-off a local actor request which is to be serviced on-node. This is done because local calls are usually filtered directly into the code of the target actor (which could therefore block indefinitely with all the usual problems).

SERVICE_TIMEOUT

public static final long SERVICE_TIMEOUT
The length of time that a service thread should wait before killing itself off (currently 5 minutes). If a service thread is not used again within this timeout period, then after its next use it will not add itself back to the service queue. This is done as a simple way to cull the service queue when not much is happening in a node. The queue will automatically build itself back up during periods of increased activity.

actorScheduler

protected Scheduler actorScheduler
The scheduler for this actor manager. The scheduler is in charge of scheduling all the threads associated with an actor manager.

ourHandler

protected RequestHandler ourHandler
The request handler implementation to use for creating request sessions for this manager. The basic implementation only creates one session for interacting with remote entities.

session

protected RequestSession session
The session used by this actor manager to interact with remote managers.

defaultActorName

protected ActorName defaultActorName
The default actor name which is reserved for special use by this manager. Typically, a manager uses this name in order to invoke functions which require an originator (e.g. actorCreate). Classes which extend ActorManager should be aware of this use of the name and code around it appropriately. This name is assigned during the initialization of the actor manager.

managed_actors

protected java.util.Hashtable managed_actors
This field hashes ActorNames to the ActorImpl instances they are associated with. In actuality, managed actors are stored using the ActorEntry inner class. Note that we can't necessarily assume that local actors are instances of BasicActorImpl.

remoteCreates

protected java.util.Hashtable remoteCreates
This hashtable temporarily holds messages for actors which are being created remotely (that is, it hashes ActorNames to Vectors). Once we have learned that a remote creation has completed, we forward the set of waiting messages to the manager which actually manages the actor.

localServices

protected java.util.Hashtable localServices
This hashtable maintains the current set of registered services available to local actors.

managerName

protected ActorManagerName managerName
The name of this actor manager. This name is created during initialization after the RequestSession for this actor has been instantiated.

requestMap

protected java.util.Hashtable requestMap
This table hashes RequestID's to the requests associated with the ID. During requestHandler exception handling, we use this information to figure out which request caused the exception and therefore which actor should receive the exception message. An independent thread periodically sweeps this table clean of any expired request IDs.

serviceQueue

protected Queue serviceQueue
The queue of waiting "service" threads. When a service needs to be handled asynchronously, the first thread on this queue is grabbed and assigned the task. If the queue is empty then the caller spawns a new "service" thread and assigns it the task. The new service thread is automatically added to the queue once it has completed its task.
Constructor Detail

BasicActorManager

public BasicActorManager()
The default constructor. Initialize all fields that can be initialized before the managerInitialize function is called.
Method Detail

implDeliver

protected void implDeliver(ActorImpl actor,
                           ActorMsgRequest msg)
This method simply calls ActorManager.implDeliver. We provide a duplicate method to do this in order to get around an apparent bug in the JDK's compiler: inner classes can't seem to find the inherited method for some reason.

Parameters:
actor - The ActorImpl to deliver the message to.
msg - The ActorMsgRequest to deliver.
Overrides:
implDeliver in class ActorManager

managerInitialize

public void managerInitialize(Scheduler S,
                              RequestHandler R)
                       throws RequestException
Initialize a new actor manager. This method should be called before the actor manager is used to manage a collection of actors.

Parameters:
S - The Scheduler instance which should be used to schedule all threads required by the manager. Most of these threads will correspond to actors. Thus, it is advantageous to use a scheduler customized to efficiently handle actors.
R - The RequestHandler instance which should be used for interactions between this manager and other managers in the system.
Throws:
RequestException - Thrown if an error is encountered while opening a new RequestHandler session.
Overrides:
managerInitialize in class ActorManager

actorCreate

protected ActorName actorCreate(ActorImpl caller,
                                ActorCreateRequest request)
                         throws java.lang.SecurityException,
                                RemoteCodeException
This method is called by a local actor to request the creation of a new actor. The type of the new actor, the node it should be created on, as well as the arguments that should be passed to its constructor are encapsulated in the request structure. The name of the new actor is returned as the result of this call. Semantically speaking, once this method completes, the returned name is henceforth a valid target for receiving messages. As a side-effect, the ID field of the request argument is assigned a value unique relative to all other local requests. This value may be used to disambiguate any asynchronous exceptions caused by this request.

If an exception is thrown by this method (asynchronously or otherwise) then the returned actor name is no longer valid and any messages sent to it will be discarded. The following asynchronous exceptions may be thrown:

Parameters:
request - The ActorCreateRequest structure which describes the new actor to be created.
Returns:
The ActorName of the newly created actor.
Throws:
java.lang.SecurityException - Thrown if the class of the new requested actor is not a subclass of Actor, or if the class of the new requested actor implementation is not a subclass of ActorImpl.
RemoteCodeException - Thrown for any other error encountered while attempting to perform the create. Note that this error may also be thrown asynchronously (e.g. when performing a remote create).
Overrides:
actorCreate in class ActorManager

actorSend

protected void actorSend(ActorImpl caller,
                         ActorMsgRequest message)
                  throws RemoteCodeException
This method is called by a local actor to send a message to another actor. The sender and receiver of the message, as well as the method to invoke and any arguments to pass are encapsulated in the message structure. Note that all messages are sent asynchronously so that method completion does not indicate message delivery. As a side-effect, the ID field of the message argument is assigned a value unique relative to all other local requests. This value may be used to disambiguate any asynchronous exceptions caused by this request.

If an exception is returned by this method then the message structure is never sent. For asynchronous exceptions, only the RemoteCodeException corresponds to a message structure which should be viewed as "delivered". All other asynchronous exceptions should be interpreted as indicating that the original message structure was never sent. The following asynchronous exceptions may be thrown:

Parameters:
message - The ActorMsg structure which indicates the sender and receiver of the message, the method to invoke on the receiver, and any arguments to pass to the target method.
Throws:
IllegalTargetException - Thrown if the target of the send is null or does not correspond to a legal actor name.
RemoteCodeException - Thrown for any other error encountered while attempting to perform the send. This usually indicates a local error in the manager implementation rather than an error encountered at the target of the message.
Overrides:
actorSend in class ActorManager

actorFatalError

protected void actorFatalError(ActorImpl caller,
                               java.lang.Exception e)
This method is called by an actor implementation to report that it has encountered a fatal error. The caller should pass an a reference to itself in order to be safely terminated by the manager. For the basic actor manager, the behavior is to report the error on the managers log file and kill the actor (thus removing it from the system).
Parameters:
thrower - The ActorImpl signalling the fatal error. Usually, this actor will be removed from the system.
e - The Exception which describes the fatal error encountered in the actor.
Overrides:
actorFatalError in class ActorManager

actorMigrate

public void actorMigrate(ActorImpl caller,
                         ActorManagerName where)
                  throws IllegalNodeException,
                         RemoteRequestRefusedException,
                         RemoteCodeException
This method is called by a local actor that wishes to be migrated to another manager. The calling actor is migrated immediately, thus it is the responsibility of the underlying Actor implementation to ensure that the actor is in a consistent state before this method is called. Note that immediate migration will destroy the thread currently running in the actor. Once the migration is complete, the actor is restarted with a fresh thread. An exception returned by this method indicates that the actor was not migrated. In this case, control is returned immediately to the calling actor.

Parameters:
thrower - A reference to the ActorImpl which wishes to be migrated.
where - The ActorManagerName of the manager where this actor should be moved.
Throws:
IllegalNodeException - Thrown if the where argument does not correspond to a legal ActorManagerName.
RemoteRequestRefusedException - Thrown if the target manager of the migration refuses to accept the migrated actor.
RemoteCodeException - Thrown if the restart code after the migration throws an exception. The remote copy is destroyed in this case and the actor is treated as if it never migrated.
Overrides:
actorMigrate in class ActorManager

actorInvokeService

public java.lang.Object actorInvokeService(ActorImpl caller,
                                           ServiceName serviceName,
                                           java.lang.String meth,
                                           java.lang.Object[] serviceArgs)
                                    throws ServiceNotFoundException,
                                           ServiceException
This method is called by a local actor in order to access a locally provided node service. The name of the service must be specified together with any arguments required to correctly invoke the service. An arbitrary object is returned as a result of the service call. Note that Objects are used to specify both the service arguments as well as the return type so that very general services may be specified. It is up to the caller to correctly cast return values to their appropriate type.
Parameters:
serviceName - The ServiceName of the service to invoke.
serviceArgs - An Object which represents the sole argument to pass to the invocation function of the service.
Returns:
An Object representing the value returned by the service invocation.
Throws:
ServiceNotFoundException - Thrown if no instance of the named service can be found on this node.
ServiceException - Thrown if the service throws an exception while processing the request.
Overrides:
actorInvokeService in class ActorManager

managerCreate

public ActorName managerCreate(ActorCreateRequest request,
                               ActorName reqName)
                        throws RemoteRequestRefusedException,
                               RemoteCodeException,
                               IllegalTargetException,
                               java.lang.IllegalAccessException
This method is called to request that a new local actor be created and managed by the target actor. Both the ID properties and the site field of the request are ignored and the actor is always created locally. Unlike actorCreate, the caller may optionally specify the name of the new actor. This is done to allow more efficient implementations of remote creation where a name is immediately returned to a local actor although the creation itself is taking place asynchronously at a remote manager. Normally this method is called using the RPC features of the request handler. This is done so that the name of the new actor may be returned and so that the caller may determine when it is legal to send the new actor messages. However, this method MAY be called asynchronously (e.g. if the caller already knows the name of the new actor because the newName field has been specified) in which case other means will need to be used to determine when it is legal to send the actor messages.
Parameters:
request - An ActorCreateRequest structure describing the new actor to be created. The ID and site fields are ignored and the new actor is always created locally.
newName - An optional argument indicating the desired ActorName of the new actor. If null then a new actor name is generated, otherwise an attempt is made to use the provided name.
Returns:
The ActorName of the newly created actor. This actor is a legal target for messages once the caller has received its name.
Throws:
RemoteRequestRefusedException - Thrown if this manager decides to refuse the creation request.
RemoteCodeException - Thrown as a wrapper for any general exception which occurs while attempting to create the new actor.
IllegalTargetException - Thrown if the specified value for newName is non-NULL but does not correspond to a legal actor name.
java.lang.IllegalAccessException - Thrown if the requested class of the new actor does not inherit from Actor.

managerDeliver

public void managerDeliver(ActorMsgRequest del)
                    throws IllegalTargetException,
                           RemoteRequestRefusedException,
                           RemoteCodeException
This method is called to indicate that a new message should be delivered to a local actor. This method is normally called asynchronously using the exception handling mechanism of the request layer. Because messages are processed by actors asynchronously, a separate method is used to return exceptions resulting from actor message processing.

Parameters:
del - The ActorMsg structure to deliver to a local actor.
Throws:
IllegalTargetException - Thrown if either the specified target actor name is malformed, or the target is not managed locally.
RemoteRequestRefusedException - Thrown if the local manager decides to refuse the remote request.
RemoteCodeException - Thrown as a wrapper for any other exception encountered while attempting to deliver the message.

managerMigrate

public void managerMigrate(ActorMigrationStructure mig)
                    throws RemoteRequestRefusedException,
                           RemoteCodeException
This method is called to pass an actor migration request. An actor migration structure contains all the information necessary to reassemble an actor on the local manager including the serialized form of the actor and the actor's name. Normally, this method is called using RPC. Upon successful completion (i.e. no thrown exceptions), the caller may assume that the migrated actor is now running on the local manager. Otherwise, the migration request was not satisfied and the caller should assume that the actor did not migrate.
Parameters:
mig - The ActorMigrationStructure giving the properties of the actor to migrate.
Throws:
RemoteRequestRefusedException - Thrown if the local manager decides to refuse the migration request.
RemoteCodeException - Thrown if an error is encountered while attempting to restart the migrated actor on the local manager.

managerRegisterService

public void managerRegisterService(ServiceName sName,
                                   Service S)
Called externally to register a new node service. The service provider is responsible for providing a unique service name. Any existing service with the same name is removed.
Parameters:
sName - The ServiceName of the new service.
S - A reference to the new Service.

managerRemoveService

public void managerRemoveService(ServiceName sName)
                          throws ServiceNotFoundException
Called externally to remove a node service. An exception is thrown if the named service does not exist.
Parameters:
sName - The name of the service to remove.
Throws:
ServiceNotFoundException - Thrown if no service with the given name is associated with this manager.

managerInvokeService

public java.lang.Object managerInvokeService(ServiceName serviceName,
                                             java.lang.String meth,
                                             java.lang.Object[] serviceArgs)
                                      throws ServiceNotFoundException,
                                             ServiceException
Called by other foundry modules (or remote managers) to invoke a local service. This equivalent to the actorInvokeService method except that no check is made to ensure that the caller is an actor.
Parameters:
serviceName - The ServiceName of the service to invoke.
serviceArgs - An Object which represents the sole argument to pass to the invocation function of the service.
Returns:
An Object representing the value returned by the service invocation.
Throws:
ServiceNotFoundException - Thrown if no instance of the named service can be found on this node.
ServiceException - Thrown if the service throws an exception while processing the request.

managerGetName

public ActorManagerName managerGetName()
Returns the name of this actor manager.

handlerException

public void handlerException(RequestSession session,
                             java.lang.Exception except,
                             RequestID id)
Called when an exception has been received for an asynchronous request sent on a particular session.
Parameters:
session - The RequestSession that the original asynchronous call originated from. This field is provided so that clients with multiple handler sessions may disambiguate the origin of exceptions.
except - The Exception which was returned from the remote handler. This will either be a NoSuchMethodException which indicates that no matching method could be found on the target (and thus the method was never invoked); or a RemoteException which encapsulates an exception thrown by the remote method itself (however, the remote method WAS invoked).
id - The RequestID of the original request which caused the exception. This information is used to disambiguate multiple asynchronous exceptions.

actorCreateAlias

public ActorName actorCreateAlias(ActorImpl caller)
Create an alias for an actor. A new ActorName is created and linked to the caller actor implementation. Henceforth, this name may be used as a target for messages to the calling implementation.

N.B.: This will only work for non-migrating actors. That's not to say that an aliased actor can't be migrated, but strange things will happen if that DOES occur. Have to formalize this at some later date!!!!

Returns:
An ActorName which may be used as an alias for the calling actor.
Throws:
java.lang.SecurityException - Thrown if the calling thread is not an instance of ActorImpl, or if the calling thread is not currently managed by this actor manager.