NOTE: this library is deprecated and no longer under development.
As of Spinnaker version 1.13, it is no longer used inside Spinnaker.
- Create and register an
com.netflix.scheduledactions.ActionInstance
which gives a handle to the implemented action (com.netflix.scheduledactions.Action
) - Actions can be scheduled using a type of
com.netflix.scheduledactions.triggers.Trigger
. For example, a scheduled trigger for an action can be a cron expression - Track and monitor the action executions with ability to add a listener for events like onCancel(), onStart(), onComplete(), onError(), etc.
Action
s can be executed in an ad-hoc manner too.Action
s can provide cancel hook using the onCancel() callback of ancom.netflix.scheduledactions.ExecutionListener
- Enable/Disable
ActionInstance
s and corresponding scheduled triggers - Persist and view a history of
execution
s for a givenActionInstance
usingscheduled-actions-cassandra
module
This library is not a workflow engine nor a scheduling library (It uses fenzo-triggers
library for time based scheduling).
Following are the two artifacts:
Group/Org | Artifact Id | Required | Features |
---|---|---|---|
com.netflix.scheduledactions | scheduled-actions-core | Yes | Core library features |
com.netflix.scheduledactions | scheduled-actions-cassandra | No | Provides cassandra persistence for ActionInstance, Execution, etc. |
com.netflix.scheduledactions | scheduled-actions-web | No | Provides spring REST controller to access the ActionsOperator |
Download instructions for gradle:
repositories {
jcenter()
}
dependencies {
compile "com.netflix.scheduledactions:${artifactId}:${version}" // For example: compile "com.netflix.scheduledactions:scheduled-actions-core:0.3"
}
com.netflix.scheduledactions.ActionsOperator
is the primary class for registering, enabling, disabling, executing and cancelling ActionInstance
s.
At a high level, users need to follow below steps to use this library:
- Implement an action
- Create an ActionInstance
- Create an ActionsOperator instance
- Register the ActionInstance with ActionsOperator
Details and sample code for each step is explained below:
Create an action by either implementing Action
interface or by extending ActionSupport
class
public class MyAction implements Action {
// Implement methods here...
}
public class MyAction extends ActionSupport {
// Implement or/and override methods here...
}
ActionInstance
provides a builder to create an action instance
ActionInstance actionInstance = ActionInstance.newActionInstance()
.withName("Process Items")
.withGroup("MyApplication")
.withAction(MyAction.class)
.withOwners("[email protected]")
.withWatchers("[email protected]")
.build();
A Trigger
can be associated with an ActionInstance
ActionInstance actionInstance = ActionInstance.newActionInstance()
.withName("Process Items")
.withGroup("MyApplication")
.withAction(MyAction.class)
.withTrigger(new CronTrigger("0 0 0/1 * * ?")) // Run the action every hour
.build();
Specify a timeout for your action execution
ActionInstance actionInstance = ActionInstance.newActionInstance()
.withName("Process Items")
.withGroup("MyApplication")
.withAction(MyAction.class)
.withTrigger(new CronTrigger("0 0 0/1 * * ?")) // Run the action every hour
.withExecutionTimeoutInSeconds(45*60L) // Timeout after 45 minutes
.build();
Specify an ExecutionListener
for your action
MyListener implements ExecutionListener {
// Implement methods here...
}
ActionInstance actionInstance = ActionInstance.newActionInstance()
.withName("Process Items")
.withGroup("MyApplication")
.withAction(MyAction.class)
.withTrigger(new CronTrigger("0 0 0/1 * * ?")) // Run the action every hour
.withExecutionTimeoutInSeconds(45*60L) // Timeout after 45 minutes
.withExecutionListener(MyListener.class)
.build();
A concurrent execution strategy can also be setup for the action instance. The strategy can be set to one of the following:
- REJECT - skip the action execution if one is already running (default)
- ALLOW - execute all
Execution
s concurrently - REPLACE - cancel the previous one and run the new one
This can be configured while creating the ActionInstance
ActionInstance actionInstance = ActionInstance.newActionInstance()
.withName("Process Items")
.withGroup("MyApplication")
.withAction(MyAction.class)
.withTrigger(new CronTrigger("0 0 0/1 * * ?")) // Run the action every hour
.withExecutionTimeoutInSeconds(45*60L) // Timeout after 45 minutes
.withExecutionListener(MyListener.class)
.withConcurrentExecutionStrategy(ConcurrentExecutionStrategy.ALLOW)
.build();
For creating an instance of ActionsOperator, use the static factory method in ActionsOperator class
ActionsOperator.getInstance(...);
The getInstance() method above takes following parameters:
- DaoConfigurer - a DAO implementations holder class. If using
scheduled-actions-cassandra
library, then the Cassandra DAO implementations can be used. If not, use the existing InMemoryXXXDao implementations - Executor - an implementation of
com.netflix.scheduledactions.executors.Executor
interface. Use thecom.netflix.scheduledactions.executors.ExecutorFactory
to get an executor - int - the size of the scheduler thread pool
So, assuming the scheduled-actions-cassandra
library is being used, below is the sample code for creating an ActionsOperator instance
Keyspace keyspace = <Astyanax keyspace instance>
DaoConfigurer daoConfigurer = new DaoConfigurer(new CassandraActionInstanceDao(keyspace), new CassandraTriggerDao(keyspace))
Executor executor = ExecutorFactory.getDefaultExecutor(new CassandraExecutionDao(keyspace), 20) // 20 is the thread pool size for the executor
ActionsOperator actionsOperator = ActionsOperator.getInstance(daoConfigurer, executor, 20)
Once you have a ActionInstance
, you can register it with the ActionsOperator
ActionsOperator actionsOperator = ActionsOperator.getInstance();
actionsOperator.registerActionInstance(actionInstance);
List<Execution> executions = actionsOperator.getExecutions(actionInstance.getId());
If you want to execute your Action
apart from being executed by the Trigger
(if ActionInstance
is created with a trigger), then
you can use ActionsOperator
to execute the ActionInstance
as well
actionsOperator.execute(actionInstance);
// OR
actionsOperator.execute(actionInstanceId);
A best case attempt will be made to cancel the execution by causing an InterruptedException
to the Executor
thread
actionsOperator.cancel(execution);
// OR
actionsOperator.cancel(executionId);
Copyright (C) 2015 Netflix. Licensed under the Apache License.
See LICENSE.txt for more information.