(ownerKey: string, leaseId: string)
| 414 | } |
| 415 | |
| 416 | async function releaseDistributedLease(ownerKey: string, leaseId: string): Promise<void> { |
| 417 | const redis = getRedisClient() |
| 418 | if (!redis) return |
| 419 | |
| 420 | const key = ownerRedisKey(ownerKey) |
| 421 | const script = ` |
| 422 | redis.call('ZREM', KEYS[1], ARGV[1]) |
| 423 | if redis.call('ZCARD', KEYS[1]) == 0 then |
| 424 | redis.call('DEL', KEYS[1]) |
| 425 | end |
| 426 | return 1 |
| 427 | ` |
| 428 | |
| 429 | let deadlineTimer: NodeJS.Timeout | undefined |
| 430 | const deadline = new Promise<never>((_, reject) => { |
| 431 | deadlineTimer = setTimeout( |
| 432 | () => reject(new Error(`Redis lease release timed out after ${LEASE_REDIS_DEADLINE_MS}ms`)), |
| 433 | LEASE_REDIS_DEADLINE_MS |
| 434 | ) |
| 435 | }) |
| 436 | |
| 437 | try { |
| 438 | await Promise.race([redis.eval(script, 1, key, leaseId), deadline]) |
| 439 | } catch (error) { |
| 440 | logger.error('Failed to release distributed owner lease', { ownerKey, error }) |
| 441 | } finally { |
| 442 | clearTimeout(deadlineTimer) |
| 443 | } |
| 444 | } |
| 445 | |
| 446 | function queueLength(): number { |
| 447 | return queueSize |
no test coverage detected