Skip to content

Commit 49f77f1

Browse files
committed
feat: add cancellation mechanism for all network ops
1 parent de0c48c commit 49f77f1

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

bin/cmd.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { pickLanguages, pickKeys } from './../lib/util.js'
55
import { execCmd } from './../lib/exec.js'
66
import { trap } from './../lib/signals.js'
77

8+
const abortController = new AbortController()
9+
810
Promise.race([
911
(async () => {
1012
const args = process.argv.slice(2)
@@ -27,8 +29,8 @@ Promise.race([
2729
)
2830
}
2931

30-
const sourceRepo = new WikibaseRepo(source)
31-
const targetRepo = new WikibaseRepo(target, { oauth })
32+
const sourceRepo = new WikibaseRepo(source, { abortController })
33+
const targetRepo = new WikibaseRepo(target, { oauth, abortController })
3234

3335
const contentLanguages = await targetRepo.getContentLanguages()
3436

@@ -55,6 +57,7 @@ Promise.race([
5557
console.error('An error occurred executing the command:')
5658
console.error(err)
5759
process.exitCode = 1
60+
abortController.abort()
5861
})
5962
.then(() => {
6063
if (process.env.CALLBACK_ON_SUCCESS && process.exitCode === 0) {

lib/repo.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import WBEdit from 'wikibase-edit'
22
import { WBK } from 'wikibase-sdk'
33

44
export default class WikibaseRepository {
5-
constructor (origin, opts = {}) {
5+
constructor (origin, opts = { abortController: new AbortController() }) {
66
this.origin = origin
7+
this.abortController = opts.abortController
78

89
this.read = new WBK({
910
instance: origin
@@ -19,8 +20,16 @@ export default class WikibaseRepository {
1920
}
2021
}
2122

23+
async withCancellationContext (thunk) {
24+
this.abortController.signal.throwIfAborted()
25+
return thunk()
26+
}
27+
2228
getContentLanguages () {
23-
return fetch(`${this.origin}/w/api.php?action=query&meta=wbcontentlanguages&format=json`)
29+
return fetch(
30+
`${this.origin}/w/api.php?action=query&meta=wbcontentlanguages&format=json`,
31+
{ signal: this.abortController.signal }
32+
)
2433
.then(r => r.json())
2534
.then(body => Object.keys(body.query.wbcontentlanguages))
2635
}
@@ -30,7 +39,7 @@ export default class WikibaseRepository {
3039
return Promise.reject(new Error('Cannot edit a read only instance.'))
3140
}
3241
return Promise.allSettled(entities.map(async entity => {
33-
return this.edit.entity.create(entity)
42+
return this.withCancellationContext(() => this.edit.entity.create(entity))
3443
}))
3544
.then((results) => {
3645
for (const result of results) {
@@ -46,14 +55,16 @@ export default class WikibaseRepository {
4655
return Promise.all(identifiers.map(async identifier => {
4756
const [entityId, revision] = identifier.split('@')
4857
const url = revision
49-
? await this.read.getEntityRevision({
58+
? await this.withCancellationContext(() => this.read.getEntityRevision({
5059
id: entityId,
5160
revision
52-
})
53-
: await this.read.getEntities({
61+
}))
62+
: await this.withCancellationContext(() => this.read.getEntities({
5463
ids: [entityId]
55-
})
56-
const { entities } = await fetch(url).then(res => res.json())
64+
}))
65+
const { entities } = await fetch(
66+
url, { signal: this.abortController.signal }
67+
).then(res => res.json())
5768
return entities[entityId]
5869
}))
5970
}

0 commit comments

Comments
 (0)