Skip to content

Commit

Permalink
feat(@vates/nbd-client): improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeauchamp committed Mar 30, 2023
1 parent e9b21c6 commit 232a80e
Showing 1 changed file with 19 additions and 25 deletions.
44 changes: 19 additions & 25 deletions @vates/nbd-client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,21 @@ module.exports = class NbdClient {
buffer.writeInt32BE(size, 24)

return new Promise((resolve, reject) => {
function decoratedReject(error) {
error.index = index
error.size = size
reject(error)
}

// this will handle one block response, but it can be another block
// since server does not guaranty to handle query in order
this.#commandQueryBacklog.set(queryId, {
size,
resolve,
reject,
reject: decoratedReject,
})
// really send the command to the server
this.#write(buffer).catch(reject)
this.#write(buffer).catch(decoratedReject)

// #readBlockResponse never throws directly
// but if it fails it will reject all the promises in the backlog
Expand All @@ -261,34 +267,22 @@ module.exports = class NbdClient {
}
const readAhead = []
const readAheadMaxLength = 10
const errors = []

// read all blocks, but try to keep readAheadMaxLength promise waiting ahead
for (const { index, size } of indexGenerator()) {
// stack readAheadMaxLengthpromise before starting to handle the results
if (readAhead.length === readAheadMaxLength) {
const block = await readAhead.shift()
if (block instanceof Error) {
break
}
yield block
// any error will stop reading blocks
yield readAhead.shift()
}
readAhead.push(
this.readBlock(index, size).catch(error => {
errors.push(error)
return error
})
)

// error is handled during unshift
const promise = this.readBlock(index, size)
promise.catch(() => {})
readAhead.push(promise)
}
while (readAhead.length > 0) {
const block = await readAhead.shift()
if (!(block instanceof Error)) {
yield block
}
}
// reading a block shoul be quite fast, we wait for all errors
// before rethrowing them
if (errors.length > 0) {
const error = new Error('fail during blocks reading')
error.errors = errors
throw error
yield readAhead.shift()
}
}
}

0 comments on commit 232a80e

Please sign in to comment.