diff --git a/src/client/datascience/crossProcessLock.ts b/src/client/datascience/crossProcessLock.ts deleted file mode 100644 index e738ec9b9186..000000000000 --- a/src/client/datascience/crossProcessLock.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { promises } from 'fs'; -import { tmpdir } from 'os'; -import * as path from 'path'; -import { traceError } from '../common/logger'; -import { sleep } from '../common/utils/async'; - -export class CrossProcessLock { - private lockFilePath: string; - private acquired: boolean = false; - - constructor(mutexName: string) { - this.lockFilePath = path.join(tmpdir(), `${mutexName}.tmp`); - } - - public async lock(): Promise { - const maxTries = 50; - let tries = 0; - while (!this.acquired && tries < maxTries) { - try { - await this.acquire(); - if (this.acquired) { - return true; - } - await sleep(100); - } catch (err) { - // Swallow the error and retry - traceError(err); - } - tries += 1; - } - return false; - } - - public async unlock() { - // Does nothing if the lock is not currently held - if (this.acquired) { - try { - // Delete the lockfile - await promises.unlink(this.lockFilePath); - this.acquired = false; - } catch (err) { - traceError(err); - } - } else { - throw new Error('Current process attempted to release a lock it does not hold'); - } - } - - /* - One of the few atomicity guarantees that the node fs module appears to provide - is with fs.open(). With the 'wx' option flags, open() will error if the - file already exists, which tells us if it was already created in another process. - Hence we can use the existence of the file as a flag indicating whether we have - successfully acquired the right to create the keyfile. - */ - private async acquire() { - try { - await promises.open(this.lockFilePath, 'wx'); - this.acquired = true; - } catch (err) { - if (err.code !== 'EEXIST') { - throw err; - } - } - } -} diff --git a/src/test/datascience/crossProcessLock.unit.test.ts b/src/test/datascience/crossProcessLock.unit.test.ts deleted file mode 100644 index 46c757c0f12f..000000000000 --- a/src/test/datascience/crossProcessLock.unit.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { assert } from 'chai'; -import { sleep } from '../../client/common/utils/async'; -import { CrossProcessLock } from '../../client/datascience/crossProcessLock'; - -suite('Cross process lock', async () => { - let mutex1: CrossProcessLock; - let mutex2: CrossProcessLock; - - suiteSetup(() => { - // Create two named mutexes with the same name - mutex1 = new CrossProcessLock('crossProcessLockUnitTest'); - mutex2 = new CrossProcessLock('crossProcessLockUnitTest'); - }); - - suiteTeardown(async () => { - // Delete the lockfile so it's clean for the next run - // Note that mutex2 should not have been acquired so there's no need to unlock it - await mutex1.unlock(); - }); - - test('Lock guarantees in-process mutual exclusion', async () => { - const result1 = await mutex1.lock(); - assert.equal(result1, true); // Expect to successfully acquire the lock since it's not held - const result2 = await Promise.race([mutex2.lock(), sleep(1000)]); - assert.equal(result2, 1000); // Expect the sleep to resolve before the mutex is acquired - }).timeout(10000); -});