-
Notifications
You must be signed in to change notification settings - Fork 4
/
AsyncTaskQueue.js
49 lines (42 loc) · 1.59 KB
/
AsyncTaskQueue.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { getTimestamp } from 'source/common/time'
import { createAsyncFuncQueue } from './AsyncFuncQueue'
import { ASYNC_TASK_KEY_MAP, runAsyncTask } from './AsyncTask'
const { PLAN_PROMISE, OUTPUT } = ASYNC_TASK_KEY_MAP
const STATUS = 'status'
const ASYNC_TASK_QUEUE_KEY_MAP = {
...ASYNC_TASK_KEY_MAP,
STATUS
}
// ## AsyncTaskQueue ##
// better for maintain long running work or resource heavy process
// add status with basic time mark
const createAsyncTaskQueue = () => {
const { getLength, reset, push: pushAsyncFunc } = createAsyncFuncQueue()
const push = (asyncTask) => {
asyncTask[ STATUS ] = { // always assign a new state
pushAt: getTimestamp(), // in second
runAt: undefined, // in second
doneAt: undefined // in second
}
return pushAsyncFunc(() => {
asyncTask[ STATUS ].runAt = getTimestamp()
const promise = runAsyncTask(asyncTask)
const onTaskDone = () => { asyncTask[ STATUS ].doneAt = getTimestamp() }
asyncTask[ PLAN_PROMISE ].then(onTaskDone, onTaskDone) // this will run before asyncTask[ PROMISE ], so both OUTPUT and STATUS data can be ready for done phase
return promise // pass to outer code
})
}
return { getLength, reset, push }
}
const createFilterStaleAsyncTask = (
maxStaleTime, // in second (set 600 to filter task ended for >=10min)
maxDoneAt = getTimestamp() - Math.abs(maxStaleTime)
) => (asyncTask) => (
!asyncTask[ OUTPUT ] || // task is not done
asyncTask[ STATUS ].doneAt > maxDoneAt // not match time range
)
export {
ASYNC_TASK_QUEUE_KEY_MAP,
createAsyncTaskQueue,
createFilterStaleAsyncTask
}