Where to store handle of setInterval?

A node which I develop needs to be run periodically. With setInterval, I could achieve this. It is necessary that the interval is set up upon loading the node. Here's my simple solution:

function ShadingNode(originalConfig) {
    RED.nodes.createNode(this,originalConfig);
        const loopIntervalTime = 5000;
        function mainloopFunc(){ ... }
        setInterval(mainloopFunc, loopIntervalTime)
        this.on('input', function(msg,send,done) {
            ...

So far, that works already. But I realized, always when I deploy anything, an additional interval starts. So the idea is to clearInterval first. But where to store the handle? I decided to use the node context.

        if (context.loopIntervalHandle) {
            clearInterval(context.loopIntervalHandle);
            context.loopIntervalHandle = null;
        };
        context.loopIntervalHandle = setInterval(mainloopFunc, loopIntervalTime)

This basically works fine, but after loop number six, I receive the following warning on the console:

[warn] Context 74363dbc26183750:43e75d.3e2038a4 contains a circular reference that cannot be persisted

Though I' curious why this warning does not appear immediately at start, I more am curious about some kind of best practice. Where should I store the handle? Maybe there's a more practicable solution.

Thanks! Tom

There's no need to use context. You can just define at as a variable inside the node constructor and it will be in scope and available to use.

@danube,
Also you might call clearInterval in the node's "close" event...

2 Likes

This is close to the limit of what I know how to do with JS and NR, so I hope I won't mislead you -- and I hope that someone will correct me if I do.

Do you mean this happens when you edit your flow and re-deploy? I would expect that to occur if you do a full deploy or restart. Deploying only modified nodes or (possibly) modified flows should prevent it. In any event, as @BartButenaers says, a clearInterval in the on('close',...) function should eliminate the issue. In general, anything your node does asynchronously should be checked for possible cleanup when the node closes.

By any chance, are you storing context in the localfilesystem? Six intervals of five seconds each corresponds exactly to the 30-second default flushInterval for writing to "disk." If you are storing something that does not serialize properly it could account for the warning message.

As Nick said you don't need to use context for this... I usually do something like node.myInterval = setInterval(.... to hold the reference - and then in the on close you can do... . if (node.myInterval) { clearInterval(node.myInterval) } to tidy it up.

1 Like

@knolleary @dceejay I was already afraid there would be a simple solution I just wasn't able to figure out. Using the constructor seems to be that kind of working way.

@drmibell Your assumption about localfilesystem is correct and explains the event after six times five loops.

@BartButenaers @drmibell @dceejay Haven't had an on close listener but now I do have one which clears the handle, in addition to a clearInterval one line above the setInterval call.

Thans all of you for leading me straight forward! Tom

1 Like