Skip to content

Commit 1be2fad

Browse files
committed
fix(SyncProcess): Make sure sync process cancels when cancel is triggered
Signed-off-by: Marcel Klehr <[email protected]>
1 parent b851d01 commit 1be2fad

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

src/lib/strategies/Default.ts

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import Diff, {
2020
} from '../Diff'
2121
import Scanner, { ScanResult } from '../Scanner'
2222
import * as Parallel from 'async-parallel'
23-
import throttle from '@jcoreio/async-throttle'
23+
import throttle, { CanceledError } from '@jcoreio/async-throttle'
2424
import type { ThrottledFunction } from '@jcoreio/async-throttle'
2525
import Mappings, { MappingSnapshot } from '../Mappings'
2626
import TResource, { IHashSettings, OrderFolderResource, TLocalTree } from '../interfaces/Resource'
@@ -79,6 +79,9 @@ export default class SyncProcess {
7979
protected masterLocation: TItemLocation
8080
protected hashSettings: IHashSettings
8181

82+
protected cancelPromise: Promise<void>
83+
protected cancelCb: (error: any) => void
84+
8285
constructor(
8386
mappings:Mappings,
8487
localTree:TLocalTree,
@@ -90,6 +93,9 @@ export default class SyncProcess {
9093
this.server = server
9194

9295
this.progressCb = throttle(progressCb, 1500)
96+
this.cancelPromise = new Promise<void>((resolve, reject) => {
97+
this.cancelCb = reject
98+
})
9399
this.canceled = false
94100
this.isFirefox = self.location.protocol === 'moz-extension:'
95101
}
@@ -140,6 +146,7 @@ export default class SyncProcess {
140146

141147
async cancel() :Promise<void> {
142148
this.canceled = true
149+
this.cancelCb(new CancelledSyncError())
143150
this.server.cancel()
144151
this.localTree.cancel()
145152
this.progressCb.cancel()
@@ -156,7 +163,12 @@ export default class SyncProcess {
156163
0.5 + (this.actionsDone / (this.actionsPlanned + 1)) * 0.5
157164
),
158165
this.actionsDone
159-
)
166+
).catch((er) => {
167+
if (er instanceof CanceledError) {
168+
return
169+
}
170+
throw er
171+
})
160172
Logger.log(`Executed ${this.actionsDone} actions from ${this.actionsPlanned} actions`)
161173
}
162174

@@ -943,7 +955,10 @@ export default class SyncProcess {
943955
this.updateProgress()
944956
}
945957

946-
const id = await action.payload.visitCreate(resource)
958+
const id = await Promise.race([
959+
action.payload.visitCreate(resource),
960+
this.cancelPromise
961+
])
947962
if (typeof id === 'undefined') {
948963
// undefined means we couldn't create the item. we're ignoring it
949964
done()
@@ -1141,7 +1156,10 @@ export default class SyncProcess {
11411156
throw new CancelledSyncError()
11421157
}
11431158

1144-
await action.payload.visitRemove(resource)
1159+
await Promise.race([
1160+
action.payload.visitRemove(resource),
1161+
this.cancelPromise,
1162+
])
11451163
diff.retract(action)
11461164
donePlan.REMOVE.commit(action)
11471165
this.updateProgress()
@@ -1161,7 +1179,11 @@ export default class SyncProcess {
11611179
throw new CancelledSyncError()
11621180
}
11631181

1164-
await action.payload.visitUpdate(resource)
1182+
await Promise.race([
1183+
action.payload.visitUpdate(resource),
1184+
this.cancelPromise,
1185+
])
1186+
11651187
await this.addMapping(resource, action.oldItem, action.payload.id)
11661188
diff.retract(action)
11671189
if (action.type === ActionType.UPDATE) {
@@ -1289,18 +1311,21 @@ export default class SyncProcess {
12891311

12901312
const items = {}
12911313
try {
1292-
await resource.orderFolder(item.id, action.order
1293-
// in rare situations the diff generates a REMOVE for an item that is still in the tree,
1294-
// make sure to sort out those failed mapings (value: undefined)
1295-
// also make sure that items are unique
1296-
.filter(item => {
1297-
if (items[item.type + '' + item.id]) {
1298-
return false
1299-
}
1300-
items[item.type + '' + item.id] = true
1301-
return item.id
1302-
})
1303-
)
1314+
await Promise.race([
1315+
resource.orderFolder(item.id, action.order
1316+
// in rare situations the diff generates a REMOVE for an item that is still in the tree,
1317+
// make sure to sort out those failed mapings (value: undefined)
1318+
// also make sure that items are unique
1319+
.filter(item => {
1320+
if (items[item.type + '' + item.id]) {
1321+
return false
1322+
}
1323+
items[item.type + '' + item.id] = true
1324+
return item.id
1325+
})
1326+
),
1327+
this.cancelPromise,
1328+
])
13041329
} catch (e) {
13051330
Logger.log('Failed to execute REORDER: ' + e.message + '\nMoving on.')
13061331
Logger.log(e)

0 commit comments

Comments
 (0)