mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-11 11:43:17 +08:00
feat: add model and turn control commands
This commit is contained in:
parent
fc8f120e13
commit
99ce38e9a4
38 changed files with 3451 additions and 169 deletions
40
src/channels/shared/session-binding-lock.mjs
Normal file
40
src/channels/shared/session-binding-lock.mjs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
const bindingLocks = new WeakMap();
|
||||
|
||||
function stateLocks(state) {
|
||||
let locks = bindingLocks.get(state);
|
||||
if (!locks) {
|
||||
locks = new Map();
|
||||
bindingLocks.set(state, locks);
|
||||
}
|
||||
return locks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the short Session binding transaction for one conversation.
|
||||
* The caller must keep long-running Session work, such as ask(), outside.
|
||||
*/
|
||||
export async function withSessionBindingLock(state, key, operation) {
|
||||
const stateType = typeof state;
|
||||
if ((stateType !== 'object' && stateType !== 'function') || state === null) {
|
||||
throw new TypeError('state is required');
|
||||
}
|
||||
if (typeof key !== 'string' || !key) throw new TypeError('conversation key is required');
|
||||
if (typeof operation !== 'function') throw new TypeError('operation is required');
|
||||
|
||||
const locks = stateLocks(state);
|
||||
const previous = locks.get(key) ?? Promise.resolve();
|
||||
let release;
|
||||
const current = new Promise((resolve) => { release = resolve; });
|
||||
locks.set(key, current);
|
||||
|
||||
await previous;
|
||||
try {
|
||||
return await operation();
|
||||
} finally {
|
||||
release();
|
||||
if (locks.get(key) === current) {
|
||||
locks.delete(key);
|
||||
if (locks.size === 0) bindingLocks.delete(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue