Dynamic name for variables,based for example on __msgid__

Hi everyone,
I want to know if there is a way to define a variable with a dynamic part in the name.

For example, I can define a flow context variable with a dynamic name, like this:

flow.set('value'+_msgid_,"test");

Or I can define a global context variable with a dynamic name, like this:

global.set('value'+_msgid_,"test");

Is it possible to do something like this but for a node context variable?

I'm trying to find the best way to deal with concurrency of requests with a HTTP In node, and one idea is to use something that allow me to have different variable names every time that a flow run.

Anyone with the same problem that can share ideas about how to circumvent this?

Thanks in advance for your help.

Use square bracket property accessors: Property accessors - JavaScript | MDN

e.g.

const httpMonitorLookupObject = node.get('httpMonitor') || {}
const propLookup = msg._msgid_ + '_whatever;
const propVal = httpMonitorLookupObject[propLookup]

// setting a value
httpMonitorLookupObject[propLookup = {}

// storing it all as a single object
node.set('httpMonitor', httpMonitorLookupObject)

Things ok at home @Steve-Mcl? :wink:

const httpMonitorLookupObject = context.get('httpMonitor') || {}
const propLookup = msg._msgid_ + '_whatever';
const propVal = httpMonitorLookupObject[propLookup]

// setting a value
httpMonitorLookupObject[propLookup] = {}

// storing it all as a single object
context.set('httpMonitor', httpMonitorLookupObject)
  • '_whatever vs '_whatever'
  • [propLookup = {} vs [propLookup] = {}
  • node.set/get vs context.set/get

unless I'm missing something, then ignore me :sweat_smile:

1 Like

Was an untested rush job :joy:

Tbf, I don't like making mistakes, this was just sloppy. I am blaming recent I'll health (man flu) and lack of :zzz:

@aguida79 ignore my post and follow @marcus-j-davies

2 Likes

Even with this idea, I cannot find the way to push the different msg.payload messages that are being generated from every node of the workflow to the specific/corresponding httpMonitorLookupObject[propLookup] key, maybe because I'm not a good Javascript coder, :frowning:

Is there a simpler/better way to try to manage concurrency with a flow that run every time that receive an HTTP In, an that events can be received many of them in a few seconds?

Thanks in advance for your help.

You can use msg.req.ip ?

The HTTP IN node will include the clients IP address

// Get Client States
let clients = context.get("clientState")
if(!clients){
    context.set("clientState",{})
    /* we do this to shift our reference to the context */
    clients = context.get("clientState")
}

// Get State for client (Based on their IP), or create a fresh state for the client if not yet known
const clientState = clients[msg.req.ip] || {}

// Set a property
clientState.someProperty = "Hello, World"

// Get a property
const someProp = clientState.someProperty

// Store it (just in-case this is a new client)
clients[msg.req.ip] = clientState

// Remove a clients state if needed
delete clients[msg.req.ip] 

You can then pass on the clientState downstream

msg.state = RED.util.cloneMessage(clientState) /* <-- important, to stop it being modified during transit */
return msg

Thanks @marcus-j-davies for your reply.
The problem in my use case is that the clientIP is going to be always the same, a FluentBit collector that is sending DNS log events by an HTTP Output to be enriched by the NodeRED workflow that I created.

Try msg.req.connection.remotePort

The port, should normally not remain the same for each request.
But that will be based on how FluentBit behaves

At some point, the port will wrap around again - but that is something you will need to manage

Thanks @marcus-j-davies , I'm going to try with that option.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.