1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Force reeval of env vars if group/flow/global envs change

This commit is contained in:
Nick O'Leary 2023-07-10 12:04:52 +01:00
parent 3209777aba
commit 7481b78b16
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
3 changed files with 90 additions and 34 deletions

View File

@ -53,27 +53,8 @@ class Flow {
this.isGlobalFlow = false; this.isGlobalFlow = false;
} }
this.id = this.flow.id || "global"; this.id = this.flow.id || "global";
// Initialise the group objects. These must be done in the right order
// starting from outer-most to inner-most so that the parent hierarchy
// is maintained.
this.groups = {} this.groups = {}
this.groupOrder = [] this.groupOrder = []
const groupIds = Object.keys(this.flow.groups || {})
while (groupIds.length > 0) {
const id = groupIds.shift()
const groupDef = this.flow.groups[id]
if (!groupDef.g || this.groups[groupDef.g]) {
// The parent of this group is available - either another group
// or the top-level flow (this)
const parent = this.groups[groupDef.g] || this
this.groups[groupDef.id] = new Group(parent, groupDef)
this.groupOrder.push(groupDef.id)
} else {
// Try again once we've processed the other groups
groupIds.push(id)
}
}
this.activeNodes = {}; this.activeNodes = {};
this.subflowInstanceNodes = {}; this.subflowInstanceNodes = {};
this.catchNodes = []; this.catchNodes = [];
@ -190,6 +171,27 @@ class Flow {
this._env = { ...this._env, ...await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id)) } this._env = { ...this._env, ...await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id)) }
} }
// Initialise the group objects. These must be done in the right order
// starting from outer-most to inner-most so that the parent hierarchy
// is maintained.
this.groups = {}
this.groupOrder = []
const groupIds = Object.keys(this.flow.groups || {})
while (groupIds.length > 0) {
const id = groupIds.shift()
const groupDef = this.flow.groups[id]
if (!groupDef.g || this.groups[groupDef.g]) {
// The parent of this group is available - either another group
// or the top-level flow (this)
const parent = this.groups[groupDef.g] || this
this.groups[groupDef.id] = new Group(parent, groupDef)
this.groupOrder.push(groupDef.id)
} else {
// Try again once we've processed the other groups
groupIds.push(id)
}
}
for (let i = 0; i < this.groupOrder.length; i++) { for (let i = 0; i < this.groupOrder.length; i++) {
// Start the groups in the right order so they // Start the groups in the right order so they
// can setup their env vars knowning their parent // can setup their env vars knowning their parent

View File

@ -271,6 +271,10 @@ function getFlows() {
async function start(type,diff,muteLog,isDeploy) { async function start(type,diff,muteLog,isDeploy) {
type = type || "full"; type = type || "full";
if (diff && diff.globalConfigChanged) {
type = 'full'
}
started = true; started = true;
state = 'start' state = 'start'
var i; var i;
@ -441,6 +445,9 @@ function stop(type,diff,muteLog,isDeploy) {
log.info(log._("nodes.flows.stopping-flows")); log.info(log._("nodes.flows.stopping-flows"));
} }
} }
if (diff.globalConfigChanged) {
type = 'full'
}
started = false; started = false;
state = 'stop' state = 'stop'
var promises = []; var promises = [];
@ -464,7 +471,7 @@ function stop(type,diff,muteLog,isDeploy) {
activeFlowIds.forEach(id => { activeFlowIds.forEach(id => {
if (activeFlows.hasOwnProperty(id)) { if (activeFlows.hasOwnProperty(id)) {
var flowStateChanged = diff && (diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1); var flowStateChanged = diff && (diff.changed.indexOf(id) !== -1 || diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1);
log.debug("red/nodes/flows.stop : stopping flow : "+id); log.debug("red/nodes/flows.stop : stopping flow : "+id);
promises.push(activeFlows[id].stop(flowStateChanged?null:stopList,removedList)); promises.push(activeFlows[id].stop(flowStateChanged?null:stopList,removedList));
if (type === "full" || flowStateChanged || diff.removed.indexOf(id)!==-1) { if (type === "full" || flowStateChanged || diff.removed.indexOf(id)!==-1) {

View File

@ -34,8 +34,11 @@ function diffNodes(oldNode,newNode) {
if (oldNode == null) { if (oldNode == null) {
return true; return true;
} }
var oldKeys = Object.keys(oldNode).filter(function(p) { return p != "x" && p != "y" && p != "wires" }); const keyFilter = p => p != 'x' && p != 'y' && p != 'wires'
var newKeys = Object.keys(newNode).filter(function(p) { return p != "x" && p != "y" && p != "wires" }); const groupKeyFilter = p => keyFilter(p) && p != 'nodes' && p != 'style' && p != 'w' && p != 'h'
var oldKeys = Object.keys(oldNode).filter(oldNode.type === 'group' ? groupKeyFilter : keyFilter);
var newKeys = Object.keys(newNode).filter(newNode.type === 'group' ? groupKeyFilter : keyFilter);
if (oldKeys.length != newKeys.length) { if (oldKeys.length != newKeys.length) {
return true; return true;
} }
@ -354,10 +357,9 @@ function diffConfigs(oldConfig, newConfig) {
var removed = {}; var removed = {};
var changed = {}; var changed = {};
var wiringChanged = {}; var wiringChanged = {};
var globalConfigChanged = false;
var linkMap = {}; var linkMap = {};
var allNestedGroups = []
var changedTabs = {};
// Look for tabs that have been removed // Look for tabs that have been removed
for (id in oldConfig.flows) { for (id in oldConfig.flows) {
@ -372,7 +374,6 @@ function diffConfigs(oldConfig, newConfig) {
var originalState = oldConfig.flows[id].disabled||false; var originalState = oldConfig.flows[id].disabled||false;
var newState = newConfig.flows[id].disabled||false; var newState = newConfig.flows[id].disabled||false;
if (originalState !== newState) { if (originalState !== newState) {
changedTabs[id] = true;
if (originalState) { if (originalState) {
added[id] = oldConfig.allNodes[id]; added[id] = oldConfig.allNodes[id];
} else { } else {
@ -435,6 +436,9 @@ function diffConfigs(oldConfig, newConfig) {
delete changed[id]; delete changed[id];
} }
} }
if (newConfig.allNodes[id].type === 'global-config') {
globalConfigChanged = true
}
} }
// This node's wiring has changed // This node's wiring has changed
if (!redUtil.compareObjects(node.wires,newConfig.allNodes[id].wires)) { if (!redUtil.compareObjects(node.wires,newConfig.allNodes[id].wires)) {
@ -450,6 +454,10 @@ function diffConfigs(oldConfig, newConfig) {
} }
} }
} }
} else {
if (JSON.stringify(node.env) !== JSON.stringify(newConfig.allNodes[id].env)) {
changed[id] = newConfig.allNodes[id];
}
} }
} }
} }
@ -457,6 +465,20 @@ function diffConfigs(oldConfig, newConfig) {
for (id in newConfig.allNodes) { for (id in newConfig.allNodes) {
if (newConfig.allNodes.hasOwnProperty(id)) { if (newConfig.allNodes.hasOwnProperty(id)) {
node = newConfig.allNodes[id]; node = newConfig.allNodes[id];
if (node.type === 'group') {
if (node.g) {
allNestedGroups.push(node)
}
if (changed[node.id]) {
if (node.nodes) {
node.nodes.forEach(nid => {
if (!changed[nid]) {
changed[nid] = true
}
})
}
}
}
// build the map of what this node is now wired to // build the map of what this node is now wired to
if (node.wires) { if (node.wires) {
linkMap[node.id] = linkMap[node.id] || []; linkMap[node.id] = linkMap[node.id] || [];
@ -550,6 +572,26 @@ function diffConfigs(oldConfig, newConfig) {
} }
} }
// Recursively mark all children of changed groups as changed
do {
madeChange = false
for (let i = 0; i < allNestedGroups.length; i++) {
const group = allNestedGroups[i]
if (!changed[group.id] && group.g && changed[group.g]) {
changed[group.id] = true
madeChange = true
}
if (changed[group.id] && group.nodes) {
group.nodes.forEach(nid => {
if (!changed[nid]) {
changed[nid] = true
madeChange = true
}
})
}
}
} while(madeChange)
// Recursively mark all instances of changed subflows as changed // Recursively mark all instances of changed subflows as changed
var changedSubflowStack = Object.keys(changedSubflows); var changedSubflowStack = Object.keys(changedSubflows);
while (changedSubflowStack.length > 0) { while (changedSubflowStack.length > 0) {
@ -575,12 +617,15 @@ function diffConfigs(oldConfig, newConfig) {
} }
} }
var diff = { var diff = {
added:Object.keys(added), added:Object.keys(added),
changed:Object.keys(changed), changed:Object.keys(changed),
removed:Object.keys(removed), removed:Object.keys(removed),
rewired:Object.keys(wiringChanged), rewired:Object.keys(wiringChanged),
linked:[] linked:[],
globalConfigChanged
} }
// Traverse the links of all modified nodes to mark the connected nodes // Traverse the links of all modified nodes to mark the connected nodes
@ -600,6 +645,7 @@ function diffConfigs(oldConfig, newConfig) {
} }
// console.log(diff); // console.log(diff);
// for (id in newConfig.allNodes) { // for (id in newConfig.allNodes) {
// if (added[id] || changed[id] || wiringChanged[id] || diff.linked.indexOf(id)!==-1) {
// console.log( // console.log(
// (added[id]?"a":(changed[id]?"c":" "))+(wiringChanged[id]?"w":" ")+(diff.linked.indexOf(id)!==-1?"l":" "), // (added[id]?"a":(changed[id]?"c":" "))+(wiringChanged[id]?"w":" ")+(diff.linked.indexOf(id)!==-1?"l":" "),
// newConfig.allNodes[id].type.padEnd(10), // newConfig.allNodes[id].type.padEnd(10),
@ -608,6 +654,7 @@ function diffConfigs(oldConfig, newConfig) {
// newConfig.allNodes[id].name||newConfig.allNodes[id].label||"" // newConfig.allNodes[id].name||newConfig.allNodes[id].label||""
// ); // );
// } // }
// }
// for (id in removed) { // for (id in removed) {
// console.log( // console.log(
// "- "+(diff.linked.indexOf(id)!==-1?"~":" "), // "- "+(diff.linked.indexOf(id)!==-1?"~":" "),