ncsoft / Unreal.js

Unreal.js: Javascript runtime built for UnrealEngine
Other
3.66k stars 348 forks source link

process.nextTick and setInterval continue to run after hotloading #208

Open mcclure opened 6 years ago

mcclure commented 6 years ago

Example 1:

Put this script in game.js, attach it as a ScriptComponent to an object:

let filename = "game";
if (typeof (module) == 'undefined') {
    require('bootstrap')(filename);
} else {
    module.exports = () => {
        let run = 1
        let count = 0
        function tick() {
            console.log("Pass", run, "Tick", count)
            count++
            process.nextTick(tick)
        }
        process.nextTick(tick);

        return () => {
            console.log("CLEANUP")
        };
    }
}

Run the script. Then change the value of run to 2 and save. Unreal.JS will hotload the new script value. Now look in the console. It will be interleaving "pass 1" and "pass 2" prints.

Example 2:

Put this script in game.js, attach it as a ScriptComponent to an object:

let filename = "game";
if (typeof (module) == 'undefined') {
    require('bootstrap')(filename);
} else {
    module.exports = () => {
        let run = 3
        let count = 0
        function tick() {
            console.log("Pass", run, "Tick", count)
            count++
        }
        setInterval(tick, 1000.0 / 20.0 )

        return () => {
            console.log("CLEANUP")
        };
    }
}

Run the script. Then change the value of run to 3 and save. Unreal.JS will hotload the new script value. Now look in the console. It will be interleaving "pass 1" and "pass 2" prints.

Observed behavior:

In both cases, the callback requested by the script triggers even though the script has been formally "unloaded".

Expected behavior:

In my opinion setInterval and nextTick requests issued by a script should be cut off after their disposal functions are called, since they might use resources which the cleanup script erased.

thejustinwalsh commented 6 years ago

setInterval has a companion function clearInterval. You could store off the id returned by setInterval and call clearInterval in your script.

It would probably be pretty difficult to stop process.nextTick from firing in any sane way. since setInterval / clearInterval produces a good pattern I would just use that instead.