atombeak
Version:
Create asynchronous atomic functions!
129 lines (128 loc) • 4.96 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Result = require("../Result");
var Message_1 = require("./Message");
var Command_1 = require("./Command");
var Log_1 = require("../Log");
var Retry = /** @class */ (function () {
function Retry(previousAttempt, oldLog) {
this.previousAttempt = previousAttempt;
this.oldLog = oldLog;
}
Retry.prototype.next = function (message) {
if (message.type === Message_1.OUTER_CHANGED) {
if (this.oldLog.isConsistentWithOuter(message.newOuter)) {
return [this, Command_1.noOp];
}
else {
var attempt = this.previousAttempt + 1;
var log = Log_1.Log.create(message.newOuter);
return [new Pending(attempt, log, []), Command_1.shouldRestart(attempt, log)];
}
}
else if (message.type === Message_1.NEXT_ITERATION || message.type === Message_1.RESULT_RECEIVED) {
return [this, Command_1.noOp];
}
else {
var exhaustive = message;
throw new Error(exhaustive);
}
};
return Retry;
}());
exports.Retry = Retry;
var Pending = /** @class */ (function () {
function Pending(attempt, intermediateLog, intermediateOuters) {
this.attempt = attempt;
this.intermediateLog = intermediateLog;
this.intermediateOuters = intermediateOuters;
}
Pending.prototype.next = function (message) {
var _a;
if (message.type === Message_1.OUTER_CHANGED) {
if (this.intermediateLog.isConsistentWithOuter(message.newOuter)) {
var newIntermediateOuters = this.intermediateOuters.concat([message.newOuter]);
return [new Pending(this.attempt, this.intermediateLog, newIntermediateOuters), Command_1.noOp];
}
else {
return this.restartWith(message.newOuter);
}
}
else if (message.type === Message_1.NEXT_ITERATION) {
if (this.attempt !== message.attempt) {
return [this, Command_1.noOp];
}
else {
var appendResult = (_a = message.log).appendStates.apply(_a, this.intermediateOuters);
if (appendResult.type === Log_1.APPEND_SUCCESS) {
return [new Pending(this.attempt, appendResult.log, []), Command_1.shouldContinue(this.attempt, appendResult.log)];
}
else if (appendResult.type === Log_1.RESTART_WITH_OUTER) {
return this.restartWith(appendResult.outer);
}
else {
var exhaustive = appendResult;
throw new Error(exhaustive);
}
}
}
else if (message.type === Message_1.RESULT_RECEIVED) {
if (this.attempt !== message.attempt) {
return [this, Command_1.noOp];
}
else {
if (message.result.type === Result.GOOD) {
return [new Done(this.attempt, message.result.log), Command_1.noOp];
}
else if (message.result.type === Result.RETRY) {
return [new Retry(this.attempt, message.result.log), Command_1.noOp];
}
else {
var exhaustive = message.result;
throw new Error(exhaustive);
}
}
}
else {
var exhaustive = message;
throw new Error(exhaustive);
}
};
Pending.prototype.restartWith = function (outer) {
var newAttempt = this.attempt + 1;
var newLog = Log_1.Log.create(outer);
return [new Pending(newAttempt, newLog, []), Command_1.shouldRestart(newAttempt, newLog)];
};
return Pending;
}());
exports.Pending = Pending;
var Done = /** @class */ (function () {
function Done(attempt, log) {
this.attempt = attempt;
this.log = log;
}
Done.prototype.getActions = function () {
return this.log.getActions();
};
Done.prototype.next = function (message) {
if (message.type === Message_1.OUTER_CHANGED) {
if (this.log.isConsistentWithOuter(message.newOuter)) {
return [this, Command_1.noOp];
}
else {
var attempt = this.attempt + 1;
var log = Log_1.Log.create(message.newOuter);
return [new Pending(attempt, log, []), Command_1.shouldRestart(attempt, log)];
}
}
else if (message.type === Message_1.NEXT_ITERATION || message.type === Message_1.RESULT_RECEIVED) {
return [this, Command_1.noOp];
}
else {
var exhaustive = message;
throw new Error(exhaustive);
}
};
return Done;
}());
exports.Done = Done;