Files: 864bc27090fe788a4bf5a86c00246ca6e4391dd0 / scheduler.js
1844 bytesRaw
1 | const binarySearchInsert = require('binary-search-insert') |
2 | |
3 | const comparator = function (a, b) { |
4 | return a.ticks - b.ticks |
5 | } |
6 | |
7 | module.exports = class Scheduler { |
8 | constructor () { |
9 | this._waits = [] |
10 | this.instances = new Map() |
11 | this.locks = new Set() |
12 | } |
13 | |
14 | getLock () { |
15 | const id = Symbol('lock') |
16 | this.locks.add(id) |
17 | return id |
18 | } |
19 | |
20 | releaseLock (id) { |
21 | this.locks.delete(id) |
22 | } |
23 | |
24 | update (instance) { |
25 | this.instances.delete(instance.id) |
26 | const instanceArray = [...this.instances] |
27 | binarySearchInsert(instanceArray, comparator, [instance.id, { |
28 | ticks: instance.ticks, |
29 | instance: instance |
30 | }]) |
31 | this.instances = new Map(instanceArray) |
32 | this._checkWaits() |
33 | } |
34 | |
35 | getInstance (id) { |
36 | const item = this.instances.get(id) |
37 | if (item) { |
38 | return item.instance |
39 | } |
40 | } |
41 | |
42 | done (instance) { |
43 | this.instances.delete(instance.id) |
44 | this._checkWaits() |
45 | } |
46 | |
47 | wait (ticks = Infinity) { |
48 | if (!this.locks.size && ticks <= this.smallest()) { |
49 | return |
50 | } else { |
51 | return new Promise((resolve, reject) => { |
52 | binarySearchInsert(this._waits, comparator, { |
53 | ticks: ticks, |
54 | resolve: resolve |
55 | }) |
56 | }) |
57 | } |
58 | } |
59 | |
60 | smallest () { |
61 | return [...this.instances][0][1].ticks |
62 | } |
63 | |
64 | _checkWaits () { |
65 | if (!this.locks.size) { |
66 | if (!this.isRunning()) { |
67 | // clear any remanding waits |
68 | this._waits.forEach(wait => wait.resolve()) |
69 | this._waits = [] |
70 | } else { |
71 | const smallest = this.smallest() |
72 | for (const index in this._waits) { |
73 | const wait = this._waits[index] |
74 | if (wait.ticks <= smallest) { |
75 | wait.resolve() |
76 | } else { |
77 | this._waits.splice(0, index) |
78 | break |
79 | } |
80 | } |
81 | } |
82 | } |
83 | } |
84 | |
85 | isRunning () { |
86 | return this.instances.size |
87 | } |
88 | } |
89 |
Built with git-ssb-web