Defer tail declarations

declare() calls that aren't followed by commit() are applied at the end
of the provision script. This change defers those until all provisions
have been executed. This prevents certain cases of preset loop faults.
This commit is contained in:
Zaid Abdulla committed 2018-09-15 00:09:58 -07:00
1 parent ec215ffb82
commit 1a56915d4b
5 files changed
+163 -83

No files matched your search

+24 -15
View File
@@ -197,36 +197,44 @@ function declare(path, timestamps, values) {
const parsedPath = common.parsePath(path);
const declaration = [parsedPath, 1];
const attrs = {};
const declaration = {
path: parsedPath,
pathGet: 1,
pathSet: null,
attrGet: null,
attrSet: null,
defer: true
};
for (const attrName in values) {
if (!timestamps[attrName]) timestamps[attrName] = 1;
const attrs = new Set();
for (const [attrName, attrValue] of Object.entries(values)) {
if (attrName === "path") {
declaration[3] = values.path;
declaration.pathSet = attrValue;
} else {
attrs[attrName] = 1;
declaration[4] = declaration[4] || {};
attrs.add(attrName);
if (!declaration.attrGet) declaration.attrGet = {};
if (!declaration.attrSet) declaration.attrSet = {};
declaration.attrGet[attrName] = 1;
if (attrName === "value" && !Array.isArray(values.value))
declaration[4].value = [values.value];
else declaration[4][attrName] = values[attrName];
declaration.attrSet.value = [values.value];
else declaration.attrSet[attrName] = values[attrName];
}
}
for (const attrName in timestamps) {
for (const [attrName, attrTimestamp] of Object.entries(timestamps)) {
if (attrName === "path") {
declaration[1] = timestamps.path;
declaration.pathGet = attrTimestamp;
} else {
attrs[attrName] = 1;
declaration[2] = declaration[2] || {};
declaration[2][attrName] = timestamps[attrName];
attrs.add(attrName);
if (!declaration.attrGet) declaration.attrGet = {};
declaration.attrGet[attrName] = attrTimestamp;
}
}
state.declarations.push(declaration);
return new ParameterWrapper(parsedPath, Object.keys(attrs));
return new ParameterWrapper(parsedPath, attrs);
}
function clear(path, timestamp, attributes) {
@@ -241,6 +249,7 @@ function commit() {
state.uncommitted = false;
if (state.revision === state.maxRevision + 1) {
for (const d of state.declarations) d.defer = false;
throw COMMIT;
} else if (state.revision > state.maxRevision + 1) {
throw new Error(