Есть ли какой-нибудь программный c способ разбить бесконечный l oop в NodeJS? - PullRequest
1 голос
/ 10 марта 2020

В конечном счете - существует ли практический метод (также, возможно, путем вставки некоторых конструкций JS в код), чтобы сломать или остановить длительный код JS во время выполнения? Например: может ли он быть прерван некоторыми process.* объектными конструкциями или подобными? Или другой путь? Действительное решение может даже включать процесс NodeJS, который нужно убить и / или перезапустить. Спасибо!

РЕДАКТИРОВАТЬ: Мне нужно выполнить какой-то определенный код пользователя на сервере, используя предложение Function (ala eval, не говоря уже о проблемах безопасности). Я не могу вставить какой-либо дополнительный код внутри него, только приложить его. Мне нужно иметь возможность взломать пользовательский код через 5 минут, если он не завершен к этому времени. Например:

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

1 Ответ

1 голос
/ 10 марта 2020

Редактировать:

Отвечая на ваши изменения. Теперь я вижу намерение. Если он работает в nodejs, вы можете использовать для этого значение worker_thread 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/Worker WebAPI не совсем такой же, но логика c должна быть похожа

Оригинал

Уничтожение процесса. Также прочитайте: https://nodejs.org/api/process.html#process_signal_events

process.kill(pid, "SIGINT")

«Убивая» функцию длительного выполнения, вам нужно немного взломать. Там нет элегантного решения. Введите контроллер, который может быть видоизменен за пределами функции длительного действия. Чтобы остановить его снаружи, установите 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/3824ca4ce1be390d34c5147db671cc9b

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...