是否有任何编程方法可以打破 NodeJS 中的无限循环? [英] Is there any programmatic way to break infinite loop in NodeJS?

查看:48
本文介绍了是否有任何编程方法可以打破 NodeJS 中的无限循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

归根结底 - 有没有一种实用的方法(也可能是通过在代码中插入一些 JS 构造)来在执行过程中中断或停止持久的 JS 代码?例如:它可以被某些 process.* 对象结构或类似结构中断吗?还是另一种方式?有效的解决方案甚至可能包括要终止和/或重新启动的 NodeJS 进程.谢谢!

Ultimately speaking - is there a practical method (also maybe by inserting some JS constructs into the code) to break or halt the long lasting JS code during the execution? For example: can it be interrupted by some process.* object constructs, or similar? Or the other way? The valid solution may even include the NodeJS process to be killed and/or restarted. Thank you!

我需要在服务器上执行一些特定的用户代码,使用 Function 子句(ala eval,更不用说安全问题了).我不能在里面插入任何额外的代码,只能附上它.我需要的是有可能在 5 分钟后破坏用户代码,如果此时还没有完成.例如:

I need to execute some particular user code on the server, using Function clause (ala eval, - let alone security concerns). I cannot insert any extra code inside it, only enclose it. What I need is to have a possibility to break user code after 5 minutes, if it is not finished by this time. For example:

usercode = 'Some code from the user';
pre_code = 'some controlling code for breaking the user code';
post_code = 'another controlling code';

fcode = pre_code + usercode + post_code;

<preparations for breaking usercode>

(new Function(fcode))(); // This MUST exit in 5 minutes

推荐答案

回答您的编辑.我现在看到了意图.如果它在 nodejs 中运行,您可以使用 worker_thread 来实现 https://nodejs.org/api/worker_threads.html#worker_threads_worker_workerdata.

Answering your edit. I see the intention now. If it is running in nodejs, you can use worker_thread for that https://nodejs.org/api/worker_threads.html#worker_threads_worker_workerdata.

例如:

// main.js
const runCode = (code) => { 
  const worker = new Worker("./code-executor.js", { workerData: { code: guestCode } });
  const promise = new Promise((resolve) => {
    setTimeout(() => worker.kill(), 60000 * 5);
    worker.on("error", () => {
      return reject(new SomeCustomError())
    });
    worker.on("message", (message) => {
      if(message.success) return resolve(message.result);
      return reject(new Error(message.error));
    });
  });

  promise.finally(() => { worker.kill() });

  return promise;
}

// code-executor.js

const { workerData, parentPort } = require("worker_threads");
const { code } = workerData;

Promise.resolve()
 .then(() => (new Function(fcode))())
 .then((result) => {
   parentPort.postMessage({
     success: true,
     result: value
   })
 })
 .catch((error) => {
   parentPort.postMessage({
     success: true,
     error: error.message
   })
 });

如果它在浏览器中 https://developer.mozilla.org/en-US/docs/Web/API/WorkerWebAPI 不完全一样,但逻辑应该是相似的

If it's in browser https://developer.mozilla.org/en-US/docs/Web/API/Worker The WebAPI is not exactly the same but the logic should be similar

原创

杀死一个进程.另请阅读:https://nodejs.org/api/process.html#process_signal_events

Killing a process. Also read: https://nodejs.org/api/process.html#process_signal_events

process.kill(pid, "SIGINT")

杀死"一个长时间运行的函数,你需要破解一下.没有优雅的解决方案.注入一个可以在长时间运行的函数之外进行变异的控制器.要从外部停止它,请设置 controller.isStopped = true

"Killing" a long running function, you gotta hack a bit. There's no elegant solution. Inject a controller which can be mutated outside of the long running function. To stop it from the outside, set controller.isStopped = true


export const STOP_EXECUTION = Symbol();

function longRunning(controller){
  ... codes

  // add stopping point
  if(controller.isStopped) throw STOP_EXECUTION;

  ... codes

  // add stopping point
  if(controller.isStopped) throw STOP_EXECUTION;

  ... codes
}

// catch it by 

try{
  longRunnning();
}catch(e){
  switch(true){
    e === STOP_EXECUTION: ...;  // the longRunning function is stopped from the outside
    default: ...;               // the longRunning function is throwing not because of being stopped 

  }
}

要点:https://gist.github.com/Kelerchian/3824ca4ce1be390d34b71>cc

Gist: https://gist.github.com/Kelerchian/3824ca4ce1be390d34c5147db671cc9b

这篇关于是否有任何编程方法可以打破 NodeJS 中的无限循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆