Skip to content

Commit

Permalink
fix: Don't set lock after freeing it
Browse files Browse the repository at this point in the history
fixes #1594
fixes #1548

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
  • Loading branch information
marcelklehr committed May 9, 2024
1 parent ec93dd3 commit 0d85c11
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 26 deletions.
19 changes: 13 additions & 6 deletions src/lib/adapters/Git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const LOCK_INTERVAL = 2 * 60 * 1000 // Lock every 2mins while syncing
const LOCK_TIMEOUT = 15 * 60 * 1000 // Override lock 0.25h after last time lock has been set
export default class GitAdapter extends CachingAdapter {
private lockingInterval: any
private lockingPromise: Promise<void>
private locked: string[]
private cancelCallback: () => void
private initialTreeHash: string
Expand Down Expand Up @@ -223,19 +224,25 @@ export default class GitAdapter extends CachingAdapter {
}

async setLock() {
const tag = 'floccus-lock-' + Date.now()
Logger.log('(git) tag ' + tag)
await git.tag({ fs: this.fs, dir: this.dir, ref: tag })
Logger.log('(git) push tag ' + tag)
await git.push({ fs: this.fs, http, dir: this.dir, ref: tag, onAuth: () => this.onAuth() })
this.locked.push(tag)
this.lockingPromise = (async() => {
const tag = 'floccus-lock-' + Date.now()
Logger.log('(git) tag ' + tag)
await git.tag({ fs: this.fs, dir: this.dir, ref: tag })
Logger.log('(git) push tag ' + tag)
await git.push({ fs: this.fs, http, dir: this.dir, ref: tag, onAuth: () => this.onAuth() })
this.locked.push(tag)
})()
await this.lockingPromise
}

async onAuth() {
return { username: this.server.username, password: this.server.password }
}

async freeLock() {
if (this.lockingPromise) {
await this.lockingPromise
}
if (!this.locked.length) {
return
}
Expand Down
7 changes: 6 additions & 1 deletion src/lib/adapters/GoogleDrive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export default class GoogleDriveAdapter extends CachingAdapter {
private cancelCallback: () => void = null
private alwaysUpload = false
private lockingInterval: any
private lockingPromise: Promise<CustomResponse>

constructor(server) {
super(server)
Expand Down Expand Up @@ -399,6 +400,9 @@ export default class GoogleDriveAdapter extends CachingAdapter {
}

async freeLock(id:string) {
if (this.lockingPromise) {
await this.lockingPromise
}
let lockFreed, i = 0
do {
const res = await this.request('PATCH', this.getUrl() + '/files/' + id,
Expand All @@ -419,14 +423,15 @@ export default class GoogleDriveAdapter extends CachingAdapter {
}

async setLock(id:string) {
const res = await this.request('PATCH', this.getUrl() + '/files/' + id,
this.lockingPromise = this.request('PATCH', this.getUrl() + '/files/' + id,
JSON.stringify({
appProperties: {
locked: JSON.stringify(Date.now())
}
}),
'application/json'
)
const res = await this.lockingPromise
return res.status === 200
}

Expand Down
35 changes: 21 additions & 14 deletions src/lib/adapters/NextcloudBookmarks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default class NextcloudBookmarksAdapter implements Adapter, BulkImportRes
private canceled = false
private cancelCallback: () => void = null
private lockingInterval: any
private lockingPromise: Promise<boolean>
private ended = false

constructor(server: NextcloudBookmarksConfig) {
Expand Down Expand Up @@ -943,25 +944,31 @@ export default class NextcloudBookmarksAdapter implements Adapter, BulkImportRes
}

private async acquireLock():Promise<boolean> {
const res = await this.sendRequest(
'POST',
'index.php/apps/bookmarks/public/rest/v2/lock',
null,
null,
true
)
this.lockingPromise = (async() => {
const res = await this.sendRequest(
'POST',
'index.php/apps/bookmarks/public/rest/v2/lock',
null,
null,
true
)

if (res.status === 401 || res.status === 403) {
throw new AuthenticationError()
}
if (res.status !== 200 && res.status !== 405 && res.status !== 423) {
throw new HttpError(res.status, 'POST')
}
if (res.status === 401 || res.status === 403) {
throw new AuthenticationError()
}
if (res.status !== 200 && res.status !== 405 && res.status !== 423) {
throw new HttpError(res.status, 'POST')
}

return res.status === 200 || res.status === 405
return res.status === 200 || res.status === 405
})()
return this.lockingPromise
}

private async releaseLock():Promise<boolean> {
if (this.lockingPromise) {
await this.lockingPromise
}
const res = await this.sendRequest(
'DELETE',
'index.php/apps/bookmarks/public/rest/v2/lock',
Expand Down
17 changes: 12 additions & 5 deletions src/lib/adapters/WebDav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const LOCK_INTERVAL = 2 * 60 * 1000 // Lock every 2mins while syncing
const LOCK_TIMEOUT = 15 * 60 * 1000 // Override lock 0.25h after last time lock has been set
export default class WebDavAdapter extends CachingAdapter {
private lockingInterval: any
private lockingPromise: Promise<any>
private locked: boolean
private cancelCallback: () => void
private initialTreeHash: string
Expand Down Expand Up @@ -91,7 +92,7 @@ export default class WebDavAdapter extends CachingAdapter {
if (res.headers['Last-Modified']) {
const date = new Date(res.headers['Last-Modified'])
const dateLocked = date.valueOf()
if (Date.now() - dateLocked < LOCK_TIMEOUT) {
if (dateLocked > Date.now() - LOCK_TIMEOUT) {
throw new ResourceLockedError()
}
} else {
Expand All @@ -100,7 +101,7 @@ export default class WebDavAdapter extends CachingAdapter {
}

if (res.status === 200) {
// continue anywayrStatus
// continue anyway
} else if (res.status === 404) {
await this.setLock()
} else {
Expand All @@ -109,23 +110,28 @@ export default class WebDavAdapter extends CachingAdapter {
this.server.bookmark_file + '.lock'
)
}
this.locked = true
}

async setLock() {
const fullURL = this.getBookmarkLockURL()
Logger.log(fullURL)
await this.uploadFile(
Logger.log('Setting lock: ' + fullURL)
this.lockingPromise = this.uploadFile(
fullURL,
'text/html',
'<html><body>I am a lock file</body></html>'
)
await this.lockingPromise
this.locked = true
}

async freeLock() {
if (this.lockingPromise) {
await this.lockingPromise
}
if (!this.locked) {
return
}

const fullUrl = this.getBookmarkLockURL()

const authString = Base64.encode(
Expand All @@ -135,6 +141,7 @@ export default class WebDavAdapter extends CachingAdapter {
let res, lockFreed, i = 0
try {
do {
Logger.log('Freeing lock: ' + fullUrl)
if (Capacitor.getPlatform() === 'web') {
res = await fetch(fullUrl, {
method: 'DELETE',
Expand Down

0 comments on commit 0d85c11

Please sign in to comment.