Functions in global.set objects - safe?

706 views
Skip to first unread message

Jon Silver

unread,
Apr 22, 2017, 3:48:39 AM4/22/17
to Node-RED
1. In a function node, declare an object with a function member
2. Store the object using global.set
3. Somewhere else, retrieve the object with global.get
4. Execute the function

This is an elegant way of adding global functions on startup, reducing function node code bloat and increasing code reuse.

It works. But is it safe? Nick?

Nick O'Leary

unread,
Apr 22, 2017, 3:58:27 AM4/22/17
to Node-RED Mailing List
The main caveat with that technique is that in a future where we support persisting the contents of context, only JSON serialisable data will be saved with the .get/.set functions. Non-serialisable data will still get stored in memory, but won't be restored across restarts.

The preferred way of doing that is via the functionGlobalSettings option in your settings file, rather than trying to do it dynamically with global.set()


Nick



--
http://nodered.org

Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send an email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/86da8fd7-a8dd-47da-93ea-a5cf705a8125%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jon Silver

unread,
Apr 22, 2017, 4:07:56 AM4/22/17
to node...@googlegroups.com

Understood… but if the non-serialisable stuff is just stripped out, and can be added back on reload, is it perfectly safe?

 

My persistence and liking for this technique is because it’s a very different use-case to using functionGlobalContext in settings.js. Where functions relate to globally held data, they can join that data in very intimate OO way, and live and be maintained within flows.json rather than in some external library.

 

Jon

 

From: node...@googlegroups.com [mailto:node...@googlegroups.com] On Behalf Of Nick O'Leary
Sent: 22 April 2017 08:58
To: Node-RED Mailing List <node...@googlegroups.com>
Subject: Re: [node-red] Functions in global.set objects - safe?

 

The main caveat with that technique is that in a future where we support persisting the contents of context, only JSON serialisable data will be saved with the .get/.set functions. Non-serialisable data will still get stored in memory, but won't be restored across restarts.

 

The preferred way of doing that is via the functionGlobalSettings option in your settings file, rather than trying to do it dynamically with global.set()

 

 

Nick

 

On 22 April 2017 at 08:48, Jon Silver <jonsilve...@gmail.com> wrote:

1. In a function node, declare an object with a function member
2. Store the object using global.set
3. Somewhere else, retrieve the object with global.get
4. Execute the function

This is an elegant way of adding global functions on startup, reducing function node code bloat and increasing code reuse.

It works. But is it safe? Nick?


--
http://nodered.org

Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.

To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.

 

--

http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---

You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/DFDDveKNhzs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.

Julian Knight

unread,
Apr 22, 2017, 12:11:17 PM4/22/17
to Node-RED
It is an interesting idea and I can see its use. Very tempting :)

But safe? I'm not entirely convinced. But here is the issue, it may well be safe for me or you depending on how we are using Node-RED and what platform we are running it on and whether we have protected it from outside influence.

But it would not necessarily be so safe in other cases. This is the "eval" question writ large isn't it? There are cases where eval is really useful and fairly safe but there are many other cases where it isn't.

Personally, I think it would be good to allow functions to be attached to global/context/flow variables - it allows greatest flexibility of use and is fairly "JavaScripty" in approach, very much like eval - but I think it would have to be an option and the default would have to be off.

As far as I can tell, the number of use-cases for this are fairly limited and most people, I think, would not need it since settings.js can easily import code kept in files and function nodes allow creation from the admin UI. But if trying to use Node-RED to create a truly dynamic system allowing user input of functions, then this might be really interesting - but of course, that is the most dangerous use-case anyway - though the use of the Node.JS VM helps limit impacts.

Just thinking out loud.

Jon Silver

unread,
Apr 22, 2017, 2:37:30 PM4/22/17
to Node-RED
Here, try this... it works.

[
   
{
       
"id": "c9398a88.07d288",
       
"type": "inject",
       
"z": "841e269b.77d478",
       
"name": "store",
       
"topic": "",
       
"payload": "",
       
"payloadType": "date",
       
"repeat": "",
       
"crontab": "",
       
"once": true,
       
"x": 150,
       
"y": 3540,
       
"wires": [
           
[
               
"c3098054.262d4"
           
]
       
]
   
},
   
{
       
"id": "c3098054.262d4",
       
"type": "function",
       
"z": "841e269b.77d478",
       
"name": "",
       
"func": "var fns = {};\n\nfns.something = something;\nfns.somethingelse = somethingelse;\n\nglobal.set(\"fns\", fns);\n\nreturn msg;\n\n\nfunction something(thing) {\n    return \"one: \" + thing;\n}\n\nfunction somethingelse(thing) {\n    return \"two: \" + thing;\n}",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 310,
       
"y": 3540,
       
"wires": [
           
[]
       
]
   
},
   
{
       
"id": "31f6f9e9.57f1f6",
       
"type": "inject",
       
"z": "841e269b.77d478",
       
"name": "test",
       
"topic": "",
       
"payload": "",
       
"payloadType": "date",
       
"repeat": "",
       
"crontab": "",
       
"once": false,
       
"x": 190,
       
"y": 3600,
       
"wires": [
           
[
               
"a6a9e393.656e4"
           
]
       
]
   
},
   
{
       
"id": "a6a9e393.656e4",
       
"type": "function",
       
"z": "841e269b.77d478",
       
"name": "",
       
"func": "var fns = global.get(\"fns\");\n\nmsg.payload = {something: fns.something(msg.payload), somethingelse: fns.somethingelse(msg.payload)};\nreturn msg;",
       
"outputs": 1,
       
"noerr": 0,
       
"x": 340,
       
"y": 3600,
       
"wires": [
           
[
               
"685feaeb.e5deb4"
           
]
       
]
   
},
   
{
       
"id": "685feaeb.e5deb4",
       
"type": "debug",
       
"z": "841e269b.77d478",
       
"name": "",
       
"active": true,
       
"console": "false",
       
"complete": "false",
       
"x": 520,
       
"y": 3600,
       
"wires": []
   
}
]

Julian Knight

unread,
Apr 22, 2017, 4:36:39 PM4/22/17
to Node-RED
Thanks Jon, I realise that works now, I was more speculating out loud about the potential use/issues for the future given Nick's comments.
Reply all
Reply to author
Forward
0 new messages