Skip to content

Commit

Permalink
refactor: best-effort unpin after files.rm
Browse files Browse the repository at this point in the history
This ensures we don't remove pins if removal failed first,
and also do pin removal in best-effort fashion to avoid crashing webui
on DAGs with multiple instances of the same CID

Also, closes #1740
  • Loading branch information
lidel committed Mar 30, 2021
1 parent 2a8aae2 commit 5285a8b
Showing 1 changed file with 26 additions and 15 deletions.
41 changes: 26 additions & 15 deletions src/bundles/files/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,27 +334,38 @@ const actions = () => ({

if (files.length === 0) return undefined

try {
if (removeRemotely) {
files.map(file =>
remoteServices.map(async service => {
try {
await ipfs.pin.remote.rm({ cid: [file.cid], service })
} catch (_) {}
})
)
}

if (removeLocally) {
await Promise.all(files.map(async file => file.pinned && ipfs.pin.rm(file.cid)))
}
/**
* Execute function asynchronously in a best-effort fashion.
* We don't want any edge case (like a directory with multiple copies of
* same file) to crash webui, nor want to bother user with false-negatives
* @param {Function} fn
*/
const tryAsync = async fn => { try { await fn() } catch (_) {} }

try {
// try removing from MFS first
await Promise.all(
files.map(async file => ipfs.files.rm(realMfsPath(file.path), {
recursive: true
}))
)

// Pin cleanup only if MFS removal was successful
if (removeRemotely) {
// remote unpin can be slow, so we do this async in best-effort fashion
files.forEach(file => remoteServices.map(async service => tryAsync(() =>
ipfs.pin.remote.rm({ cid: [file.cid], service })
)))
}

if (removeLocally) {
// removal of local pin can fail if same CID is present twice,
// this is done in best-effort as well
await Promise.all(files.map(async file => file.pinned && tryAsync(() =>
ipfs.pin.rm(file.cid)
)))
}

const src = files[0].path
const path = src.slice(0, src.lastIndexOf('/'))
await store.doUpdateHash(path)
Expand All @@ -381,7 +392,7 @@ const actions = () => ({
const srcPath = src.startsWith('/') ? src : `/ipfs/${name}`

try {
return ipfs.files.cp(srcPath, dst)
return await ipfs.files.cp(srcPath, dst)
} finally {
await store.doFilesFetch()
}
Expand Down

0 comments on commit 5285a8b

Please sign in to comment.