I have a django backend and I'm trying to poll the status of multiple Celery Tasks (https://docs.celeryq.dev/en/stable/index.html) every 3 seconds.
So for example I have 4 task ids:
- 3099023
- 3493494
- 4309349
- 5498458
So I have to call http.get<...>(backend) every 3 seconds 4 times with each id, until the state of a id is "FINISHED". This should stop the poll of the finished task.
Is there a simple way to do that?
I was trying to do that in a for loop:
- Iterating through my ids
- Create a timer for each id
- In each timer poll the id with a backend http call
- Continue if response of the http call is not finished - otherwise stop
CodePudding user response:
I think that we can do something better using rxjs, this is an example of using rxjs operators to achieve your goal.
NOTE: This is just an example without Components/Services to make the things simple in the example.
import { interval, of, mergeMap, from, switchMap, takeWhile } from 'rxjs';
const ids = [3099023, 3493494, 4309349, 5498458];
from(ids).pipe(
mergeMap((id) =>
interval(3000).pipe(
switchMap((val) => mockHttpCallExample(val, id)),
takeWhile((httpResonse) => httpResonse !== 'FINISHED')
))).subscribe(val => console.log(val))
const mockHttpCallExample = (val, id) => {
let httpResponse;
if (id % 2 === 0 && val === 4) {
httpResponse = 'FINISHED'
} else if (id % 2 !== 0 && val === 5) {
httpResponse = 'FINISHED'
} else {
httpResponse = 'OK'
}
console.log(id, val);
return of(httpResponse)
}
What are we doing here:
- With the from operator, we are emitting a value for each id
- In the mergeMap, every 3s we are making an http request to the API
- The process will end when we receive the 'FINISHED' string from the mock API call