Skip to content

Commit

Permalink
[pledge] global context and more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dmonad committed Mar 24, 2024
1 parent 7cbd84d commit 6e45d27
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 23 deletions.
55 changes: 39 additions & 16 deletions pledge.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import * as queue from './queue.js'
import * as object from './object.js'

/**
* @type {queue.Queue<queue.QueueValue<()=>void>>}
*/
const ctxFs = queue.create()

/**
* @param {() => void} f
*/
const runInGlobalContext = f => {
const isEmpty = queue.isEmpty(ctxFs)
queue.enqueue(ctxFs, new queue.QueueValue(f))
if (isEmpty) {
while (!queue.isEmpty(ctxFs)) {
/** @type {queue.QueueValue<()=>{}>} */ (ctxFs.start).v()
queue.dequeue(ctxFs)
}
}
}

/**
* @template V
* @typedef {V | PledgeInstance<V>} Pledge
Expand Down Expand Up @@ -163,10 +183,9 @@ export const createWithDependencies = (init, ...deps) => {
*/
export const whenResolved = (p, f) => {
if (p instanceof PledgeInstance) {
p.whenResolved(f)
} else {
f(p)
return p.whenResolved(f)
}
return f(p)
}

/**
Expand All @@ -180,6 +199,20 @@ export const whenCanceled = (p, f) => {
}
}

/**
* @template P
* @template Q
* @param {Pledge<P>} p
* @param {(r: P) => Q} f
* @return {Pledge<Q>}
*/
export const map = (p, f) => {
if (p instanceof PledgeInstance) {
return p.map(f)
}
return f(p)
}

/**
* @template {PledgeMap} PS
* @param {PS} ps
Expand Down Expand Up @@ -208,18 +241,6 @@ export const all = ps => {
return pall
}

/**
* @template T
* @param {Pledge<T>} p
* @param {function(T):Pledge<T>} f
*/
export const map = (p, f) => {
if (p instanceof PledgeInstance) {
return p.map(f)
}
return f(p)
}

/**
* @template Result
* @template {any} YieldResults
Expand All @@ -242,7 +263,9 @@ export const coroutine = f => {
whenCanceled(res.value, (reason) => {
gen.throw(reason)
})
whenResolved(res.value, handleGen)
runInGlobalContext(() =>
whenResolved(res.value, handleGen)
)
}
handleGen()
return p
Expand Down
39 changes: 32 additions & 7 deletions pledge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,62 @@ export const testPledgeCoroutine = async _tc => {
* @param {t.TestCase} _tc
*/
export const testPledgeVsPromisePerformanceTimeout = async _tc => {
const iterations = 1000
const iterations = 25000
const waitTime = 0
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (promise)`, async () => {
for (let i = 0; i < iterations; i++) {
await promise.wait(waitTime)
}
})
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (pledge)`, () =>
pledge.coroutine(function * () {
for (let i = 0; i < iterations; i++) {
yield pledge.wait(waitTime)
}
}).promise()
)
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (promise)`, async () => {
for (let i = 0; i < iterations; i++) {
await promise.wait(waitTime)
}
})
}

/**
* @typedef {Promise<number> | number} MaybePromise
*/

/**
* @param {t.TestCase} _tc
*/
export const testPledgeVsPromisePerformanceResolved = async _tc => {
const iterations = 100000
const iterations = 25000
t.measureTime(`Awaiting ${iterations} callbacks (only iterate)`, () => {
for (let i = 0; i < iterations; i++) { /* nop */ }
})
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (promise)`, async () => {
for (let i = 0; i < iterations; i++) {
await promise.resolve(0)
}
})
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (await, no resolve)`, async () => {
for (let i = 0; i < iterations; i++) {
/**
* @type {Promise<number> | number}
*/
const x = 0
await x
}
})
await t.measureTimeAsync(`Awaiting ${iterations} callbacks (pledge)`, () =>
pledge.coroutine(function * () {
for (let i = 0; i < iterations; i++) {
yield 0
}
}).promise()
)
t.measureTime(`Awaiting ${iterations} callbacks (pledge, manual wrap)`, () => {
/**
* @type {pledge.Pledge<number>}
*/
let val = 0
for (let i = 0; i < iterations; i++) {
val = pledge.map(val, _v => 0)
}
})
}

0 comments on commit 6e45d27

Please sign in to comment.