Skip to content

Commit

Permalink
fix(Project): prevent potential data corruption in saveToCloud and …
Browse files Browse the repository at this point in the history
…`saveToLocalCache`

Fixes goplus#761
  • Loading branch information
aofei committed Aug 20, 2024
1 parent 822cf1d commit 542f976
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 8 deletions.
2 changes: 1 addition & 1 deletion spx-gui/src/models/project/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type State = {
}

export class History {
private mutex = new Mutex()
readonly mutex = new Mutex()

constructor(
private project: Project,
Expand Down
6 changes: 4 additions & 2 deletions spx-gui/src/models/project/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ export class Project extends Disposable {

/** Save to cloud */
async saveToCloud() {
const [metadata, files] = this.export()
const [metadata, files] = await this.history.mutex.runExclusive(this.export)
if (this.isDisposed) throw new Error('disposed')
const saved = await cloudHelper.save(metadata, files)
this.applyMetadata(saved.metadata)
this.lastSyncedFilesHash = await hashFiles(files)
Expand All @@ -396,7 +397,8 @@ export class Project extends Disposable {

/** Save to local cache */
private async saveToLocalCache(key: string) {
const [metadata, files] = this.export()
const [metadata, files] = await this.history.mutex.runExclusive(this.export)
if (this.isDisposed) throw new Error('disposed')
await localHelper.save(key, metadata, files)
}

Expand Down
16 changes: 12 additions & 4 deletions spx-gui/src/utils/disposable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@
export type Disposer = () => void

export class Disposable {
_disposers: Disposer[] = []
private disposers: Disposer[] = []

private _isDisposed = false
get isDisposed() {
return this._isDisposed
}

addDisposer = (disposer: Disposer) => {
this._disposers.push(disposer)
if (this._isDisposed) throw new Error('disposed')
this.disposers.push(disposer)
}

dispose = () => {
while (this._disposers.length > 0) {
this._disposers.pop()?.()
if (this._isDisposed) return
this._isDisposed = true
while (this.disposers.length > 0) {
this.disposers.pop()?.()
}
}
}
2 changes: 1 addition & 1 deletion spx-gui/src/utils/exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class DefaultException extends Exception {
}

/**
* Cancelled is a special exception, it stands for a "cancel operation" because of user ineraction.
* Cancelled is a special exception, it stands for a "cancel operation" because of user interaction.
* Like other exceptions, it breaks normal flows, while it is supposed to be ignored by all user-feedback components,
* so the user will not be notified of cancelled exceptions.
*/
Expand Down

0 comments on commit 542f976

Please sign in to comment.