feat: complete WorkBuddy parity and Windows release workflow
This commit is contained in:
1 parent
143516b3a8
commit
d5512df549
434 files changed
+54977
-1854
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { promises as fs } from 'node:fs'
|
||||
import { assertActive } from './policy'
|
||||
|
||||
interface Waiting { workspace: string; start(): void; cancel(): void }
|
||||
const queue: Waiting[] = [], busy = new Set<string>()
|
||||
const maximumActive = 4, maximumQueued = 32
|
||||
function drain(): void {
|
||||
for (let index = 0; index < queue.length && busy.size < maximumActive;) {
|
||||
const item = queue[index]
|
||||
if (busy.has(item.workspace)) { index++; continue }
|
||||
queue.splice(index, 1); busy.add(item.workspace); item.start()
|
||||
}
|
||||
}
|
||||
/** A workspace snapshot observes the previous approved commit, never a concurrent stale copy. */
|
||||
export async function withSandboxExecution<T>(root: string, signal: AbortSignal | undefined, operation: (canonicalRoot: string) => Promise<T>): Promise<T> {
|
||||
assertActive(signal)
|
||||
const real = await fs.realpath(root), workspace = process.platform === 'win32' ? real.toLowerCase() : real
|
||||
if (queue.length >= maximumQueued || queue.filter(item => item.workspace === workspace).length >= 8) throw new Error('沙盒执行队列已满,请稍后重试')
|
||||
return new Promise<T>((done, reject) => {
|
||||
const item: Waiting = {
|
||||
workspace,
|
||||
start() {
|
||||
signal?.removeEventListener('abort', item.cancel)
|
||||
Promise.resolve().then(() => { assertActive(signal); return operation(real) }).then(done, reject).finally(() => { busy.delete(workspace); drain() })
|
||||
},
|
||||
cancel() {
|
||||
const index = queue.indexOf(item)
|
||||
if (index < 0) return
|
||||
queue.splice(index, 1); signal?.removeEventListener('abort', item.cancel)
|
||||
reject(Object.assign(new Error('排队中的沙盒执行已取消'), { name: 'AbortError' }))
|
||||
}
|
||||
}
|
||||
queue.push(item)
|
||||
signal?.addEventListener('abort', item.cancel, { once: true })
|
||||
if (signal?.aborted) item.cancel()
|
||||
drain()
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user