1

I'm creating a program where I constantly run and stop async code, but I need a good way to stop the code.

Currently, I have tried to methods:

Method 1:

When a method is running, and another method is called to stop the first method, I start an infinite loop to stop that code from running and then remove the method from the queue(array)

I'm 100% sure that this is the worst way to accomplish it, and it works very buggy.

Code:

class test{
    async Start(){
         const response = await request(options);
         if(stopped){
             while(true){
                 await timeout(10)
             }
         }
    }
}

Code 2:

var tests = [];

Start(){
    const test = new test();
    tests.push(test)
    tests.Start();
}

Stop(){
    tests.forEach((t, i) => {t.stopped = true;};
    tests = [];
}

Method 2:

I load the different methods into Workers, and when I need to stop the code, I just terminate the Worker.

It always takes a lot of time(1 sec) to create the Worker, and therefore not the best way, since I need the code to run without 1-2 sec pauses.

Code:

const Worker = require("tiny-worker");
const code = new Worker(path.resolve(__dirname, "./Code/Code.js"))   

Stopping:

code.terminate()

Is there any other way that I can stop async code?

The program contains Request using nodejs Request-promise module, so program is waiting for requests, it's hard to stop the code without one of the 2 methods.

6
  • Please put the code in the question. Along with current and expected output. stackoverflow.com/help/how-to-ask Commented Jul 11, 2019 at 8:48
  • The first approach would not work at all. If the request is "hanging" your code won't even hit the next line: async function is suspended awaiting the promise to be settled. Commented Jul 11, 2019 at 9:06
  • What's wrong with just if(stopped){//do nothing}? You can't stop a request once it is sent, the sever will process your request anyway. What you can do is simply ignore the response. Commented Jul 11, 2019 at 9:14
  • Can we see the ACTUAL asynchronous operation you're trying to stop. This and your other question today both sound like you don't understand the event-driven model of Javascript/node.js and thus you're trying to code something that is very contra to the core model of Javascript. If we can see the actual problem you're trying to solve with the actual code for the actual asynchronous requests, perhaps we'd have a better idea of offering suggestions for how to best fit that into the node.js model. Posting pseudo-code in your question leads to pseudo-answers. Real code leads to real answers. Commented Jul 12, 2019 at 21:39
  • When a method is running, and another method is called to stop the first method, I start an infinite loop to stop that code from running and then remove the method from the queue(array). This sure sounds like the wrong approach for Javascript/node.js. But, until we can see the actual asynchronous operations and the actual problem you're trying to solve with them, we can't make a good suggestion for how to do it that is compatible with Javascript/node.js. Commented Jul 12, 2019 at 21:44

2 Answers 2

4

Is there any other way that I can stop async code?

Keep in mind the basic of how Nodejs works. I think there is some misunderstanding here.

It execute the actual function in the actual context, if encounters an async operation the event loop will schedule it's execetution somewhere in the future. There is no way to remove that scheduled execution.

More info on event loop here.

In general for manage this kind of situations you shuold use flags or semaphores.

The program contains Request using nodejs Request-promise module, so program is waiting for requests, it's hard to stop the code

If you need to hard "stop the code" you can do something like

func stop() {
    process.exit()
}

But if i'm getting it right, you're launching requests every x time, at some point you need to stop sending the request without managing the response.

You can't de-schedule the response managemente portion, but you can add some logic in it to (when it will be runned) check if the "request loop" has been stopped.

let loop_is_stopped = false
let sending_loop = null

func sendRequest() {
    const response = await request(options) // "wait here"
    // following lines are scheduled after the request promise is resolved
    if (loop_is_stopped) {
        return
    }
    // do something with the response
}

func start() {
    sending_loop = setInterval(sendRequest, 1000)
}

func stop() {
    loop_is_stopped = true
    clearInterval(sending_loop)
}

module.exports = { start, stop }
Sign up to request clarification or add additional context in comments.

Comments

0

We can use Promise.all without killing whole app (process.exit()), here is my example (you can use another trigger for calling controller.abort()):

const controller = new AbortController();

class Workflow {
  static async startTask() {
    await new Promise((res) => setTimeout(() => {
      res(console.log('RESOLVE'))
    }, 3000))
  }
}

class ScheduleTask {
  static async start() {
    return await Promise.all([
      new Promise((_res, rej) => { if (controller.signal.aborted) return rej('YAY') }),
      Workflow.startTask()
    ])
  }
}

setTimeout(() => {
  controller.abort()
  console.log("ABORTED!!!");
}, 1500)

const run = async () => {
  try {
    await ScheduleTask.start()
    console.log("DONE")
  } catch (err) {
    console.log("ERROR", err.name)
  }
}
run()
// ABORTED!!!
// RESOLVE

"DONE" will never be showen.

res will be complited

Maybe would be better to run your code as script with it's own process.pid and when we need to interrupt this functionality we can kill this process by pid in another place of your code process.kill.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.