git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 864bc27090fe788a4bf5a86c00246ca6e4391dd0

Files: 864bc27090fe788a4bf5a86c00246ca6e4391dd0 / scheduler.js

1844 bytesRaw
1const binarySearchInsert = require('binary-search-insert')
2
3const comparator = function (a, b) {
4 return a.ticks - b.ticks
5}
6
7module.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