(
lockDir: string,
input: { key: string; onWait?: Wait; signal?: AbortSignal },
opts: Opts,
)
| 272 | } |
| 273 | |
| 274 | async function acquireLockDir( |
| 275 | lockDir: string, |
| 276 | input: { key: string; onWait?: Wait; signal?: AbortSignal }, |
| 277 | opts: Opts, |
| 278 | ) { |
| 279 | const stop = mono() + opts.timeoutMs |
| 280 | let attempt = 0 |
| 281 | let waited = 0 |
| 282 | let delay = opts.baseDelayMs |
| 283 | |
| 284 | while (true) { |
| 285 | input.signal?.throwIfAborted() |
| 286 | |
| 287 | const res = await tryAcquireLockDir(lockDir, opts) |
| 288 | if (res.acquired) { |
| 289 | return res |
| 290 | } |
| 291 | |
| 292 | if (mono() > stop) { |
| 293 | throw new Error(`Timed out waiting for lock: ${input.key}`) |
| 294 | } |
| 295 | |
| 296 | attempt += 1 |
| 297 | const ms = jitter(delay) |
| 298 | await input.onWait?.({ |
| 299 | key: input.key, |
| 300 | attempt, |
| 301 | delay: ms, |
| 302 | waited, |
| 303 | }) |
| 304 | await sleep(ms, input.signal) |
| 305 | waited += ms |
| 306 | delay = Math.min(opts.maxDelayMs, Math.floor(delay * 1.7)) |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | export async function acquire(key: string, input: Options = {}): Promise<Lease> { |
| 311 | input.signal?.throwIfAborted() |
no test coverage detected