/**
 * 同一考勤会话（session）内的互斥执行器：
 * 保证针对同一个 sessionId 的并发操作按提交顺序串行执行。
 */
export class SessionMutex {
  private queueTails = new Map<number, Promise<void>>();

  async runExclusive<T>(sessionId: number, fn: () => Promise<T>): Promise<T> {
    const tail = this.queueTails.get(sessionId) ?? Promise.resolve();
    let release!: () => void;
    const newTail = new Promise<void>((resolve) => { release = resolve; });
    this.queueTails.set(sessionId, newTail);
    await tail;
    try {
      return await fn();
    } finally {
      release();
      if (this.queueTails.get(sessionId) === newTail) {
        this.queueTails.delete(sessionId);
      }
    }
  }
}
