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.ActionInstancewhich 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.
Actions can be executed in an ad-hoc manner too.Actions can provide cancel hook using the onCancel() callback of ancom.netflix.scheduledactions.ExecutionListener- Enable/Disable
ActionInstances and corresponding scheduled triggers - Persist and view a history of
executions for a givenActionInstanceusingscheduled-actions-cassandramodule
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 ActionInstances.
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
Executions 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-cassandralibrary, then the Cassandra DAO implementations can be used. If not, use the existing InMemoryXXXDao implementations - Executor - an implementation of
com.netflix.scheduledactions.executors.Executorinterface. Use thecom.netflix.scheduledactions.executors.ExecutorFactoryto 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.