Error: Lock file is already being held
marcj opened this issue · 4 comments
I'm using proper-lockfile in a Jest test suite which is executed in parallel across multiple processes.
My code
import * as lockFile from 'proper-lockfile';
import {readJsonSync, writeJSONSync} from "fs-extra";
const startPort = 28000;
const portFile = '/tmp/glut-integration-port.txt';
> lockFile.lockSync(portFile, {stale: 30000});
let port = startPort;
try {
port = readJsonSync(portFile, {throws: false}) || startPort;
if (port > 50000) {
port = startPort;
}
const thisPort = port + 1;
writeJSONSync(portFile, thisPort);
} finally {
lockFile.unlockSync(portFile);
}
When Jest is executed I get randomly the following error:
Error: Lock file is already being held
at /Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:68:47
at Object.newFs.<computed> [as stat] (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/adapter.js:20:13)
at /Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:56:20
at Object.newFs.<computed> [as mkdir] (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/adapter.js:17:24)
at acquireLock (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:29:16)
at RetryOperation._fn (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:233:13)
at RetryOperation.Object.<anonymous>.RetryOperation.attempt (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/node_modules/retry/lib/retry_operation.js:112:8)
at /Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:232:19
at Object.newFs.<computed> [as realpath] (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/adapter.js:20:13)
at resolveCanonicalPath (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:22:16)
at lock (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/lockfile.js:224:5)
at /Users/marc/bude/glut.ts/node_modules/proper-lockfile/lib/adapter.js:53:9
at AsyncFunction.lockSync (/Users/marc/bude/glut.ts/node_modules/proper-lockfile/index.js:13:42)
Environment:
npm: '6.9.0',
node: '12.2.0',
macOS 10.15.1
Also happens for me during npm install in my GitHub workflows
- I have playwright in my devDependencies
It happens when relaunching a Github workflow (not on first run)In fact it's random, when it starts to happen it happens a lot even on new commits
macOS 10.15.7
Node 16.13.0
npm 8.1.0
npm ERR! code 1
npm ERR! path /Users/runner/work/server/server/node_modules/@jsenv/core/node_modules/playwright
npm ERR! command failed
npm ERR! command sh -c node install.js
npm ERR! /Users/runner/work/server/server/node_modules/proper-lockfile/lib/lockfile.js:68
npm ERR! return callback(Object.assign(new Error('Lock file is already being held'), { code: 'ELOCKED', file }));
npm ERR! ^
npm ERR!
npm ERR! Error: Lock file is already being held
npm ERR! at /Users/runner/work/server/server/node_modules/proper-lockfile/lib/lockfile.js:68:47
npm ERR! at callback (/Users/runner/work/server/server/node_modules/graceful-fs/polyfills.js:299:20)
npm ERR! at FSReqCallback.oncomplete (node:fs:199:5) {
npm ERR! code: 'ELOCKED',
npm ERR! file: '/Users/runner/Library/Caches/ms-playwright'
npm ERR! }
use pnpm i
windows10 node 16.13.0
E:\Walker\Desktop\learn\vite\node_modules\.pnpm\proper-lockfile@4.1.2\node_modules\proper-lockfile\lib\lockfile.js:68
│ return callback(Object.assign(new Error('Lock file is already being held'), { code: 'ELOCKED', file }));
│ ^
│ Error: Lock file is already being held
│ at E:\Walker\Desktop\learn\vite\node_modules\.pnpm\proper-lockfile@4.1.2\node_modules\proper-lockfile\lib\lockfile.j
│ at callback (E:\Walker\Desktop\learn\vite\node_modules\.pnpm\registry.npmmirror.com+graceful-fs@4.2.8\node_modules\g
│ at FSReqCallback.oncomplete (node:fs:199:5) {
│ code: 'ELOCKED',
│ file: 'C:\\Users\\Walker\\AppData\\Local\\ms-playwright'
│ }
I've been getting this as well, in my case I suspect it's that I'm not giving enough time for the process to try to acquire a lockfile. Originally I was allocating 10-1000ms, but now I'm extending the window:
await lockfile.lock(dbLockfilePath, {
retries: { retries: 100, minTimeout: 10, maxTimeout: 100 },
});
My suspicion is that there's enough contention that it's not able to process all the work and give the lock to the one making the request within 1000ms, because Jest will max out CPU usage real hard.
This is happening for us a lot with linux (Ubuntu) users, and for the same exact code it does not seem to EVER be a problem for other operating systems.