V
- The computed value of the ScheduledServicepublic abstract class ScheduledService<V> extends Service<V>
The ScheduledService is a Service
which will automatically restart
itself after a successful execution, and under some conditions will
restart even in case of failure. A new ScheduledService begins in
the READY state, just as a normal Service. After calling
start
or restart
, the ScheduledService will
enter the SCHEDULED state for the duration specified by delay
.
Once RUNNING, the ScheduledService will execute its Task. On successful
completion, the ScheduledService will transition to the SUCCEEDED state,
and then to the READY state and back to the SCHEDULED state. The amount
of time the ScheduledService will remain in this state depends on the
amount of time between the last state transition to RUNNING, and the
current time, and the period
. In short, the period
defines the minimum amount of time from the start of one run and the start of
the next. If the previous execution completed before period
expires,
then the ScheduledService will remain in the SCHEDULED state until the period
expires. If on the other hand the execution took longer than the
specified period, then the ScheduledService will immediately transition
back to RUNNING.
If, while RUNNING, the ScheduledService's Task throws an error or in
some other way ends up transitioning to FAILED, then the ScheduledService
will either restart or quit, depending on the values for
backoffStrategy
, restartOnFailure
, and
maximumFailureCount
.
If a failure occurs and restartOnFailure
is false, then
the ScheduledService will transition to FAILED and will stop. To restart
a failed ScheduledService, you must call restart manually.
If a failure occurs and restartOnFailure
is true, then
the the ScheduledService may restart automatically. First,
the result of calling backoffStrategy
will become the
new cumulativePeriod
. In this way, after each failure, you can cause
the service to wait a longer and longer period of time before restarting.
Once the task completes successfully, the cumulativePeriod is reset to
the value of period
.
ScheduledService defines static EXPONENTIAL_BACKOFF_STRATEGY and LOGARITHMIC_BACKOFF_STRATEGY
implementations, of which LOGARITHMIC_BACKOFF_STRATEGY is the default value for
backoffStrategy. After maximumFailureCount
is reached, the
ScheduledService will transition to FAILED in exactly the same way as if
restartOnFailure
were false.
If the period
or delay
is changed while the
ScheduledService is running, the new values will be taken into account on the
next iteration. For example, if the period
is increased, then the next time the
ScheduledService enters the SCHEDULED state, the new period
will be used.
Likewise, if the delay
is changed, the new value will be honored on
the next restart or reset/start.
ScheduledService<Document> svc = new ScheduledService<Document>() {
protected Task<Document> createTask() {
return new Task<Document>() {
protected Document call() {
// Connect to a Server
// Get the XML document
// Parse it into a document
return document;
}
};
}
};
svc.setPeriod(Duration.seconds(1));
This example will ping the remote server every 1 second.
Timing for this class is not absolutely reliable. A very busy event thread might introduce some timing lag into the beginning of the execution of the background Task, so very small values for the period or delay are likely to be inaccurate. A delay or period in the hundreds of milliseconds or larger should be fairly reliable.
The ScheduledService in its default configuration has a default period
of 0 and a
default delay
of 0. This will cause the ScheduledService to execute the task immediately
upon Service.start()
, and re-executing immediately upon successful completion.
For this purposes of this class, any Duration that answers true to Duration.isUnknown()
will treat that duration as if it were Duration.ZERO. Likewise, any Duration which answers true
to Duration.isIndefinite()
will be treated as if it were a duration of Double.MAX_VALUE
milliseconds. Any null Duration is treated as Duration.ZERO. Any custom implementation of an backoff strategy
callback must be prepared to handle these different potential values.
The ScheduledService introduces a new property called lastValue
. The lastValue is the value that
was last successfully computed. Because a Service clears its value
property on each run, and
because the ScheduledService will reschedule a run immediately after completion (unless it enters the
cancelled or failed states), the value property is not overly useful on a ScheduledService. In most cases
you will want to instead use the value returned by lastValue.
Service.ready()
, Service.scheduled()
, Service.running()
, succeeded()
,
Service.cancelled()
, and failed()
methods are implemented in this class. Subclasses which also
override these methods must take care to invoke the super implementation.Worker.State
Modifier and Type | Field and Description |
---|---|
private ObjectProperty<Callback<ScheduledService<?>,Duration>> |
backoffStrategy
Computes the amount of time to add to the period on each failure.
|
private ReadOnlyObjectWrapper<Duration> |
cumulativePeriod
The current cumulative period in use between iterations.
|
private ReadOnlyIntegerWrapper |
currentFailureCount
The current number of times the ScheduledService has failed.
|
private ObjectProperty<Duration> |
delay
The initial delay between when the ScheduledService is first started, and when it will begin
operation.
|
private static java.util.Timer |
DELAY_TIMER
This Timer is used to schedule the delays for each ScheduledService.
|
private java.util.TimerTask |
delayTask
This is a TimerTask scheduled with the DELAY_TIMER.
|
static Callback<ScheduledService<?>,Duration> |
EXPONENTIAL_BACKOFF_STRATEGY
A Callback implementation for the
backoffStrategy property which
will exponentially backoff the period between re-executions in the case of
a failure. |
private boolean |
freshStart
Whether or not this iteration is a "fresh start", such as the initial call to start,
or a call to restart, or a call to reset followed by a call to start.
|
private long |
lastRunTime
The timestamp of the last time the task was run.
|
private ReadOnlyObjectWrapper<V> |
lastValue
The last successfully computed value.
|
static Callback<ScheduledService<?>,Duration> |
LINEAR_BACKOFF_STRATEGY
A Callback implementation for the
backoffStrategy property which
will linearly backoff the period between re-executions in the case of
a failure. |
static Callback<ScheduledService<?>,Duration> |
LOGARITHMIC_BACKOFF_STRATEGY
A Callback implementation for the
backoffStrategy property which
will logarithmically backoff the period between re-executions in the case of
a failure. |
private ObjectProperty<Duration> |
maximumCumulativePeriod
The maximum allowed value for the cumulativePeriod.
|
private IntegerProperty |
maximumFailureCount
The maximum number of times the ScheduledService can fail before it simply ends in the FAILED
state.
|
private ObjectProperty<Duration> |
period
The minimum amount of time to allow between the start of the last run and the start of the next run.
|
private BooleanProperty |
restartOnFailure
Indicates whether the ScheduledService should automatically restart in the case of a failure in the Task.
|
private boolean |
stop
This is set to false when the "cancel" method is called, and reset to true on "reset".
|
Constructor and Description |
---|
ScheduledService() |
Modifier and Type | Method and Description |
---|---|
ObjectProperty<Callback<ScheduledService<?>,Duration>> |
backoffStrategyProperty() |
boolean |
cancel()
Cancels any currently running task and stops this scheduled service, such that
no additional iterations will occur.
|
(package private) long |
clock()
Gets the time of the current clock.
|
private java.util.TimerTask |
createTimerTask(Task<V> task)
Creates the TimerTask used for delaying execution.
|
ReadOnlyObjectProperty<Duration> |
cumulativePeriodProperty() |
ReadOnlyIntegerProperty |
currentFailureCountProperty() |
ObjectProperty<Duration> |
delayProperty() |
protected void |
executeTask(Task<V> task)
Uses the
executor defined on this Service to execute the
given task. |
private void |
executeTaskNow(Task<V> task)
Called when it is time to actually execute the task (any delay has by now been
accounted for).
|
protected void |
failed()
A protected convenience method for subclasses, called whenever the
state of the Service has transitioned to the FAILED state.
|
Callback<ScheduledService<?>,Duration> |
getBackoffStrategy() |
Duration |
getCumulativePeriod() |
int |
getCurrentFailureCount() |
Duration |
getDelay() |
V |
getLastValue() |
Duration |
getMaximumCumulativePeriod() |
int |
getMaximumFailureCount() |
Duration |
getPeriod() |
boolean |
getRestartOnFailure() |
(package private) boolean |
isFreshStart()
This method only exists for the sake of testing.
|
ReadOnlyObjectProperty<V> |
lastValueProperty() |
ObjectProperty<Duration> |
maximumCumulativePeriodProperty() |
IntegerProperty |
maximumFailureCountProperty() |
private static double |
normalize(Duration d)
Normalize our handling of Durations according to the class documentation.
|
ObjectProperty<Duration> |
periodProperty() |
void |
reset()
Resets the Service.
|
BooleanProperty |
restartOnFailureProperty() |
(package private) void |
schedule(java.util.TimerTask task,
long delay)
This method exists only for testing purposes.
|
void |
setBackoffStrategy(Callback<ScheduledService<?>,Duration> value) |
(package private) void |
setCumulativePeriod(Duration value) |
private void |
setCurrentFailureCount(int value) |
void |
setDelay(Duration value) |
void |
setMaximumCumulativePeriod(Duration value) |
void |
setMaximumFailureCount(int value) |
void |
setPeriod(Duration value) |
void |
setRestartOnFailure(boolean value) |
protected void |
succeeded()
A protected convenience method for subclasses, called whenever the
state of the Service has transitioned to the SUCCEEDED state.
|
private void |
superReset()
Called by this class when we need to avoid calling this class' implementation of
reset which has the side effect of resetting the "freshStart", currentFailureCount,
and other state.
|
addEventFilter, addEventHandler, buildEventDispatchChain, cancelFromReadyState, cancelled, checkThread, createTask, exceptionProperty, executorProperty, fireEvent, getException, getExecutor, getMessage, getOnCancelled, getOnFailed, getOnReady, getOnRunning, getOnScheduled, getOnSucceeded, getProgress, getState, getTitle, getTotalWork, getValue, getWorkDone, isFxApplicationThread, isRunning, messageProperty, onCancelledProperty, onFailedProperty, onReadyProperty, onRunningProperty, onScheduledProperty, onSucceededProperty, progressProperty, ready, removeEventFilter, removeEventHandler, restart, runLater, running, runningProperty, scheduled, setEventHandler, setExecutor, setOnCancelled, setOnFailed, setOnReady, setOnRunning, setOnScheduled, setOnSucceeded, start, stateProperty, titleProperty, totalWorkProperty, valueProperty, workDoneProperty
public static final Callback<ScheduledService<?>,Duration> EXPONENTIAL_BACKOFF_STRATEGY
backoffStrategy
property which
will exponentially backoff the period between re-executions in the case of
a failure. This computation takes the original period and the number of
consecutive failures and computes the backoff amount from that information.
If the service
is null, then Duration.ZERO is returned. If the period is 0 then
the result of this method will simply be Math.exp(currentFailureCount)
. In all other cases,
the returned value is the same as {@code period + (period * Math.exp(currentFailureCount))).
public static final Callback<ScheduledService<?>,Duration> LOGARITHMIC_BACKOFF_STRATEGY
backoffStrategy
property which
will logarithmically backoff the period between re-executions in the case of
a failure. This computation takes the original period and the number of
consecutive failures and computes the backoff amount from that information.
If the service
is null, then Duration.ZERO is returned. If the period is 0 then
the result of this method will simply be Math.log1p(currentFailureCount)
. In all other cases,
the returned value is the same as {@code period + (period * Math.log1p(currentFailureCount))).
public static final Callback<ScheduledService<?>,Duration> LINEAR_BACKOFF_STRATEGY
backoffStrategy
property which
will linearly backoff the period between re-executions in the case of
a failure. This computation takes the original period and the number of
consecutive failures and computes the backoff amount from that information.
If the service
is null, then Duration.ZERO is returned. If the period is 0 then
the result of this method will simply be currentFailureCount
. In all other cases,
the returned value is the same as {@code period + (period * currentFailureCount).
private static final java.util.Timer DELAY_TIMER
private ObjectProperty<Duration> delay
Service.start()
or Service.restart()
.private ObjectProperty<Duration> period
cumulativePeriod
)
will depend on this property as well as the backoffStrategy
and number of failures.private ObjectProperty<Callback<ScheduledService<?>,Duration>> backoffStrategy
private BooleanProperty restartOnFailure
private IntegerProperty maximumFailureCount
private ReadOnlyIntegerWrapper currentFailureCount
private ReadOnlyObjectWrapper<Duration> cumulativePeriod
period
,
except after a failure, in which case the result of the backoffStrategy will be used as the cumulative period
following each failure. This is reset whenever the ScheduledService is manually restarted or an iteration
is successful. The cumulativePeriod is modified when the ScheduledService enters the scheduled state.
The cumulativePeriod can be capped by setting the maximumCumulativePeriod
.private ObjectProperty<Duration> maximumCumulativePeriod
private ReadOnlyObjectWrapper<V> lastValue
private long lastRunTime
private boolean freshStart
private java.util.TimerTask delayTask
private boolean stop
public final Duration getDelay()
public final void setDelay(Duration value)
public final ObjectProperty<Duration> delayProperty()
public final Duration getPeriod()
public final void setPeriod(Duration value)
public final ObjectProperty<Duration> periodProperty()
public final Callback<ScheduledService<?>,Duration> getBackoffStrategy()
public final void setBackoffStrategy(Callback<ScheduledService<?>,Duration> value)
public final ObjectProperty<Callback<ScheduledService<?>,Duration>> backoffStrategyProperty()
public final boolean getRestartOnFailure()
public final void setRestartOnFailure(boolean value)
public final BooleanProperty restartOnFailureProperty()
public final int getMaximumFailureCount()
public final void setMaximumFailureCount(int value)
public final IntegerProperty maximumFailureCountProperty()
public final int getCurrentFailureCount()
public final ReadOnlyIntegerProperty currentFailureCountProperty()
private void setCurrentFailureCount(int value)
public final Duration getCumulativePeriod()
public final ReadOnlyObjectProperty<Duration> cumulativePeriodProperty()
void setCumulativePeriod(Duration value)
public final Duration getMaximumCumulativePeriod()
public final void setMaximumCumulativePeriod(Duration value)
public final ObjectProperty<Duration> maximumCumulativePeriodProperty()
public final V getLastValue()
public final ReadOnlyObjectProperty<V> lastValueProperty()
protected void executeTask(Task<V> task)
Service
Uses the executor
defined on this Service to execute the
given task. If the executor
is null, then a default
executor is used which will create a new daemon thread on which to
execute this task.
This method is intended only to be called by the Service implementation.
executeTask
in class Service<V>
task
- a non-null task to executeprotected void succeeded()
Service
protected void failed()
Service
public void reset()
Service
public boolean cancel()
void schedule(java.util.TimerTask task, long delay)
task
- not nulldelay
- >= 0boolean isFreshStart()
long clock()
private void superReset()
private java.util.TimerTask createTimerTask(Task<V> task)
task
- must not be null.private void executeTaskNow(Task<V> task)
task
- must not be nullprivate static double normalize(Duration d)
d
- can be null