@node-red/runtime
Advanced tools
Comparing version 3.0.0-beta.3 to 3.0.0-beta.4
@@ -258,3 +258,80 @@ /** | ||
return sendCredentials; | ||
} | ||
}, | ||
/** | ||
* Gets running state of runtime flows | ||
* @param {Object} opts | ||
* @param {User} opts.user - the user calling the api | ||
* @param {Object} opts.req - the request to log (optional) | ||
* @return {{state:string, started:boolean}} - the current run state of the flows | ||
* @memberof @node-red/runtime_flows | ||
*/ | ||
getState: async function(opts) { | ||
runtime.log.audit({event: "flows.getState"}, opts.req); | ||
const result = { | ||
state: runtime.flows.state() | ||
} | ||
return result; | ||
}, | ||
/** | ||
* Sets running state of runtime flows | ||
* @param {Object} opts | ||
* @param {Object} opts.req - the request to log (optional) | ||
* @param {User} opts.user - the user calling the api | ||
* @param {string} opts.state - the requested state. Valid values are "start" and "stop". | ||
* @return {Promise<Flow>} - the active flow configuration | ||
* @memberof @node-red/runtime_flows | ||
*/ | ||
setState: async function(opts) { | ||
opts = opts || {}; | ||
const makeError = (error, errcode, statusCode) => { | ||
const message = typeof error == "object" ? error.message : error | ||
const err = typeof error == "object" ? error : new Error(message||"Unexpected Error") | ||
err.status = err.status || statusCode || 400; | ||
err.code = err.code || errcode || "unexpected_error" | ||
runtime.log.audit({ | ||
event: "flows.setState", | ||
state: opts.state || "", | ||
error: errcode || "unexpected_error", | ||
message: err.code | ||
}, opts.req); | ||
return err | ||
} | ||
const getState = () => { | ||
return { | ||
state: runtime.flows.state() | ||
} | ||
} | ||
if(!runtime.settings.runtimeState || runtime.settings.runtimeState.enabled !== true) { | ||
throw (makeError("Method Not Allowed", "not_allowed", 405)) | ||
} | ||
switch (opts.state) { | ||
case "start": | ||
try { | ||
try { | ||
runtime.settings.set('runtimeFlowState', opts.state); | ||
} catch(err) {} | ||
if (runtime.settings.safeMode) { | ||
delete runtime.settings.safeMode | ||
} | ||
await runtime.flows.startFlows("full") | ||
return getState() | ||
} catch (err) { | ||
throw (makeError(err, err.code, 500)) | ||
} | ||
case "stop": | ||
try { | ||
try { | ||
runtime.settings.set('runtimeFlowState', opts.state); | ||
} catch(err) {} | ||
await runtime.flows.stopFlows("full") | ||
return getState() | ||
} catch (err) { | ||
throw (makeError(err, err.code, 500)) | ||
} | ||
default: | ||
throw (makeError(`Cannot change flows runtime state to '${opts.state}'}`, "invalid_run_state", 400)) | ||
} | ||
}, | ||
} |
@@ -94,3 +94,3 @@ /** | ||
safeSettings.codeEditor = runtime.settings.editorTheme.codeEditor || {}; | ||
safeSettings.codeEditor.lib = safeSettings.codeEditor.lib || "ace"; | ||
safeSettings.codeEditor.lib = safeSettings.codeEditor.lib || "monaco"; | ||
safeSettings.codeEditor.options = safeSettings.codeEditor.options || {}; | ||
@@ -152,3 +152,15 @@ } | ||
} | ||
if(safeSettings.diagnostics.enabled === false) { | ||
safeSettings.diagnostics.ui = false; // cannot have UI without endpoint | ||
} | ||
safeSettings.runtimeState = { | ||
//unless runtimeState.ui and runtimeState.enabled are explicitly true, they will default to false. | ||
enabled: !!runtime.settings.runtimeState && runtime.settings.runtimeState.enabled === true, | ||
ui: !!runtime.settings.runtimeState && runtime.settings.runtimeState.ui === true | ||
} | ||
if(safeSettings.runtimeState.enabled !== true) { | ||
safeSettings.runtimeState.ui = false; // cannot have UI without endpoint | ||
} | ||
runtime.settings.exportNodeSettings(safeSettings); | ||
@@ -155,0 +167,0 @@ runtime.plugins.exportPluginSettings(safeSettings); |
@@ -39,2 +39,4 @@ /** | ||
var started = false; | ||
var state = 'stop' | ||
var credentialsPendingReset = false; | ||
@@ -54,2 +56,3 @@ | ||
started = false; | ||
state = 'stop'; | ||
if (!typeEventRegistered) { | ||
@@ -219,8 +222,11 @@ events.on('type-registered',function(type) { | ||
// Stop the active flows (according to deploy type and the diff) | ||
return stop(type,diff,muteLog).then(() => { | ||
return stop(type,diff,muteLog,true).then(() => { | ||
// Once stopped, allow context to remove anything no longer needed | ||
return context.clean(activeFlowConfig) | ||
}).then(() => { | ||
if (!isLoad) { | ||
log.info(log._("nodes.flows.updated-flows")); | ||
} | ||
// Start the active flows | ||
start(type,diff,muteLog).then(() => { | ||
start(type,diff,muteLog,true).then(() => { | ||
events.emit("runtime-event",{id:"runtime-deploy",payload:{revision:flowRevision},retain: true}); | ||
@@ -232,3 +238,7 @@ }); | ||
} else { | ||
if (!isLoad) { | ||
log.info(log._("nodes.flows.updated-flows")); | ||
} | ||
events.emit("runtime-event",{id:"runtime-deploy",payload:{revision:flowRevision},retain: true}); | ||
return flowRevision; | ||
} | ||
@@ -266,5 +276,6 @@ }); | ||
async function start(type,diff,muteLog) { | ||
type = type||"full"; | ||
async function start(type,diff,muteLog,isDeploy) { | ||
type = type || "full"; | ||
started = true; | ||
state = 'start' | ||
var i; | ||
@@ -291,3 +302,3 @@ // If there are missing types, report them, emit the necessary runtime event and return | ||
} | ||
events.emit("runtime-event",{id:"runtime-state",payload:{error:"missing-types", type:"warning",text:"notification.warnings.missing-types",types:activeFlowConfig.missingTypes},retain:true}); | ||
events.emit("runtime-event",{id:"runtime-state",payload:{state: 'stop', error:"missing-types", type:"warning",text:"notification.warnings.missing-types",types:activeFlowConfig.missingTypes},retain:true}); | ||
return; | ||
@@ -306,3 +317,3 @@ } | ||
} | ||
events.emit("runtime-event",{id:"runtime-state",payload:{error:"missing-modules", type:"warning",text:"notification.warnings.missing-modules",modules:missingModules},retain:true}); | ||
events.emit("runtime-event",{id:"runtime-state",payload:{state: 'stop', error:"missing-modules", type:"warning",text:"notification.warnings.missing-modules",modules:missingModules},retain:true}); | ||
return; | ||
@@ -316,6 +327,19 @@ } | ||
log.info("*****************************************************************") | ||
events.emit("runtime-event",{id:"runtime-state",payload:{error:"safe-mode", type:"warning",text:"notification.warnings.safe-mode"},retain:true}); | ||
state = 'safe' | ||
events.emit("runtime-event",{id:"runtime-state",payload:{state: 'safe', error:"safe-mode", type:"warning",text:"notification.warnings.safe-mode"},retain:true}); | ||
return; | ||
} | ||
let runtimeState | ||
try { | ||
runtimeState = settings.get('runtimeFlowState') || 'start' | ||
} catch (err) {} | ||
if (runtimeState === 'stop') { | ||
log.info(log._("nodes.flows.stopped-flows")); | ||
events.emit("runtime-event",{id:"runtime-state",payload:{ state: 'stop', deploy:isDeploy },retain:true}); | ||
state = 'stop' | ||
started = false | ||
return | ||
} | ||
if (!muteLog) { | ||
@@ -375,3 +399,2 @@ if (type !== "full") { | ||
} | ||
// Having created or updated all flows, now start them. | ||
for (id in activeFlows) { | ||
@@ -381,3 +404,2 @@ if (activeFlows.hasOwnProperty(id)) { | ||
activeFlows[id].start(diff); | ||
// Create a map of node id to flow id and also a subflowInstance lookup map | ||
@@ -400,3 +422,3 @@ var activeNodes = activeFlows[id].getActiveNodes(); | ||
} else { | ||
events.emit("runtime-event",{id:"runtime-state",retain:true}); | ||
events.emit("runtime-event",{id:"runtime-state", payload:{ state: 'start', deploy:isDeploy}, retain:true}); | ||
} | ||
@@ -414,3 +436,3 @@ | ||
function stop(type,diff,muteLog) { | ||
function stop(type,diff,muteLog,isDeploy) { | ||
if (!started) { | ||
@@ -435,2 +457,3 @@ return Promise.resolve(); | ||
started = false; | ||
state = 'stop' | ||
var promises = []; | ||
@@ -487,2 +510,4 @@ var stopList; | ||
events.emit("flows:stopped",{config: activeConfig, type: type, diff: diff}); | ||
events.emit("runtime-event",{ id:"runtime-state", payload:{ state: 'stop', deploy:isDeploy }, retain:true }); | ||
// Deprecated event | ||
@@ -807,3 +832,3 @@ events.emit("nodes-stopped"); | ||
get started() { return started }, | ||
state: () => { return state }, | ||
// handleError: handleError, | ||
@@ -810,0 +835,0 @@ // handleStatus: handleStatus, |
@@ -218,3 +218,3 @@ /*! | ||
return redNodes.loadContextsPlugin().then(function () { | ||
redNodes.loadFlows().then(redNodes.startFlows).catch(function(err) {}); | ||
redNodes.loadFlows().then(() => { redNodes.startFlows() }).catch(function(err) {}); | ||
started = true; | ||
@@ -403,3 +403,3 @@ }); | ||
version: externalAPI.version, | ||
/** | ||
@@ -409,3 +409,3 @@ * @memberof @node-red/diagnostics | ||
diagnostics:externalAPI.diagnostics, | ||
storage: storage, | ||
@@ -412,0 +412,0 @@ events: events, |
@@ -125,2 +125,3 @@ { | ||
"stopping-error": "Error stopping node: __message__", | ||
"updated-flows": "Updated flows", | ||
"added-flow": "Adding flow: __label__", | ||
@@ -127,0 +128,0 @@ "updated-flow": "Updated flow: __label__", |
{ | ||
"name": "@node-red/runtime", | ||
"version": "3.0.0-beta.3", | ||
"version": "3.0.0-beta.4", | ||
"license": "Apache-2.0", | ||
@@ -19,4 +19,4 @@ "main": "./lib/index.js", | ||
"dependencies": { | ||
"@node-red/registry": "3.0.0-beta.3", | ||
"@node-red/util": "3.0.0-beta.3", | ||
"@node-red/registry": "3.0.0-beta.4", | ||
"@node-red/util": "3.0.0-beta.4", | ||
"async-mutex": "0.3.2", | ||
@@ -23,0 +23,0 @@ "clone": "2.1.2", |
561744
13175
+ Added@node-red/registry@3.0.0-beta.4(transitive)
+ Added@node-red/util@3.0.0-beta.4(transitive)
- Removed@node-red/registry@3.0.0-beta.3(transitive)
- Removed@node-red/util@3.0.0-beta.3(transitive)
Updated@node-red/util@3.0.0-beta.4