Search code examples
node.jsasp.net-corecancellation

Is there a way to stop a script execution on Node.js using Microsoft.AspNetCore.NodeServices?


I am trying to execute some javascript on Node server, using Microsoft.AspNetCore.NodeServices, with this code:

JObject result = null;
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var scriptTimeout = 2000;

tokenSource.CancelAfter((int) scriptTimeout);

result = await _nodeServices.InvokeExportAsync<JObject>(token, "./Node/script", "run");

The InvokeExportAsync in fact provides a CancellationToken parameter that successfully kills the task, but the node process keeps consuming CPU until the script finishes.

For example, if I try to run a script that takes 10m to complete and the cancellation token kills it on 5m, I can see for more 5m the script executing and consuming CPU on task manager.


Solution

  • You should never try to terminate the node process when some task is canceled .

    The CancellationToken parameter in InvokeAsync<T>(CancellationToken cancellationToken, string moduleName, params object[] args) is not used to terminate the Node.js process , but used to cancel the .NET code that invokes those scripts written in Node.js .

    Let's say there're 3 async tasks running in Node.js:

    setTimeout(resolve, 100, 100); // task 1
    setTimeout(resolve, 200, 100); // task 2
    setTimeout(resolve, 300, 100); // task 3
    

    Now we want to cancel the 2nd task , since INodeServices is an singleton service, and JavaScript runs in single thread, if we choose to terminate the node.js process, task 1 and task 2 will also fail .

    Secondly , .NET has no idea about what should be done in Node.js when a task reaches its timeout limit. Let's say you've asked for some resources in Node.js , and you'll free the resources when task is completed. Now you're using the .NET to cancel the task, what about the resources allocated in Node.js ?

    I suggest you should wrap your Node.js code into an auto cancelable task. Because JavaScript has no cancelable promise yet, you might use a 3rd party lib or custom your own addons.