MCPcopy
hub / github.com/msgbyte/tianji / acquire

Method acquire

src/server/cache/distributedLock.ts:78–177  ·  view source on GitHub ↗

* Acquire a distributed lock * @param lockName - Name of the lock * @param options - Override default options for this specific lock * @returns Promise

(
    lockName: string,
    options?: Partial<DistributedLockOptions>
  )

Source from the content-addressed store, hash-verified

76 * @returns Promise<LockResult>
77 */
78 async acquire(
79 lockName: string,
80 options?: Partial<DistributedLockOptions>
81 ): Promise<LockResult> {
82 const opts = { ...this.options, ...options };
83 const cacheManager = await getCacheManager();
84 const lockKey = `${opts.prefix}:${lockName}`;
85 const lockId = nanoid();
86 const lockValue = {
87 id: lockId,
88 acquiredAt: Date.now(),
89 acquiredBy: process.pid.toString(), // Use process ID as identifier
90 };
91
92 let retries = 0;
93 const maxRetries = opts.skipOnFailure ? 1 : opts.maxRetries;
94
95 while (retries < maxRetries) {
96 try {
97 // Try to acquire the lock
98 const existingLock = await cacheManager.get(lockKey);
99
100 if (!existingLock) {
101 // Lock is available, try to acquire it
102 await cacheManager.set(
103 lockKey,
104 JSON.stringify(lockValue),
105 opts.timeout
106 );
107
108 await sleep(Math.random() * 100); // NOTICE: avoid setting too quickly to conflict
109
110 // Verify we actually got the lock (handle race conditions)
111 const verifyLock = await cacheManager.get(lockKey);
112 if (verifyLock) {
113 const parsedLock = JSON.parse(String(verifyLock));
114 if (parsedLock.id === lockId) {
115 logger.debug(
116 `[DistributedLock] Successfully acquired lock: ${lockName}`
117 );
118
119 return {
120 acquired: true,
121 lockId,
122 release: async () => {
123 await this.release(lockName, lockId);
124 },
125 };
126 }
127 }
128 } else {
129 // Check if the existing lock has expired
130 const parsedLock = JSON.parse(String(existingLock));
131 const lockAge = Date.now() - parsedLock.acquiredAt;
132
133 if (lockAge > opts.timeout) {
134 // Lock has expired, try to clean it up and retry
135 logger.warn(

Callers 1

withLockMethod · 0.95

Calls 11

releaseMethod · 0.95
sleepFunction · 0.90
getCacheManagerFunction · 0.85
nowMethod · 0.80
toStringMethod · 0.80
parseMethod · 0.80
debugMethod · 0.80
warnMethod · 0.80
errorMethod · 0.80
getMethod · 0.65
deleteMethod · 0.65

Tested by

no test coverage detected