Skip to content

Commit e18b572

Browse files
committed
fix(core): Wrong ignore of source libraries
1 parent 4e61243 commit e18b572

File tree

3 files changed

+168
-1
lines changed

3 files changed

+168
-1
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ typings/
6666

6767
dist/
6868
bin/
69-
lib/
7069
docs/
7170
.coveralls.yml
7271
tags

src/lib/queue.js

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { findWith, last, is, isEmpty } from "@asd14/m"
2+
import isDeepEqual from "fast-deep-equal"
3+
4+
/**
5+
* Unique, sequential, promise based queue
6+
*
7+
* @example
8+
* const queue = buildQueue()
9+
*
10+
* queue.enqueue(Users.login, {
11+
* args:{
12+
* body: {email: "lorem@test.com", password: "secret"}
13+
* }
14+
* })
15+
* .then(...)
16+
* .catch(...)
17+
*
18+
* @returns {object<enqueue, dequeue>}
19+
*/
20+
export const buildQueue = () => {
21+
const jobsList = []
22+
let isProcessing = false
23+
24+
return {
25+
enqueue({ id, fn, args }) {
26+
const runningJob = findWith({
27+
id,
28+
args: source => isDeepEqual(source, args),
29+
})(jobsList)
30+
31+
if (is(runningJob)) {
32+
return runningJob.fnPromise
33+
}
34+
35+
let deferredResolve = null
36+
let deferredReject = null
37+
const fnResultPromise = new Promise((resolve, reject) => {
38+
deferredResolve = resolve
39+
deferredReject = reject
40+
})
41+
42+
// add job at begining of queue
43+
jobsList.unshift({
44+
id,
45+
args,
46+
fn,
47+
fnResultPromise,
48+
onResolve: results => {
49+
deferredResolve(results)
50+
},
51+
onReject: error => {
52+
deferredReject(error)
53+
},
54+
})
55+
56+
// start processing jobs
57+
this.dequeue()
58+
59+
// return promise that will be resolved after fn is called and resolved
60+
return fnResultPromise
61+
},
62+
63+
dequeue() {
64+
const shouldStartRunningJobs = !isProcessing && !isEmpty(jobsList)
65+
66+
if (!shouldStartRunningJobs) {
67+
return undefined
68+
}
69+
70+
const { fn, args, onResolve, onReject } = last(jobsList)
71+
72+
// no jobs will be started until current one finishes
73+
isProcessing = true
74+
75+
return Promise.resolve()
76+
.then(() => {
77+
// Need to remove ourselves before job.fn resolves. If another
78+
// action of the same signature runs right after it will return this
79+
// job because job still exists in queue
80+
jobsList.pop()
81+
82+
return fn(...args)
83+
})
84+
.then(onResolve)
85+
.catch(onReject)
86+
.finally(() => {
87+
// process next in queue
88+
isProcessing = false
89+
this.dequeue()
90+
})
91+
},
92+
}
93+
}

src/lib/queue.test.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* eslint-disable no-loop-func */
2+
import test from "tape"
3+
import { map } from "@asd14/m"
4+
5+
import { buildQueue } from "./queue"
6+
7+
test("Promise Queue - Promise based unique elements queue", t => {
8+
const queue = buildQueue()
9+
10+
let findCountBatch1 = 0
11+
let findDateBatch1 = null
12+
let findCountBatch2 = 0
13+
let findDateBatch2 = null
14+
15+
const jobs = [
16+
// add job with same arguments
17+
...map(() =>
18+
queue.enqueue({
19+
fn: () => {
20+
findCountBatch1++
21+
findDateBatch1 = new Date()
22+
23+
return new Promise(resolve => {
24+
setTimeout(() => {
25+
resolve([{ id: 1, name: "test" }])
26+
}, 100)
27+
})
28+
},
29+
args: [
30+
{
31+
path: "/todos",
32+
query: { limit: 10 },
33+
},
34+
],
35+
})
36+
)([1, 2, 3, 4, 5]),
37+
// add job with different arguments
38+
...map(() =>
39+
queue.enqueue({
40+
fn: () => {
41+
findCountBatch2++
42+
findDateBatch2 = new Date()
43+
44+
return new Promise(resolve => {
45+
setTimeout(() => {
46+
resolve([{ id: 1, name: "test" }])
47+
}, 100)
48+
})
49+
},
50+
args: [
51+
{
52+
path: "/todos",
53+
query: { limit: 20 },
54+
},
55+
],
56+
})
57+
)([1, 2, 3, 4, 5]),
58+
]
59+
60+
Promise.all(jobs).then(() => {
61+
t.equals(
62+
findCountBatch1 === 1 && findCountBatch2 === 1,
63+
true,
64+
"Same signature jobs enqueued at the same times should run once"
65+
)
66+
67+
t.equals(
68+
findDateBatch1 < findDateBatch2,
69+
true,
70+
"Different signature jobs should run sequentially"
71+
)
72+
73+
t.end()
74+
})
75+
})

0 commit comments

Comments
 (0)