Skip to content

Instantly share code, notes, and snippets.

@swazza
Created May 9, 2017 12:22
Show Gist options
  • Save swazza/e5141c09fa0bc8b6eaee4bdebb74a942 to your computer and use it in GitHub Desktop.
Save swazza/e5141c09fa0bc8b6eaee4bdebb74a942 to your computer and use it in GitHub Desktop.
Ridiculously Simple SAGA Coordinator
function bookCar() {
console.log('%c Starting Book Car Task', 'color: blue');
console.log('...');
console.log('...');
console.log('%c Car Booking Confirmed.', 'color: green');
console.log('%c Book Car Task done.', 'color: blue');
return true;
}
function bookHotel() {
console.log('%c Starting Book Hotel Task', 'color: blue');
console.log('...');
throw new Error('Error booking hotel');
console.log('...');
console.log('%c Hotel Booking Confirmed.', 'color: green');
console.log('%c Book Hotel Task done.', 'color: blue');
return true;
}
function bookFlight() {
console.log('%c Starting Book Flight Task', 'color: blue');
console.log('...');
console.log('...');
console.log('%c Flight Booking Confirmed.', 'color: green');
console.log('%c Book Flight Task done.', 'color: blue');
return true;
}
function* bookCarTask() {
try {
yield bookCar();
} catch (err) {
console.log('%c Book Car Task Compensated', 'color: orange');
yield err;
}
}
function* bookHotelTask() {
try {
yield bookHotel();
} catch (err) {
console.log('%c Book Hotel Task Compensated', 'color: orange');
yield err;
}
}
function* bookFlightTask() {
try {
yield bookFlight();
} catch (err) {
console.log('%c Book Flight Task Compensated', 'color: orange');
yield err;
}
}
let tasks = [bookCarTask(), bookHotelTask(), bookFlightTask()];
let coordinator = (tasks) => {
let nextTasks = [];
try {
nextTasks = tasks.filter((task, index) => {
let { done, value } = task.next();
if(value instanceof Error) {
console.log(`%c ...`, 'color: red');
console.log(`%c ${value.message}`, 'color: red');
console.log(`%c Compensating all previously run tasks`, 'color: red');
console.log(`%c ...`, 'color: red');
throw {value, index};
}
return !done;
});
} catch (err) {
let { index, value } = err;
tasks
.filter((task, i) => i < index)
.forEach(task => task.throw(value));
}
if(nextTasks.length > 0) {
coordinator(nextTasks)
}
}
coordinator(tasks)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment