com.sun.sgs.impl.service.task
Class TaskServiceImpl

java.lang.Object
  extended by com.sun.sgs.impl.util.AbstractService
      extended by com.sun.sgs.impl.service.task.TaskServiceImpl
All Implemented Interfaces:
TaskManager, NodeMappingListener, RecoveryListener, Service, TaskService

public class TaskServiceImpl
extends AbstractService
implements TaskService, NodeMappingListener, RecoveryListener

This is an implementation of TaskService that works on a single node and across multiple nodes. It handles persisting tasks and keeping track of which tasks have not yet run to completion, so that in the event of a system failure the tasks can be run on re-start.

Durable tasks that have not yet run are persisted as instances of PendingTask, indexed by the owning identity. When a given identity is mapped to the local node, all tasks associated with that identity are started running on the local node. As long as an identity still has pending tasks scheduled to run locally, that identity is marked as active. To help minimize object creation, a cache of PendingTasks is created for each identity.

When an identity is moved from the local node to a new node, then all recurring tasks for that identity are cancelled, and all tasks for that identity are re-scheduled on the identity's new node. When an already-scheduled, persisted task tries to run on the old node, that task is dropped since it is already scheduled to run on the new node. After an identity has been moved, any subsequent attempts to schedule durable tasks on behalf of that identity on the old node will result in the tasks being scheduled to run on the new node. This is called task handoff.

Task handoff between nodes is done by noting the task in a node-specific entry in the data store. Each node will periodically query this entry to see if any tasks have been handed off. The time in milliseconds for this period is configurable via the "com.sun.sgs.impl.service.task.TaskServiceImpl.handoff.period" property described below. This checking will be delayed on node startup to give the system a chance to finish initializing. The time in milliseconds for this delay is configurable via the "com.sun.sgs.impl.service.task.TaskServiceImpl.handoff.start" property.

When the final task for an identity completes, or an initial task for an identity is scheduled, the status of that identity as reported by this service changes. Rather than immediately reporting this status change, however, a delay is taken to see if the status is about to change back to its previous state. This helps avoid voting too frequently. The time in milliseconds for delaying this vote is configurable via the "com.sun.sgs.impl.service.task.TaskServiceImpl.vote.delay" property.

The TaskServiceImpl supports the following configuration properties, some of which have already been mentioned above:

Property: "com.sun.sgs.impl.service.task.TaskServiceImpl.handoff.period"
Default: 500L
Specifies the periodic time in milliseconds that the TaskServiceImpl will regularly query its handoff queue for tasks that have been handed off by other nodes.

Property: "com.sun.sgs.impl.service.task.TaskServiceImpl.handoff.start"
Default: 2500L
Specifies the time in milliseconds that the TaskServiceImpl will wait at startup before querying its handoff queue for the first time.

Property: "com.sun.sgs.impl.service.task.TaskServiceImpl.vote.delay"
Default: 5000L
Specifies the time in milliseconds to wait before reporting a status change for an identity. The status change is not reported if the identity's status changes back to its original state during this delay period.

Property: "com.sun.sgs.impl.service.task.TaskServiceImpl.continue.policy"
Default: "com.sun.sgs.impl.service.task.FixedTimeContinuePolicy"
Specifies the fully qualified class name of the class which will be used as the ContinuePolicy for the task service. The given class should be a non-abstract class that implements the ContinuePolicy interface, and that provides a constructor with the parameters (Properties, ComponentRegistry, TransactionProxy)


Nested Class Summary
 
Nested classes/interfaces inherited from class com.sun.sgs.impl.util.AbstractService
AbstractService.State, AbstractService.Version
 
Field Summary
static String CONTINUE_POLICY_DEFAULT
          The default continue policy.
static String CONTINUE_POLICY_PROPERTY
          The property key to specify which class to use as the continue policy.
static String DS_PREFIX
          The name prefix used to bind all service-level objects associated with this service.
static long HANDOFF_PERIOD_DEFAULT
          The default length of time in milliseconds to wait between hand-off checks.
static String HANDOFF_PERIOD_PROPERTY
          The property key to set how long to wait between hand-off checks.
static long HANDOFF_START_DEFAULT
          The default delay in milliseconds before hand-off checking starts.
static String HANDOFF_START_PROPERTY
          The property key to set the delay before hand-off checking starts.
static String NAME
          The identifier used for this Service.
(package private) static long NEVER
           
(package private) static long PERIOD_NONE
           
(package private) static long START_NOW
           
static long VOTE_DELAY_DEFAULT
          The default delay in milliseconds for status votes.
static String VOTE_DELAY_PROPERTY
          The property key to set the delay in milliseconds for status votes.
 
Fields inherited from class com.sun.sgs.impl.util.AbstractService
appName, dataService, IO_TASK_PROPERTY_PREFIX, IO_TASK_RETRIES_PROPERTY, IO_TASK_WAIT_TIME_PROPERTY, maxIoAttempts, retryWaitTime, taskOwner, taskScheduler, transactionScheduler, txnProxy
 
Constructor Summary
TaskServiceImpl(Properties properties, ComponentRegistry systemRegistry, TransactionProxy transactionProxy)
          Creates an instance of TaskServiceImpl.
 
Method Summary
 void doReady()
          Performs ready operations.
 void doShutdown()
          Performs shutdown operations.
(package private)  PendingTask fetchPendingTask(BigInteger objId)
          Private helper that fetches the task associated with the given ID.
 String getName()
          Returns the name used to identify this service.
protected  void handleServiceVersionMismatch(AbstractService.Version oldVersion, AbstractService.Version currentVersion)
          Handles conversion from the oldVersion to the currentVersion.
 void mappingAdded(Identity id, Node oldNode)
          Notifies this listener that an identity has been added to this node.
 void mappingRemoved(Identity id, Node newNode)
          Notifies this listener that an identity has been removed from this node.
 void recover(Node node, SimpleCompletionHandler handler)
          Notifies this listener that the specified node has failed and that this listener needs to orchestrate recovery.
 void scheduleNonDurableTask(KernelRunnable task, boolean transactional)
          Schedules a single task to run once the current task has finished.
 void scheduleNonDurableTask(KernelRunnable task, long delay, boolean transactional)
          Schedules a single task to run, after the given delay, once the current task has finished.
 PeriodicTaskHandle schedulePeriodicTask(Task task, long delay, long period)
          Schedules a task to run periodically after a delay.
 void scheduleTask(Task task)
          Schedules a task to run now.
 void scheduleTask(Task task, long delay)
          Schedules a task to run after a delay.
 boolean shouldContinue()
          Returns true if the currently running task should do more work if it is available.
 
Methods inherited from class com.sun.sgs.impl.util.AbstractService
callFinished, callStarted, checkNonTransactionalContext, checkServiceVersion, createTaskQueue, getDataService, getState, isAlive, isInInitializedState, isRetryableException, ready, runIoTask, shutdown, shuttingDown
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.sun.sgs.service.Service
ready, shutdown
 

Field Detail

NAME

public static final String NAME
The identifier used for this Service.

See Also:
Constant Field Values

DS_PREFIX

public static final String DS_PREFIX
The name prefix used to bind all service-level objects associated with this service.

See Also:
Constant Field Values

VOTE_DELAY_PROPERTY

public static final String VOTE_DELAY_PROPERTY
The property key to set the delay in milliseconds for status votes.

See Also:
Constant Field Values

VOTE_DELAY_DEFAULT

public static final long VOTE_DELAY_DEFAULT
The default delay in milliseconds for status votes.

See Also:
Constant Field Values

HANDOFF_START_PROPERTY

public static final String HANDOFF_START_PROPERTY
The property key to set the delay before hand-off checking starts.

See Also:
Constant Field Values

HANDOFF_START_DEFAULT

public static final long HANDOFF_START_DEFAULT
The default delay in milliseconds before hand-off checking starts.

See Also:
Constant Field Values

HANDOFF_PERIOD_PROPERTY

public static final String HANDOFF_PERIOD_PROPERTY
The property key to set how long to wait between hand-off checks.

See Also:
Constant Field Values

HANDOFF_PERIOD_DEFAULT

public static final long HANDOFF_PERIOD_DEFAULT
The default length of time in milliseconds to wait between hand-off checks.

See Also:
Constant Field Values

CONTINUE_POLICY_PROPERTY

public static final String CONTINUE_POLICY_PROPERTY
The property key to specify which class to use as the continue policy.

See Also:
Constant Field Values

CONTINUE_POLICY_DEFAULT

public static final String CONTINUE_POLICY_DEFAULT
The default continue policy.

See Also:
Constant Field Values

START_NOW

static final long START_NOW
See Also:
Constant Field Values

PERIOD_NONE

static final long PERIOD_NONE
See Also:
Constant Field Values

NEVER

static final long NEVER
See Also:
Constant Field Values
Constructor Detail

TaskServiceImpl

public TaskServiceImpl(Properties properties,
                       ComponentRegistry systemRegistry,
                       TransactionProxy transactionProxy)
                throws Exception
Creates an instance of TaskServiceImpl. See the class javadoc for applicable properties.

Parameters:
properties - application properties
systemRegistry - the registry of system components
transactionProxy - the system's TransactionProxy
Throws:
Exception - if the service cannot be created
Method Detail

getName

public String getName()
Returns the name used to identify this service.

Specified by:
getName in interface Service
Overrides:
getName in class AbstractService
Returns:
the service's name

handleServiceVersionMismatch

protected void handleServiceVersionMismatch(AbstractService.Version oldVersion,
                                            AbstractService.Version currentVersion)
Handles conversion from the oldVersion to the currentVersion. This method is invoked by checkServiceVersion if a version mismatch is detected and is invoked from within a transaction.

Specified by:
handleServiceVersionMismatch in class AbstractService
Parameters:
oldVersion - the old version
currentVersion - the current version

doReady

public void doReady()
Performs ready operations. This method is invoked by the ready method only once so that the subclass can perform any operations necessary during the "ready" phase.

Specified by:
doReady in class AbstractService

doShutdown

public void doShutdown()
Performs shutdown operations. This method is invoked by the shutdown method only once so that the subclass can perform any operations necessary to shutdown the service.

Specified by:
doShutdown in class AbstractService

recover

public void recover(Node node,
                    SimpleCompletionHandler handler)
Notifies this listener that the specified node has failed and that this listener needs to orchestrate recovery. This method is invoked outside of a transaction.

When recovery for this listener for the specified node is complete, the completed method of the specified handler must be invoked.

Recovery does not need to be performed in this method, but may be performed asynchronously.

The implementation of this method should be idempotent because it may be invoked multiple times. If it is invoked multiple times, the completed method must be called for each handler provided.

Specified by:
recover in interface RecoveryListener
Parameters:
node - a failed node to recover
handler - a handler to notify when recovery is complete

scheduleTask

public void scheduleTask(Task task)
Schedules a task to run now. The TaskManager will call the task's run method as soon as possible after the completion of the task in which this method is called, according to its scheduling algorithm.

If the call to the run method throws an exception, that exception implements ExceptionRetryStatus, and its shouldRetry method returns true, then the TaskManager will make further attempts to run the task. It will continue those attempts until either an attempt succeeds or it notices an exception is thrown that is not retryable. The TaskManager is permitted to treat a non-retryable exception as a hint. In particular, a task that throws a non-retryable exception may be retried if the node running the task crashes.

Specified by:
scheduleTask in interface TaskManager
Parameters:
task - the task to run

scheduleTask

public void scheduleTask(Task task,
                         long delay)
Schedules a task to run after a delay. The TaskManager will wait for the specified number of milliseconds, and then call the task's run method as soon as possible after the completion of the task in which this method is called, according to its scheduling algorithm.

If the call to the run method throws an exception, that exception implements ExceptionRetryStatus, and its shouldRetry method returns true, then the TaskManager will make further attempts to run the task. It will continue those attempts until either an attempt succeeds or it notices an exception is thrown that is not retryable. The TaskManager is permitted to treat a non-retryable exception as a hint. In particular, a task that throws a non-retryable exception may be retried if the node running the task crashes.

Specified by:
scheduleTask in interface TaskManager
Parameters:
task - the task to run
delay - the number of milliseconds to delay before running the task

schedulePeriodicTask

public PeriodicTaskHandle schedulePeriodicTask(Task task,
                                               long delay,
                                               long period)
Schedules a task to run periodically after a delay. The TaskManager will wait for the specified number of milliseconds, and then call the task's run method as soon as possible after the completion of the task in which this method is called, according to its scheduling algorithm. It will also arrange to run the task periodically at the specified interval following the delay until the PeriodicTaskHandle.cancel method is called on the associated handle. At the start of each period, which occurs period milliseconds after the scheduled start of the previous period, a new task will be scheduled to run. The TaskManager will make a best effort to run a new task in each period, but even if the task cannot be run in one period, a new task will always be scheduled for the following period. The TaskManager will wait until the current attempt to run the task has ended before making another attempt to run it, regardless of whether the attempts are for the same or different periods.

If the call to the run method throws an exception, that exception implements ExceptionRetryStatus, and its shouldRetry method returns true, then the TaskManager will make further attempts to run the task. It will continue those attempts until either an attempt succeeds or it notices an exception is thrown that is not retryable. Note that calls to PeriodicTaskHandle.cancel have no effect on attempts to retry a task after the first attempt. The TaskManager is permitted to treat a non-retryable exception as a hint. In particular, a task that throws a non-retryable exception may be retried if the node running the task crashes.

Specified by:
schedulePeriodicTask in interface TaskManager
Parameters:
task - the task to run
delay - the number of milliseconds to delay before running the task
period - the number of milliseconds that should elapse between the starts of periodic attempts to run the task
Returns:
a handle for managing the scheduling of the task

shouldContinue

public boolean shouldContinue()
Returns true if the currently running task should do more work if it is available. Otherwise, returns false. This method should always return true until the current task has done enough work such that the work required to reschedule the task is negligible in comparison to the work already done.

Specified by:
shouldContinue in interface TaskManager
Returns:
true if the currently running task should do more work if possible; otherwise false

scheduleNonDurableTask

public void scheduleNonDurableTask(KernelRunnable task,
                                   boolean transactional)
Schedules a single task to run once the current task has finished. The task will not be persisted by the TaskService, and therefore is not guaranteed to run.

Specified by:
scheduleNonDurableTask in interface TaskService
Parameters:
task - the KernelTask to run
transactional - true if the given task should be run in a transaction, false otherwise

scheduleNonDurableTask

public void scheduleNonDurableTask(KernelRunnable task,
                                   long delay,
                                   boolean transactional)
Schedules a single task to run, after the given delay, once the current task has finished. The task will not be persisted by the TaskService, and therefore is not guaranteed to run. As described in TaskManager, the delay is from the time of this call, not from the time that the transaction commits.

Specified by:
scheduleNonDurableTask in interface TaskService
Parameters:
task - the KernelTask to run
delay - the number of milliseconds to delay before running the task
transactional - true if the given task should be run in a transaction, false otherwise

fetchPendingTask

PendingTask fetchPendingTask(BigInteger objId)
Private helper that fetches the task associated with the given ID. If this is a non-periodic task, then the task is also removed from the managed map of pending tasks. This method is typically used when a task actually runs. If the Task was managed by the application and has been removed by the application, or another TaskService task has already removed the pending task entry, then this method returns null meaning that there is no task to run.


mappingAdded

public void mappingAdded(Identity id,
                         Node oldNode)
Notifies this listener that an identity has been added to this node.

Specified by:
mappingAdded in interface NodeMappingListener
Parameters:
id - the added identity
oldNode - the last node the identity was assigned to, or null if this is the identity's first assignment

mappingRemoved

public void mappingRemoved(Identity id,
                           Node newNode)
Notifies this listener that an identity has been removed from this node.

Specified by:
mappingRemoved in interface NodeMappingListener
Parameters:
id - the removed identity
newNode - the new node assignment for the identity, or null if the identity has been removed from the system

RedDwarf, Version 0.10.1
2010-03-14 10:56:12

Copyright © 2010 The RedDwarf Authors. All rights reserved
Copyright © 2007-2010 Sun Microsystems, Inc. All rights reserved