The method workflowExecutionActivityMessageService.updateExecutionActivity(workflowExecutionActivityGuid,updateWorkflowExecutionActivityView)
takes two parameters, workflowExecutionActivityGuid and updateWorkflowExecutionActivityView.
The first parameter workflowExecutionActivityGuid is an input parameter and the second one updateWorkflowExecutionActivityView is an output parameter.
Script
const WAIT_BETWEEN_RETRIES_IN_SECONDS = 1;
const NUMBER_OF_RETRIES = 3;
const MAX_DURATION = 10;
const numberOfRetries = Math.min(Math.ceil(Math.log2(MAX_DURATION)), NUMBER_OF_RETRIES);
var delay = WAIT_BETWEEN_RETRIES_IN_SECONDS * Math.pow(2, numberOfRetries);
return callback(null, {
delay: delay,
numberOfRetries: numberOfRetries
});
public class WorkflowExecutionValidator {
private final List<Validator> validators;
public WorkflowExecutionValidator() {
validators = new ArrayList<>();
validators.add(new WorkflowExecutionValidator.WorkflowExecutionValidator_Running());
validators.add(new WorkflowExecutionValidator.WorkflowExecutionValidator_Completed());
validators.add(new WorkflowExecutionValidator.WorkflowExecutionValidator_Failed());
validators.add(new WorkflowExecutionValidator.WorkflowExecutionValidator_Cancelled());
}
public ValidationResult validate(final Runnable action, final WorkflowExecution execution) {
for (Validator validator : validators) {
if (validator.isApplicable(execution)) {
return validator.validate(action, execution);
}
}
throw new IllegalStateException(String.format("Unable to find validator for status %s", execution.getStatus()));
}
This function will execute the step function if it fails, it will retry 3 times, and then it will stop retrying.
In the function updateWorkflowExecutionV2, we have a new workflowExecution instance.
The value of workflowExecution.status is updated to RUNNING by workflowExecution.setStatus(RUNNING).
And the value of other attribute is updated by workflowExecution.setStartTime(startTime)
The value of isRateLimitedProcessingAllowed is updated by updateWorkflowExecutionDTO.isRateLimitedProcessingAllowed.
Finally, updateWorkflowExecutionDTO is returned.
Script
function add(a, b) {
return a + b;
}
add(1, 2);
public void validate(WorkflowExecutionRequest request, WorkflowExecution workflowExecution) {
validators.forEach(validator -> validator.validate(request, workflowExecution));
}
To run the unit tests execute following command from the root directory of the project:
WorkflowExecutionValidator.validateTransition( oldStatus, newStatus);
public class JavaClass {
public static void main(String[] args){
}
public boolean isString(Object obj){
return obj instanceof String;
}
public static void printString(Object obj) throws Exception
{
if (isString(obj)){
System.out.println((String) obj);
} else {
throw new Exception("Not a string");
}
}
}
## Deployment
1. Install the prerequisites. [Node.js](https://nodejs.org/en/), [Git](https://git-scm.com/downloads)
2. Clone this repository to your local machine or server.
3. Run the following command to install dependencies.
while (true) {
Thread.sleep(10000);
System.out.println("Shreyas");
}
java
package com.amazonaws.services.simpleworkflow.flow.interceptors;
import com.amazonaws.services.simpleworkflow.flow.DataConverter;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.WorkflowContext;
import com.amazonaws.services.simpleworkflow.flow.WorkflowExecution;
import com.amazonaws.services.simpleworkflow.flow.common.FlowConstants;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityExecutionContext;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementation;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementationFactory;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementationOptions;
import com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementationOptions.ScheduleActivityTaskFailedCause;
import com.amazonaws.services.simple
Script
var validators = {
"open": {
"closed": function(issue, user) {
return issue.hasAssignee(user, Issue.OPEN)
}
},
"closed": {
// can be reopened by anyone
"open": function(issue, user) {
return true
}
}
}
public boolean isValidNextStatus(Order order, Status status) {
switch (order.getStatus()) {
case CREATED:
return status == Status.PENDING || status == Status.CANCELED;
case PENDING:
return status == Status.IN_PROCESS || status == Status.CANCELED;
case IN_PROCESS:
return status == Status.SHIPPED || status == Status.CANCELED;
case SHIPPED:
return status == Status.DELIVERED;
case DELIVERED:
case CANCELED:
default:
return false;
}
}
enum State {
STARTED,
IN_PROGRESS,
RESOLVED,
CLOSED
}
enum Validator {
START_TO_INPROGRESS {
public void validate(State from, State to) {
if(from != STARTED) {
throw new IllegalStateException("Not allowed state transition from: " + from + " to: " + to);
}
}
},
INPROGRESS_TO_RESOLVED {
public void validate(State from, State to) {
if(from != IN_PROGRESS || to != RESOLVED) {
throw new IllegalStateException("Not allowed state transition from: " + from + " to: " + to);
}
}
},
RESOLVED_TO_CLOSED {
public void validate(State from, State to) {
if(from != RESOLVED || to != CLOSED) {
throw new IllegalStateException("Not allowed state transition from: " + from + " to: " +
}
}
public static void printWithWait(String s) {
System.out.println(s);
try{
Thread.sleep(10000);
}catch (InterruptedException ie){}
}
public class StateValidator {
public StateValidator(State currentState) {
this.currentState = currentState;
}
public boolean isValid(State newState) {
boolean result = false;
switch(newState) {
case TO_BE_APPROVED:
result = (currentState == State.DRAFT);
break;
case APPROVED:
result = (currentState == State.TO_BE_APPROVED);
break;
case PUBLISHED:
result = (currentState == State.APPROVED);
break;
case ARCHIVED:
result = (currentState == State.PUBLISHED);
break;
case DRAFT:
result = (currentState == State.ARCHIVED);
break;
default:
break;
}
return result;
}
private State currentState;
}
The function retry takes in three parameters. The first parameter is the maximum number of times that the function will retry calling the method. The second parameter is the amount of time in milliseconds that the function will wait before calling the method again. The last parameter is the method that will be called. The function will also log any exception thrown. If the method throws an exception and there are more attempts left, the function will wait for the delay and call the method again. If there are not any more retries left, the function will throw a RetryFailedException.
##### To run the unit tests:
To update the activity of a workflow, an activity DTO is used. The DTO has several parameters that are set by the method to
update the activity.
public void send(String message) throws InterruptedException {
int count = 0;
while (count < 3) {
try {
sqs.sendMessage(queueUrl, message);
break;
} catch (AmazonServiceException ex) {
count++;
if (ex.getErrorCode().equals("RequestError") && ex.getStatusCode() == 400) {
System.out.println("SQS message payload size too large, will retry with a smaller message size");
sqs.sendMessage(queueUrl, message.substring(0, Math.min(message.length(), 256)));
}
}
Thread.sleep(Math.min((int) Math.pow(2, count) * 1000, 10000));
}
}
Script
function Status(status) {
this._status = status;
this._validators = [];
}
Status.prototype.addValidator = function(validator) {
this._validators.push(validator);
}
Status.prototype._applyValidators = function() {
for (var i = 0; i < this._validators.length; i++) {
this._validators[i](this._status);
}
}
var status = new Status('new');
//add validator
status.addValidator(function(status) {
if (status === 'new') {
console.log('status is new');
}
});
//add another validator
status.addValidator(function(status) {
if (status === 'new') {
throw new Error('status is new');
}
});
//execute validators
status._applyValidators();
public void print_name(int delay) throws InterruptedException {
for (int i = 0; i < 3; i++) {
System.out.print("Shreyas");
Thread.sleep(delay * 1000);
}
}
void run() throws InterruptedException {
print_name(10);
print_name(3);
}
@Override
public void
handle(WorkflowExecutionEvent event,
Error error,
StepFunctionRetryer retryer) {
// The processing must not exceed the message visibility timeout
if (System.currentTimeMillis() < event.getMessage().getExpectedExecutionTimeInSeconds() * 1000) {
try {
retryer.retry(event, error);
} catch (Exception e) {
// This exception is thrown if the maximum number of retries has been exhausted.
// At this point we can decide to fail the step function execution or to retry the execution again.
// We can also use the retryer.retry(event, error, delayInSeconds) method to control the delay for the next retry.
// The delays are calculated using an exponential backoff algorithm.
retryer.retry(event, error);
}
}
}
Script
function add(a, b) {
return a + b;
}
add(1, 2);
public class Test {
static String printString(String a){
return a;
}
static void printString(int a) throws Exception{
throw new Exception("This is not a string");
}
public static void main (String[] args) throws Exception {
int i = 0;
while(i < 3){
try{
printString(3);
}
catch(Exception e){
System.out.println(e.getMessage());
i++;
}
}
printString("this is a string");
}
}
Script
{
"StartAt": "Start",
"States": {
"Start": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:662688594788:function:helloworld",
"Retry": [
{
"ErrorEquals": [
"States.ALL"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"End": true
}
}
}
import java.util.*;
import java.lang.*;
import java.io.*;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
long start = System.currentTimeMillis();
System.out.println("Start: " + start);
while(true){
System.out.println("Shreyas");
if(System.currentTimeMillis() - start > 10000){
break;
}
}
}
}
public class WorkflowExecutionValidator {
public static boolean isTransitionAllowed(WorkflowExecution wf, WorkflowExecution.State nextState) {
if (wf.getState() == nextState) {
// no transition if previous state and next state are the same
return false;
}
return getValidator(wf.getState()).isTransitionAllowed(nextState);
}
private static StateValidator getValidator(WorkflowExecution.State state) {
switch (state) {
case STARTED:
return new StartedValidator();
case RUNNING:
return new RunningValidator();
case SUCCEEDED:
return new SucceededValidator();
case FAILED:
return new FailedValidator();
case CANCELLED:
return new CancelledValidator();
case TIMED_OUT:
return new TimedOutValidator();
default:
throw new IllegalArgumentException("State not expected: " + state);
}
- **Examples:**
Script
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
The for loop is used to repeat a block of statements.
public class Retry {
public static void main(String[] args) {
int retries = 3;
int delay = 5;
String string = "shreyas";
System.out.println(string);
while (retries > 0) {
try {
Thread.sleep(delay * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(string);
retries--;
}
}
}
this expression is used to determine the name that is displayed in the list view of the workflow executions.
If the execution is produced by a workflow job, $acquiredObjectName has a value,
otherwise the workflowId is displayed.
(Note: we need to use the workflowExecutionId because the workflowId of the workflow job
is not uniquely defined, the workflowId of the workflow execution is unique.)
package com.example.retry;
import java.io.IOException;
public class Retry {
public static void main(String[] args) throws IOException {
Retry retry = new Retry();
retry.retry(3, () -> retry.dodgyMethod());
}
void retry(int attempts, RetryFunction function) throws IOException {
while (attempts > 0) {
try {
function.run();
break;
} catch (IOException e) {
attempts--;
}
}
}
void dodgyMethod() throws IOException {
throw new IOException();
}
@FunctionalInterface
interface RetryFunction {
public void run() throws IOException;
}
}
This for loop is for retry functionality.
The method updateExecutionActivity updates the execution activity view, in case of success it returns a response with the HttpStatus.ok and the updated execution activity view.
public class ValidatorFactory {
public interface Validator {
public void validate();
}
public class WorkflowValidatorFactory {
private Map<String, Validator> validatorMap = new HashMap<>();
public WorkflowValidatorFactory() {
validatorMap.put("SUBMITTED", new SubmittedValidator());
validatorMap.put("IN_PROGRESS", new InProgressValidator());
validatorMap.put("COMPLETED", new CompletedValidator());
}
public Validator getValidator(String status) {
return validatorMap.get(status);
}
}
public class SubmittedValidator implements Validator {
@Override
public void validate() {
//do validation logic
}
}
public class InProgressValidator implements Validator {
@Override
public void validate() {
//do validation logic
}
}
public class CompletedValidator implements Validator {
@Override
public void validate() {
//do validation logic
Script
var myName = 'Johan';
function throwException(myName) {
if (typeof myName != 'string') {
throw 'myName should be a string';
}
}
throwException(myName)
If you are using IntelliJ you can run the tests by right clicking on the `test_add` method and selecting 'Run TestAdd.test_add'.
## Assignments
### Problem One
Write a function that takes an array of integers and returns their sum.
For example `sum([1, 2, 3])` should return 6
### Problem Two
Write a function that takes an array of integers and returns their average.
For example, `average([1, 2, 3])` should return 2
### Problem Three
Write a function that takes an array of integers, and returns the index of the array that holds the largest value.
For example, `indexOfMax([1, 2, 3, 2, 1])` should return 2
### Problem Four
Write a function that takes an array of integers, and returns the largest value.
For example, `max([1, 2, 3, 2, 1])` should return 3
### Problem Five
Write a function that takes an array of integers, and returns the smallest value.
For example, `min
Script
var validators = {
'init': function () { return true },
'created': function (wf, _) {
return wf.status === 'created'
},
'submitted': function (wf, _) {
return wf.status === 'submitted'
},
'inProgress': function (wf, _) {
return wf.status === 'inProgress'
},
'executing': function (wf, _) {
return wf.status === 'inProgress'
},
'completed': function (wf, _) {
return wf.status === 'completed'
},
'failed': function (wf, _) {
return wf.status === 'failed'
},
'cancelled': function (wf, _) {
return wf.status === 'cancelled'
}
}
Script
function check_string(s)
{
if (typeof s !== 'string')
{
throw new Error("It's not a string!")
}
console.log(s)
}
check_string(2)
// It's not a string!
check_string("Hello World")
// Hello World
public class ExponentialBackoff {
private static final int MAX_RETRIES = 5;
private static final long INITIAL_DELAY = 500;
private static final long MAX_DELAY = 15000;
public static void main(String[] args) {
int currentRetries = 0;
long delay = INITIAL_DELAY;
while (currentRetries < MAX_RETRIES) {
System.out.println("currentRetries: " + currentRetries + " ; delay: " + delay);
currentRetries++;
delay *= 2;
if (delay > MAX_DELAY) {
delay = MAX_DELAY;
}
}
}
}
Script
function printString(str){
if(typeof str !== "string"){
throw new Error("Argument not a string");
}
console.log(str)
return str;
}
for(var i = 0; i < 3; i++){
try{
printString("hello");
}catch(e){
console.log("error: " + e);
}
}
private List<Validator> validators
String a = "Hello";
a.equals(a);
Script
function printString(str) {
if (typeof(str) === 'string') {
return str
}
else {
throw "string needed"
}
}
try{
printString("hello")
}
catch(err){
console.log("error", err)
}
import java.util.Scanner;
public class MyClass {
public static void main(String args[]) {
Scanner myObj = new Scanner(System.in);
System.out.println("Enter username");
String userName = myObj.nextLine();
System.out.println("Username is: " + userName);
}
}
String str = "shreyas";
int delay = 5;
int retries = 3;
int duration = 10;
int numAttempt = 0;
while (numAttempt < retries && duration < 10) {
try {
//print the string
}
catch (Exception e) {
// sleep for delay seconds
}
numAttempt++;
duration = duration + delay;
}
int retryCount = 0;
while (retryCount++ < 3) {
try {
LambdaLogger.log("Trying to send a request to Step Function service. Try #" + retryCount);
Thread.sleep(new java.util.Random().nextInt(2000));
} catch (Exception e) {
LambdaLogger.log("Error");
}
}
public class WorkflowExecutionValidator {
private static final Map<WorkflowExecutionStatus, StatusValidator> statusValidatorMap = new HashMap<>();
static {
statusValidatorMap.put(WorkflowExecutionStatus.WAITING_FOR_INPUT, new WaitingForInputValidator());
statusValidatorMap.put(WorkflowExecutionStatus.COMPLETED, new CompletedValidator());
statusValidatorMap.put(WorkflowExecutionStatus.FAILED, new FailedValidator());
}
public static void validate(WorkflowExecution workflowExecution, WorkflowExecutionStatus targetStatus) {
StatusValidator statusValidator = statusValidatorMap.get(workflowExecution.getStatus());
if (statusValidator == null) {
throw new IllegalStateException("No validator for status " + workflowExecution.getStatus());
}
statusValidator.validate(workflowExecution, targetStatus);
}
}
private void process(String message, String receiptHandle) throws Exception {
String messageBody = new String(Base64.decodeBase64(message));
String[] messageArr = messageBody.split(":");
String taskToken = messageArr[0];
String input = messageArr[1];
int numberOfRetries = Integer.parseInt(messageArr[2]);
try {
stepFunctionHelper.startExecution(taskToken, input);
sqsHelper.deleteMessage(receiptHandle);
} catch (Exception e) {
if (numberOfRetries < 3) {
int delay = (int) Math.pow(2, numberOfRetries) * 1000;
new Thread(() -> {
try {
Thread.sleep(delay);
queueMessage(messageBody, numberOfRetries + 1);
} catch (Exception e1) {
}
}).start();
sqsHelper.deleteMessage(receiptHandle);
} else {
throw e;
}
public void validate(WorkflowExecution workflowExecution) {
if (workflowExecution.getTransition() == null) {
throw new IllegalArgumentException("Transition is not set.");
}
final WorkflowExecutionStatus fromStatus = workflowExecution.getStatus();
if (fromStatus == null) {
throw new IllegalArgumentException("Status is not set.");
}
final Transition transition = workflowExecution.getTransition();
final List<Validator> validators = getValidators(fromStatus);
for (Validator validator : validators) {
if (!validator.isTransitionAllowed(transition)) {
throw new IllegalStateException("Transition from " + fromStatus + " to " + transition + " is forbidden.");
}
}
}
Script
function getValidator(state) {
return function(action) {
return action === state;
};
}
const validator = getValidator('running');
validator('running'); // returns true
workflowExecution.setStatus(WorkflowExecutionStatus.COMPLETED);
workflowExecutionValidator.validateTransition(
workflowExecution,
WorkflowExecutionStatus.COMPLETED, DummyUser.ADMIN);
The function add takes two arguments a and b and returns the sum of a and b.
public class WorkflowExecutionValidator {
private List<Validator> validators;
public boolean isValid(WorkflowExecution workflowExecution){
//the validator to be used is selected based on the status
Validator validator = validators.stream().filter(validator -> validator.isFor(workflowExecution.getStatus())).findFirst().orElseThrow(() -> new RuntimeException("Could not find a validator for status " + workflowExecution.getStatus()));
return validator.isValid(workflowExecution);
}
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="workflow" method="POST">
<input type="text" name="search_key" />
<input type="submit" value="Search" />
</form>
</body>
</html>
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.javacodegeeks.snippets.enterprise")
public class AppConfig {
}
public class WebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
class WorkflowExecutionValidator {
List<WorkflowExecutionStatusValidator> validators;
public boolean isTransitionAllowed(WorkflowExecutionStatus currentStatus, WorkflowExecutionStatus newStatus){
//get validator by currentStatus, get a list of validators, check if the new status is in the list of allowed statuses
for(WorkflowExecutionStatusValidator validator: validators){
if(validator.getCurrentStatus() == currentStatus){
return validator.isAllowed(newStatus);
}
}
return false;
}
}
3.2 Tests that: public void assertEquals(long expected, long actual)
Asserts that two longs are equal. If they are not, an AssertionFailedError, with the given message, is thrown.
Parameters:
expected long: the expected value
actual long: the actual value
Throws:
AssertionFailedError if the two longs are not equal
test_assert
3.3 Tests that: public void assertEquals(String message, float expected, float actual, float delta)
Asserts that two floats are equal to within a positive delta. If they are not, an AssertionFailedError, with the given message, is thrown. If the expected value is infinity then the delta value is ignored. NaNs are considered equal: assertEquals(Float.NaN, Float.NaN, *) passes.
Parameters:
message String: the identifying message for the AssertionFailedError (null okay)
expected float: the expected value
actual float: the value to check against expected
delta float: the maximum delta between expected and actual
class WorkflowExecutionValidator(object):
def __init__(self, workflow_execution: WorkflowExecution):
self.workflow_execution = workflow_execution
def validate(self):
validators = [
InitialValidator(),
ProcessingValidator(),
FailedValidator(),
CompletedValidator()
]
for validator in validators:
if validator.is_validator_for(self.workflow_execution):
return validator.validate(self.workflow_execution)
The program shows how to write an enum State in Java and how to use the enum State to create a new object of type Order. The Order class's constructor sets the state to PENDING. The program also shows how to use enum State to write conditional statements like if () {} to control the state of Order.
public class ExpBackoffRetry {
public static void main(String[] args) {
String s = "abc";
int[] arr = {1, 2, 3, 4};
System.out.println(arr[1]);
int i = 0;
while (i < 4) {
int waitTime = (int)Math.pow(2, i);
i++;
}
while (i < 4) {
int waitTime = (int)Math.pow(2, i);
i++;
}
}
}
Script
function printString(str) {
if(typeof str !== "string") {
throw new Error("string expected");
}
console.log(str);
}
printString("hello");
printString(1);
The function above takes two arguments a and b and returns the sum of a and b.
Script
"Retry": [
{
"ErrorEquals": [
"States.ALL"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2
}
]
Script
var retry_time = 0;
for (var retry_attempt = 0; retry_attempt < 3; retry_attempt++) {
retry_time += Math.pow(2, retry_attempt) * 1000;
if (retry_time > 10000) {
break;
}
}
import time
from functools import wraps
def retry(f):
@wraps(f)
def wrapper(*args, **kwargs):
exception = None
for _ in range(3):
try:
return f(*args, **kwargs)
except Exception as e:
exception = e
time.sleep(1)
raise exception
return wrapper
Script
function sleep(seconds) {
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
}
function listSQS(url, params = {}, retries = 3) {
return new Promise((resolve, reject) => {
var sqs = new AWS.SQS({
apiVersion: '2012-11-05'
});
sqs.listQueues(params, (err, data) => {
if (err) {
if (retries > 0) {
sleep(Math.pow(2, 4 - retries)).then(() => {
listSQS(url, params, retries - 1).then(resolve, reject)
})
} else {
reject(err)
}
} else {
resolve(data)
}
})
})
}
exports.handler = (event, context, callback) => {
var url = event.queueUrl;
listSQS(url).then(data => {
Script
var timeout = 3000; // 3 seconds
function printWithTimeout(str, timeout) {
setTimeout(function() {
console.log(str);
}, timeout);
}
printWithTimeout("Shreyas", timeout);
printWithTimeout("Shreyas", timeout);
printWithTimeout("Shreyas", timeout);
The annotation @JmsListener is a Spring annotation that tells to the spring container to listen for messages on the destination workflow.execution.initiator.queue.name
Integer retrySeconds = 0;
for (int i = 1; i <= 3; i++) {
retrySeconds += Math.pow(2, i - 1);
}
Script
function Add(){
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
}
return sum;
}
Script
function exponentialRetryPolicy(context) {
var retries = 3;
var backoffRate = 2.0;
var retryInterval = 1000; // 1s
var maxInterval = 10000; // 10s
var maxElapsedTime = 10000; // 10s
var errorCodes = [
"RequestEntityTooLarge",
"Throttling",
"ThrottlingException",
"RequestLimitExceeded",
"LimitExceededException",
"InternalServerError",
"ServiceUnavailable"
];
return new ExponentialRetryPolicy(errorCodes, retryInterval, maxInterval, maxElapsedTime, retries, backoffRate, context);
}
Script
function printString(str) {
if (typeof str === 'string') {
console.log(str);
} else {
throw new Error('input is not a string');
}
}
try {
printString(1);
} catch (e) {
var retryCount = 3;
while (retryCount-- > 0) {
printString(1);
}
}
function createValidator(state) {
return function(currentState) {
return currentState === state;
}
}
var isClosed = createValidator('closed');
var isPending = createValidator('pending');
var isOpen = createValidator('open');
// Usage
isClosed('closed'); // true
isClosed('pending'); // false
isClosed('open'); // false
int retryCount = 0;
while (retryCount <= 3) {
try {
// Attempt to send request to Step Function
break;
} catch (SdkClientException e) {
retryCount++;
final int pause = (int) (Math.pow(2, retryCount) * 100);
Thread.sleep(pause);
// Re-throw if retryCount is 3
if (retryCount == 3) {
throw e;
}
}
}
public void retry() {
final int maxRetries = 3;
int attempts = 0;
int sleepTime = 100;
Exception lastException = null;
do {
attempts++;
try {
// perform request
} catch (Exception e) {
lastException = e;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ie) {
break;
}
sleepTime *= 2;
}
} while (attempts < maxRetries && sleepTime < 10000);
if (attempts == maxRetries) {
throw lastException;
}
}
//TODO
public boolean validate(Workflow wf, String user) throws IOException {
boolean isValidated = true;
Path inputDir = new Path(wf.getInputDirectory());
FileSystem fs = inputDir.getFileSystem(conf);
FileStatus[] files = fs.listStatus(inputDir);
for (FileStatus status : files) {
Path path = status.getPath();
if (fs.isFile(path)) {
try {
isValidated = isValidated && validateFile(fs.open(path));
} catch (IOException e) {
e.printStackTrace();
isValidated = false;
}
}
}
return isValidated;
}
This function listens to the queue defined in the properties file. The properties file is in the resources folder
private static final int MAX_RETRIES = 3;
private static final int RETRY_DELAY_MS = 2000;
private static int attempt = 0;
public static void main(String[] args) throws InterruptedException {
while (attempt < MAX_RETRIES) {
attempt++;
System.out.println("Attempting: " + attempt);
Thread.sleep(RETRY_DELAY_MS * attempt);
}
}
The function configureStatusCodeBasedRetryPolicy take an argument maxAttempts, create an instance of SimpleRetryPolicy with maxAttempts as argument, create an instance of NeverRetryPolicy, and return an anonymous class with a method classify that takes an argument classifiable. If classifiable is an instance of HttpStatusCodeException, we cast it to a HttpStatusCodeException and call the method getRetryPolicyForStatus with the statusCode attribute of the classifiable and the simpleRetryPolicy and the neverRetryPolicy as arguments (which returns simpleRetryPolicy if the statusCode is in the list of retriable status codes and neverRetryPolicy otherwise). If classifiable is not an instance of HttpStatusCodeException, we return the simpleRetryPolicy.
Script
var todo = {
status: 'open',
validators: {
'open': ['close'],
'close': ['open'],
'assigned': ['open', 'close']
},
init: function(status) {
this.status = status;
return this;
},
change: function(newStatus) {
if (this.validators[this.status].indexOf(newStatus) > -1) {
this.status = newStatus;
return this;
} else {
return 'Error';
}
}
}
Script
var validStatus = {
'new': ['pending'],
'pending': ['approved', 'rejected'],
'approved': [],
'rejected': []
}
var isValidStatus = function (currentStatus, newStatus) {
return validStatus[currentStatus].indexOf(newStatus) >= 0;
};
isValidStatus('new', 'pending');
@Test
public void test() {
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com");
driver.findElement(By.name("q")).sendKeys("Automation");
driver.findElement(By.name("btnK")).sendKeys(Keys.RETURN);
//driver.findElement(By.name("btnG")).click();
driver.close();
driver.quit();
}
Script
function validator() {
var current_state = this.get_state();
var new_state = this.next_state();
if (this.transition_allowed(current_state, new_state)) {
this.set_state(new_state);
}
}
public class StringUtils{
public void print(String s){
if(s==null){
throw new NullPointerException("null string");
}
System.out.println(s);
}
}
Script
function printWithPause(str, duration) {
return new Promise(function(resolve) {
setTimeout(function() {
console.log(str)
resolve()
}, duration)
})
}
function printAllInOrder() {
printWithPause("Shreyas", 1000)
.then(() => printWithPause("Shreyas", 1000))
.then(() => printWithPause("Shreyas", 1000))
}
printAllInOrder()
public abstract class Validator<T> {
public abstract Collection<ValidatorResult> validate(T object);
}
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i <= 3; i++) {
System.out.println("Shreyas");
Thread.sleep(10000);
}
}
The function add takes two arguments a and b and returns the sum of a and b.
javascript
{
"newActivityState": "new state",
"newActivityOutput": {
"age": "test age",
"name": "test name"
}
}
@Test
public void executeRetryStepFunction_whenException_retried() {
// GIVEN
WorkflowExecution execution = WorkflowExecutionFixture.someWorkflowExecution();
String stepFunctionArn = "stepFunctionArn";
// WHEN
when(workflowExecutionInitiatorService.addExecuteStepFunction(execution, stepFunctionArn)).thenThrow(new RetryableException("some error"))
.thenReturn(null);
try {
workflowInitiatorService.executeRetryStepFunction(execution, stepFunctionArn);
fail("expected RetryableException");
} catch (RetryableException ex) {
// THEN
verify(workflowExecutionInitiatorService, times(2)).addExecuteStepFunction(any(), any());
}
}
private static final int DEFAULT_MAX_RETRY = 5;
private static final int MAX_RETRY = 10;
private static final double BACKOFF_MULTIPLIER = 1.5;
private static final long DEFAULT_INITIAL_RETRY_INTERVAL = 1000L;
private static final long MAX_RETRY_INTERVAL = 30000L;
private static final Logger log = LoggerFactory.getLogger(StepFunctionWorkflowServiceClient.class);
private int maxRetry;
private double backoffMultiplier;
private long initialRetryInterval;
private long maxRetryInterval;
private final String endpoint;
private final String accessKey;
private final String secretKey;
public StepFunctionWorkflowServiceClient(String endpoint, String accessKey, String secretKey) {
this(endpoint, accessKey, secretKey, DEFAULT_INITIAL_RETRY_INTERVAL, MAX_RETRY_INTERVAL, BACKOFF_MULTIPLIER, MAX_RETRY, DEFAULT_MAX_RETRY);
}
public StepFunction
Script
{
"defaultTaskList": { "name": "_defaultTaskList" },
"defaultTaskPriority": "0",
"defaultTaskScheduleToStartTimeout": "NONE",
"defaultTaskScheduleToCloseTimeout": "60",
"defaultTaskStartToCloseTimeout": "120",
"defaultTaskHeartbeatTimeout": "NONE"
}
Script
def print_lyrics():
print("Hey Jude, don't make it bad.")
print("Take a sad song and make it better.")
print_lyrics()
Script
function validator (currentStatus, transitionStatus) {
return function(newStatus) {
return {
to: function(desiredStatus) {
return (desiredStatus === transitionStatus) && (newStatus === currentStatus);
}
}
}
}
Script
function throwError(num) {
console.log(num)
}
throwError("hello world")
The object with the name $acquiredObjectName in the workflow instance with the id $workflowExecutionId
public class WorkflowExecutionValidator {
private List<Validator> validators;
public boolean isAllowed(WorkflowExecution workflowExecution, WorkflowExecution wf, WorkflowExecutionState state) {
...
//if (state == WorkflowExecutionState.FAILED) {
// validators.get(WorkflowExecutionState.FAILED.ordinal()).isAllowed(workflowExecution, state)
//}
//if (state == WorkflowExecutionState.SUCCEEDED) {
// validators.get(WorkflowExecutionState.SUCCEEDED.ordinal()).isAllowed(workflowExecution, state)
//}
//if (state == WorkflowExecutionState.RUNNING) {
// validators.get(WorkflowExecutionState.RUNNING.ordinal()).isAllowed(workflowExecution, state)
//}
//if (state == WorkflowExecutionState.WAITING) {
// validators.
public class ExponentialBackoff {
private static final long DEFAULT_MIN_DELAY = 1000;
private static final long DEFAULT_MAX_DELAY = 300000;
private static final double DEFAULT_DELAY_MULTIPLIER = 2;
private static final long DEFAULT_MAX_ATTEMPTS = 3;
private static final Random RANDOM = new Random();
private long minDelay = DEFAULT_MIN_DELAY;
private long maxDelay = DEFAULT_MAX_DELAY;
private double delayMultiplier = DEFAULT_DELAY_MULTIPLIER;
private long maxAttempts = DEFAULT_MAX_ATTEMPTS;
private long lastDelay;
public long nextDelay(final long attemptNumber) {
if (attemptNumber == 0) {
lastDelay = minDelay;
} else {
lastDelay = Math.min(
Math.round(lastDelay * delayMultiplier + RANDOM.nextDouble() * lastDelay),
@Data
public class WorkflowExecutionValidator {
private List<Validator> validators;
public void validate(WorkflowExecutionStatus current, WorkflowExecutionStatus target) {
// 1. select validator based on current status
// 2. apply validator to check if the transition is allowed
}
}
public void throwException() throws Exception {
throw new Exception("An exception thrown");
}
public class WorkflowExecutionValidator {
private final List<Validator<WorkflowExecution>> validators = new ArrayList<>();
public void addValidator(Validator<WorkflowExecution> validator) {
validators.add(validator);
}
public boolean validate(WorkflowExecution execution, WorkflowExecutionStatus newStatus) {
final Validator<WorkflowExecution> validator = findValidator(execution);
return validator.validate(execution, newStatus);
}
private Validator<WorkflowExecution> findValidator(WorkflowExecution execution) {
return validators.stream()
.filter(validator -> validator.canHandle(execution))
.findFirst()
.orElseThrow(() -> new IllegalStateException("Can't find validator for workflow execution " + execution));
}
}
public interface Validator<T> {
boolean validate(T execution, WorkflowExecutionStatus newStatus);
boolean canHandle(T execution);
}
public class RetryFunction implements Function<Throwable, Integer> {
private static final Logger LOG = LoggerFactory.getLogger(RetryFunction.class);
private static final long BASE_SLEEP = (long) (Math.pow(2, 0) * 100);
private static final long MAX_SLEEP = (long) (Math.pow(2, 3) * 100);
@Override
public Integer apply(Throwable throwable) {
LOG.info("error", throwable);
long sleepTime = BASE_SLEEP;
if (throwable instanceof ActivityTaskFailedException) {
ActivityTaskFailedException activityTaskFailedException = (ActivityTaskFailedException) throwable;
// sleepTime = Long.parseLong(activityTaskFailedException.getCause().getMessage());
sleepTime = MAX_SLEEP;
}
if (sleepTime > MAX_SLEEP) {
sleepTime = MAX_SLEEP;
}
LOG.info("sleepTime={}", sleepTime
Script
var AWS = require('aws-sdk');
var stepfunctions = new AWS.StepFunctions();
exports.handler = function(event, context, callback) {
var params = {
stateMachineArn: event.stateMachineArn
};
stepfunctions.startExecution(params, function(err, data) {
if (err) {
console.log(err);
if (err.code == 'ThrottlingException') {
context.fail(err);
} else {
callback(err);
}
} else {
console.log(data);
callback(null, data);
}
});
};
public static void printString(String str) {
if (str instanceof String) {
System.out.println(str);
} else {
for (int i = 0; i < 3; i++) {
System.out.println("Try again");
try {
throw new Exception("Invalid String");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
interface WorkflowExecutionValidator {
boolean isTransitionAllowed(WorkflowExecution workflowExecution, WorkflowExecutionStatus toStatus);
}
Script
var myDuration = 10;
var printed = false;
var timeoutID = window.setTimeout(printName, myDuration);
function printName() {
if (!printed) {
console.log("Shreyas");
printed = true;
}
}
var totalDuration = 0;
var timeouts = [];
while (totalDuration < 10) {
timeoutID = window.setTimeout(printName, myDuration);
timeouts.push(timeoutID);
totalDuration += myDuration;
}
for (var i = 0; i < timeouts.length; i++) {
window.clearTimeout(timeouts[i]);
}
@Test(retryAnalyzer = CustomRetry.class)
public void test1() {
System.out.println("Shreyas");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assert.fail();
}
@Test(retryAnalyzer = CustomRetry.class)
public void test2() {
System.out.println("Shreyas");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assert.fail();
}
@Test(retryAnalyzer = CustomRetry.class)
public void test3() {
System.out.println("Shreyas");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Assert.fail();
}
This code checks if the httpStatus is contained in HTTP_STATUSES_FOR_SIMPLE_RETRY,
if yes, it returns simpleRetryPolicy, otherwise, it returns neverRetryPolicy.
public class MyClass {
public static int attempts = 3;
public static void main(String[] args) {
// write your code here
for (int i=1; i<=attempts; i++) {
long start = System.currentTimeMillis();
// do something
while(System.currentTimeMillis() - start < 10000) {
}
if (i == attempts) {
System.out.println("Number of retries = " + attempts);
System.out.println("Should complete all the retries under 10 seconds");
}
}
}
}
class StringPrinter {
public void printString(String s){
if(!(s instanceof String)){
throw new RuntimeException("Invalid String");
}
System.out.println(s);
}
}
Script
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function print(name, maxAttempts, maxDuration) {
var counter = 0
var start = new Date().getTime();
var end = start;
var totalDuration = 0;
for (var i = 0; i < maxAttempts; i++) {
console.log(name)
sleep(10000)
end = new Date().getTime();
totalDuration = end - start;
if (totalDuration >= maxDuration) {
break;
}
}
}
print("Shreyas", 3, 10000)
public class ExponentialRetry {
public static void main(String[] args) {
int maxAttempts = 3;
int delay = 1000;
int maxDelay = 5000;
int backoff = 2;
int retries = 0;
while(retries++ < maxAttempts) {
try {
// call aws step functions
} catch(Exception ex) {
// backoff exponential with jitter
delay = getExponentialWithJitterDelay(delay, maxDelay, backoff);
try {
Thread.sleep(delay);
} catch (Exception e) {
// do nothing
}
}
}
}
private static int getExponentialWithJitterDelay(int delay, int maxDelay, int backoff) {
if (delay > maxDelay) {
return maxDelay;
}
Random r = new Random();
double rand = (1 + r.nextDouble()) / 2;
return (int) (rand * delay * backoff);
takes a GUID, a request body, and a view and returns a response entity of type workflowExecutionActivityView.
Script
function printName(name) {
console.log(name);
setTimeout(function(){}, 10000);
}
## Coding
### Code Creation
- Use the following as a guide to create a new class
@Override
public void onFailure(Throwable t) {
if (numOfRetries < MAX_RETRIES) {
logger.info("Retrying the action for the " + numOfRetries + " time.");
numOfRetries++;
executorService.schedule(() -> {
PublishMetricsAction.FailedMessageRetry failedMessageRetry = new PublishMetricsAction.FailedMessageRetry(t);
failedMessageRetry.execute();
}, getNextBackOff(numOfRetries));
} else {
logger.error("Failed to publish metrics after " + numOfRetries + " retries.");
//TODO: send error email
}
}
private long getNextBackOff(int numOfRetries){
if (numOfRetries < 0 || numOfRetries >= MAX_RETRIES) {
return 0;
}
double exponentialBackOffMs = retryBackOff[numOfRetries] * Math.pow(2, numOfRetries
public class WorkflowExecutionValidator {
private List<Validator> validators;
public WorkflowExecutionValidator(List<Validator> validators) {
this.validators = validators;
}
public void validate(WorkflowExecution execution) {
// pick up an appropriate validator from a list and check if transition is allowed
}
}
import java.util.Scanner;
public class ExceptionDemo {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a string: ");
String str = scanner.next();
int len = str.length();
System.out.println("The length of the string is: " + len);
} catch (Exception e) {
System.out.println("Error occurred: " + e.getMessage());
}
}
}
RetryPolicy retryPolicy = new RetryPolicy.RetryPolicyBuilder().withDelayBackoff(Duration.ofSeconds(2), Duration.ofSeconds(30))
.withJitter(0.5)
.withMaxRetryAttempts(20)
.withMaxAttempts(20)
.withInterruptiblePredicate(new Predicate<Throwable>() {
@Override
public boolean test(Throwable throwable) {
return throwable instanceof InterruptedException;
}
})
.build();
The function updateExecutionActivityAndWorkflowExecution takes two arguments workflowExecutionActivityGuid and updateView, and returns an UpdateWorkflowExecutionActivityDTO.
import time
def retry(retry_count, delay_in_seconds):
start_time = time.time()
print("Start time: " + str(start_time))
for i in range(retry_count):
time.sleep(delay_in_seconds)
current_time = time.time()
print("Current time: " + str(current_time))
print("Duration: " + str(current_time-start_time))
print("Try number: " + str(i))
retry(3, 2)
The function workflowExecutionActivityMessageService.updateExecutionActivity takes the workflowExecutionActivityGuid and updateWorkflowExecutionActivityView and returns workflowExecutionActivity.
@Override
public boolean canTransitionTo(WorkflowExecutionStatus status) {
return validators.stream().filter(validator -> validator.getStatus() == status).findAny().get().validate(this);
}
public class WorkflowExecutionValidator extends Validator<WorkflowExecution> {
@Override
public boolean validate(WorkflowExecution workflowExecution) {
return workflowExecution.getStatus() == WorkflowExecutionStatus.PAUSED;
}
}
int result = -1;
int attempts = 0;
int duration = 0;
while (attempts < 3 && duration <= 10) {
try {
result = action.execute();
break;
} catch (Exception e) {
duration += action.getDuration();
attempts++;
}
}
def retry_func(retries):
def decorator(func):
def wrapped(arg):
for i in range(retries):
func(arg)
if i % 3 == 0:
sleep(3)
return wrapped
return decorator
@retry_func(3)
def func(arg):
print(arg)
func(1)
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
## License
MIT License. Copyright 2018 Noah Pepper. http://noahcs.com
WorkflowExecutionValidator.validateOperation()
public static void main(String[] args) throws Exception {
final long startTime = System.currentTimeMillis();
int retries = 0;
final int maxRetries = 3;
final long timeout = 10000;
while(true) {
try {
if (retries > maxRetries) {
throw new Exception("Too many retries");
}
String str = String.valueOf("shreyas");
System.out.println(str);
break;
} catch (Exception e) {
retries++;
final long elapsed = System.currentTimeMillis() - startTime;
if (elapsed >= timeout) {
throw e;
}
}
}
}
Script
function add(a, b) {
if(typeof a !== "string" || typeof b !== "string") {
throw "Inputs must be a string";
} else {
console.log(a + " " + b);
}
}
public static void printNum (int number) throws Exception {
if (number < 0) {
throw new Exception("Number can't be less than zero");
} else {
System.out.println("Number is " + number);
}
}
If the acquiredObjectName is an empty string, than return workflowExecutionId
Script
const machine = Machine({
id: 'machine',
initial: 'A',
states: {
A: {
on: {
EVENT: [
{
target: 'B',
actions: [
'selectValidator',
'validate'
]
},
]
}
},
B: {
on: {
EVENT: 'A'
}
}
}
});
const guards = {
selectValidator: context => {
if (context.transition.event.type === 'EVENT') {
context.validator = _someValidator
}
},
validate: context => {
if (context.transition.event.type === 'EVENT') {
context.validator.validate(context)
}
}
}
def exponentialBackoff(max_attempt_count, max_attempt_duration):
count = 1
wait_time = 1
duration = 0
while count <= max_attempt_count and duration <= max_attempt_duration:
print("Attempting to notify Step Function Service. Attempt number " + str(count))
count = count + 1
duration = duration + wait_time
time.sleep(wait_time)
wait_time = wait_time * 2
print(count)
exponentialBackoff(10,15)
The function startExecution takes three arguments stateMachineArn, executionName and executionInput. The function will return the executionArn of the statemachine.
import java.util.concurrent.TimeUnit;
public class Solution {
public static void main(String[] args) {
String str = "shreyas";
int delay = 5;
int maxRetries = 3;
int totalDuration = 10;
printWithRetry(str, delay, maxRetries, totalDuration);
}
public static void printWithRetry(String str, int delay, int maxRetries, int totalDuration) {
int attempt = 0;
int totalDelay = 0;
while (attempt < maxRetries) {
attempt++;
if (totalDelay >= totalDuration) {
throw new RuntimeException();
}
try {
TimeUnit.SECONDS.sleep(delay);
System.out.println(str);
return;
} catch (InterruptedException e) {
totalDelay += delay;
}
}
throw new RuntimeException();
}
}
public void getRetries() {
int numRetries = 3;
long delay = 1000;
int i = 0;
while (i < numRetries) {
try {
...
} catch (Exception e) {
i++;
if (i == numRetries) {
throw e;
}
delay = delay * 2;
Thread.sleep(delay);
}
}
}
public boolean canTransit(String from, String to, String user) {
Validator validator = getValidator(from, to);
return validator.canTransit(from, to, user);
}
private static final Map<WorkflowExecutionStatus, Validator> validators = new HashMap<WorkflowExecutionStatus, Validator>() {{
put(WorkflowExecutionStatus.CREATED, new CreatedValidator());
put(WorkflowExecutionStatus.RUNNING, new RunningValidator());
put(WorkflowExecutionStatus.SUSPENDED, new SuspendedValidator());
put(WorkflowExecutionStatus.COMPLETED, new CompletedValidator());
put(WorkflowExecutionStatus.FAILED, new FailedValidator());
put(WorkflowExecutionStatus.CANCELED, new CanceledValidator());
}};
The above code will listen to the message in the workflow.execution.initiator.queue.name of the AWS SQS instance.
After retrieving the message it will send it to processMessage() method.
The method annotated with @JmsListener will be invoked when a message is received on the queue with the name workflow.execution.initiator.queue.name.
// Java program to illustrate the
// concept of method overloading
class Test
{
// Method with 1 parameter
public void disp(char c)
{
System.out.println(c);
}
// Method with 2 parameters
public void disp(char c, int num)
{
System.out.println(c + " "+num);
}
}
public class Main
{
public static void main(String args[])
{
Test obj = new Test();
obj.disp('a');
obj.disp('a',10);
}
}
: The java method startExecution uses the stepFunctionsClient to start a new execution.
public class Order {
public enum State {
PENDING,
SUSPENDED,
ACTIVE,
CANCELLED,
COMPLETED
}
Status state;
public Order() {
this.state = State.PENDING;
}
public void approve() {
if (this.state == State.PENDING) {
this.state = State.ACTIVE;
}
}
public void suspend() {
if (this.state == State.ACTIVE) {
this.state = State.SUSPENDED;
}
}
public void complete() {
if (this.state == State.ACTIVE || this.state == State.SUSPENDED) {
this.state = State.COMPLETED;
}
}
public void cancel() {
if (this.state == State.ACTIVE || this.state == State.PENDING) {
this.state = State.CANCELLED;
}
}
public