* Release a distributed lock * @param lockName - Name of the lock * @param lockId - Lock identifier returned when acquiring the lock * @returns Promise - Whether the lock was successfully released
(lockName: string, lockId: string)
| 183 | * @returns Promise<boolean> - Whether the lock was successfully released |
| 184 | */ |
| 185 | async release(lockName: string, lockId: string): Promise<boolean> { |
| 186 | try { |
| 187 | const cacheManager = await getCacheManager(); |
| 188 | const lockKey = `${this.options.prefix}:${lockName}`; |
| 189 | |
| 190 | const existingLock = await cacheManager.get(lockKey); |
| 191 | if (existingLock) { |
| 192 | const parsedLock = JSON.parse(String(existingLock)); |
| 193 | |
| 194 | // Only release if we own the lock |
| 195 | if (parsedLock.id === lockId) { |
| 196 | await cacheManager.delete(lockKey); |
| 197 | logger.debug( |
| 198 | `[DistributedLock] Successfully released lock: ${lockName}` |
| 199 | ); |
| 200 | return true; |
| 201 | } else { |
| 202 | logger.warn( |
| 203 | `[DistributedLock] Cannot release lock ${lockName}: lock is owned by different process (${parsedLock.id} vs ${lockId})` |
| 204 | ); |
| 205 | return false; |
| 206 | } |
| 207 | } else { |
| 208 | logger.debug( |
| 209 | `[DistributedLock] Lock ${lockName} was already released or expired` |
| 210 | ); |
| 211 | return true; |
| 212 | } |
| 213 | } catch (error) { |
| 214 | logger.error( |
| 215 | `[DistributedLock] Error releasing lock ${lockName}:`, |
| 216 | error |
| 217 | ); |
| 218 | return false; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | /** |
| 223 | * Execute a function with a distributed lock |
no test coverage detected