Node Context set and get are the unique per message?

Hi,

Quick question, if I set a context variable in a node is that shared with multiple message or are the unique per message.

I have a manual join based on context of 3 third party API calls, I need all 3 back. I have a 30 second time out in case one does not return.

Say my flow is processing a call, then another call comes in right behind that, will the two messages share the context or will they be unique to each message?

Do I need to store context with the message id?

let waitTime = context.get("jointimeout");
var t;
if ( waitTime === undefined ) {
    t = new Date();
    t.setSeconds(t.getSeconds() + 30);
    context.set("jointimeout", t);
}
if (msg.topic ==="newSmartsheetRowID") context.set(msg.topic, msg.payload);
if (msg.topic ==="msCalendarID") context.set(msg.topic, msg.payload);
if (msg.topic ==="maininfo") context.set(msg.topic, msg);

let newSmartsheetRowID = context.get("newSmartsheetRowID");
let msCalendarID = context.get("msCalendarID");
let maininfo = context.get("maininfo");

if ( maininfo !== undefined && newSmartsheetRowID !== undefined &&
                        msCalendarID !== undefined ) {
    //combine message and return
    msg = {}
    msg = maininfo;
    msg.msCalendarID = msCalendarID;
    msg.newSmartsheetRowID = newSmartsheetRowID;
    //node.warn(msg);
    context.set("newSmartsheetRowID");
    context.set("msCalendarID");
    context.set("maininfo");
    return msg;
    
}
waitTime = context.get("jointimeout");
t = new Date();
if (t >= waitTime) {
    node.warn("Time-Off Request Join Time Out: " + t + ":" + waitTime);
    context.set("newSmartsheetRowID");
    context.set("msCalendarID");
    context.set("maininfo");
    context.set("jointimeout");
    return msg;
}
//return nothing and wait.
return;

Thanks in advance.
Harry

the node context is unique to the NODE. so anything that passes through it will access the same context. Yes you would need to key the context variable with something that was unique to each set of three parts...

This is something the built in split/join nodes can help do for you - when we split each messages gets a msg.part property with an id property unique to that set... you could create that manually nad then let the join node manually join them for you maybe.

Trouble is we're not splitting the messages with a split, it's just goes in 3 separate paths and need all 3 paths to come back together. I played with join for some time and ended up do the manual context because I could never get the join node to be constant.

you should be able to manually add the .parts property to each path with a consistent id - but of course you can do it in a function if you like - but yes they all need to be keyed together somehow so they are separate in the node context.

I played with creating my own parts with the join but I had inconstant results. Willing to try again, I might clone the flow and play with it again. In the meantime, I added the msg.id to the calls and deleting them as well.

let waitTime = context.get(msg.id + ":jointimeout");
var t;
if ( waitTime === undefined ) {
    t = new Date();
    t.setSeconds(t.getSeconds() + 30);
    context.set(msg.id + ":jointimeout", t);
}
if (msg.topic ==="newSmartsheetRowID") context.set(msg.id + ":newSmartsheetRowID", msg.payload);
if (msg.topic ==="msCalendarID") context.set(msg.id + ":msCalendarID", msg.payload);
if (msg.topic ==="maininfo") context.set(msg.id + ":maininfo", msg);

let newSmartsheetRowID = context.get(msg.id + ":newSmartsheetRowID");
let msCalendarID = context.get(msg.id + ":msCalendarID");
let maininfo = context.get(msg.id + ":maininfo");

if ( maininfo !== undefined && newSmartsheetRowID !== undefined &&
                        msCalendarID !== undefined ) {
    //combine message and return
    msg = {}
    msg = maininfo;
    msg.msCalendarID = msCalendarID;
    msg.newSmartsheetRowID = newSmartsheetRowID;
    //node.warn(msg);
    context.set(msg.id + ":newSmartsheetRowID");
    context.set(msg.id + ":msCalendarID");
    context.set(msg.id + ":maininfo");
    context.set(msg.id + ":jointimeout");
    return msg;
    
}
waitTime = context.get(msg.id + ":jointimeout");
t = new Date();
if (t >= waitTime) {
    node.warn("Time-Off Request Join Time Out: " + t + ":" + waitTime);
    context.set(msg.id + ":newSmartsheetRowID");
    context.set(msg.id + ":msCalendarID");
    context.set(msg.id + ":maininfo");
    context.set(msg.id + ":jointimeout");
    return msg;
}
//return nothing and wait.
return;

I can't see what you are doing that a join node wouldn't?

If you set a join node to manual & key value mode, then set the item count & timeout, you should have the same result (or at least a useable result without the overhead of a function node & context management.

Thanks for the feedback, my experience with the join as really been inconsistent. I even opened a couple of threads here on the challenges.

Item count; The join node works on properties, even if you're trying to merge objects. So I wanted to wait for 3 msg objects back, but I had to count properties and it got unreliable

I was even resetting the msg object back to empty with msg = {} then adding my own properties so I could keep a count, this made scalability a pain, resulting in inconsistent results.

I had messed with creating my own parts object to trying recreate what split does but, again inconsistent results.

The manual join as worked and been working great, it does not care how many properties an object contains, it just merges the object. If I could get the join node to wait for 3 objects not matter how many properties they have and just merge all 3 objects in one, it would be great.

I just wanting to preempt multiple messages coming in, hopefully adding the message id to the context name will make them unique.

thanks again
Harry

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