Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/handlers/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async function patchHandler (req, res, next) {
}

// Patch the graph and write it back to the file
const result = await withLock(path, { mustExist: false }, async () => {
const result = await withLock(path, async () => {
const graph = await readGraph(resource)
await applyPatch(patchObject, graph, url)
return writeGraph(graph, resource, ldp.resourceMapper.resolveFilePath(req.hostname), ldp.serverUri)
Expand Down
8 changes: 4 additions & 4 deletions lib/ldp.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class LDP {
}

// Directory created, now write the file
return withLock(path, { mustExist: false }, () => new Promise((resolve, reject) => {
return withLock(path, () => new Promise((resolve, reject) => {
// HACK: the middleware in webid-oidc.js uses body-parser, thus ending the stream of data
// for JSON bodies. So, the stream needs to be reset
if (contentType.includes('application/json')) {
Expand Down Expand Up @@ -445,15 +445,15 @@ class LDP {
const linkPath = this.resourceMapper._removeDollarExtension(path)
try {
// first delete file, then links with write permission only (atomic delete)
await withLock(path, { mustExist: false }, () => promisify(fs.unlink)(path))
await withLock(path, () => promisify(fs.unlink)(path))

const aclPath = `${linkPath}${this.suffixAcl}`
if (await promisify(fs.exists)(aclPath)) {
await withLock(aclPath, { mustExist: false }, () => promisify(fs.unlink)(aclPath))
await withLock(aclPath, () => promisify(fs.unlink)(aclPath))
}
const metaPath = `${linkPath}${this.suffixMeta}`
if (await promisify(fs.exists)(metaPath)) {
await withLock(metaPath, { mustExist: false }, () => promisify(fs.unlink)(metaPath))
await withLock(metaPath, () => promisify(fs.unlink)(metaPath))
}
} catch (err) {
debug.container('DELETE -- unlink() error: ' + err)
Expand Down
33 changes: 5 additions & 28 deletions lib/lock.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,10 @@
/* eslint-disable no-async-promise-executor */
const AsyncLock = require('async-lock')

const { lock } = require('proper-lockfile')
const lock = new AsyncLock({ timeout: 30 * 1000 })

const staleSeconds = 30

// Obtains a lock on the path, and maintains it until the callback finishes
function withLock (path, options = {}, callback = options) {
return new Promise(async (resolve, reject) => {
let releaseLock, result
try {
// Obtain the lock
releaseLock = await lock(path, {
retries: 10,
update: 1000,
stale: staleSeconds * 1000,
realpath: !!options.mustExist,
onCompromised: () =>
reject(new Error(`The file at ${path} was not updated within ${staleSeconds}s.`))
})
// Hold on to the lock until the callback's returned promise resolves
result = await callback()
} catch (error) {
reject(error)
// Ensure the lock is always released
} finally {
await releaseLock()
}
resolve(result)
})
// Obtains a lock on the path, and maintains it until the task finishes
async function withLock (path, executeTask) {
return await lock.acquire(path, executeTask)
}

module.exports = withLock
20 changes: 5 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"dependencies": {
"@solid/acl-check": "^0.3.0",
"@solid/oidc-auth-manager": "^0.22.0",
"async-lock": "^1.2.4",
"body-parser": "^1.19.0",
"bootstrap": "^3.4.1",
"busboy": "^0.3.1",
Expand Down Expand Up @@ -92,7 +93,6 @@
"nodemailer": "^6.4.11",
"oidc-op-express": "^0.0.3",
"owasp-password-strength-test": "^1.3.0",
"proper-lockfile": "^4.1.1",
"rdflib": "^1.3.1",
"recursive-readdir": "^2.2.2",
"rimraf": "^3.0.2",
Expand Down