I have a controller on nestjs that is writing a job to the queue.
The job processing suppose to last between 100MS to 5000MS.
I don't want to disconnect the client until I have the answer.
How can I do that and not running a while loop? write now I have this very bad code:
@Post('job')
async job(@Body() request): Promise<JobRes>{
const job = await this.bullQueue.add('hande', request);
while(true){ //UGLY AND BAD
const state = await job.getState();
if(state == 'completed'){
return await this.db.findByJobId(job.id);
}
await sleet(1_000);
}
}
This solution require a lot of resources from the event loop and is not safe at all.
I'm looking for a better solution to hand the request untill I have response.
Thanks
CodePudding user response:
I don't know what your request
, job
or bullQueue
is. But generally you have the following possibilities:
make the
job
to be a promise -- iebullQueue.add()
must return aPromise<Promise<T>>
or depending on whatrequest
is you may be able to turn it into a promise directly without adding it to some queue -- so you can do something like thisconst job = await this.bullQueue.add('hande', request); // const job = request.toPromise(); just some pseudo code, wrapping request into a promise await job; ...
make
job
emit an event when it's finished so you can do something like thisconst job = await this.bullQueue.add('hande', request); await new Promise(res => { //attach the event listener to job //and once the event is raised, resovle the promise job.on("completed", () =>{ res(); }); }) ...
If you cannot change the implementation of your job
you are pretty much out of luck, ie you can only wait for your condition to become fulfilled ... See @Michael Lampu answer on how to make this a bit more structured ...
CodePudding user response:
Hei!
import { setTimeout } from "timers/promises"
const abc = async()=>{
while((await job.getState())!=='completed') await setTimeout(500)
return await this.db.findByJobId(job.id);
}
This approach has little to do with mind, while will do its work. See comments.