Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

feat: support passing AbortSignals to the configured repo #89

Merged
merged 2 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
},
"homepage": "https://github.com/ipfs/js-ipfs-block-service#readme",
"devDependencies": {
"abort-controller": "^3.0.0",
"aegir": "^19.0.3",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"cids": "~0.7.1",
"dirty-chai": "^2.0.1",
"fs-extra": "^8.0.1",
Expand Down
38 changes: 24 additions & 14 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,59 +54,67 @@ class BlockService {
* Put a block to the underlying datastore.
*
* @param {Block} block
* @param {Object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
*/
put (block) {
put (block, options) {
if (this.hasExchange()) {
return this._bitswap.put(block)
return this._bitswap.put(block, options)
} else {
return this._repo.blocks.put(block)
return this._repo.blocks.put(block, options)
}
}

/**
* Put a multiple blocks to the underlying datastore.
*
* @param {Array<Block>} blocks
* @param {Object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
*/
putMany (blocks) {
putMany (blocks, options) {
if (this.hasExchange()) {
return this._bitswap.putMany(blocks)
return this._bitswap.putMany(blocks, options)
} else {
return this._repo.blocks.putMany(blocks)
return this._repo.blocks.putMany(blocks, options)
}
}

/**
* Get a block by cid.
*
* @param {CID} cid
* @param {Object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise<Block>}
*/
get (cid) {
get (cid, options) {
if (this.hasExchange()) {
return this._bitswap.get(cid)
return this._bitswap.get(cid, options)
} else {
return this._repo.blocks.get(cid)
return this._repo.blocks.get(cid, options)
}
}

/**
* Get multiple blocks back from an array of cids.
*
* @param {Array<CID>} cids
* @param {Object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Iterator<Block>}
*/
getMany (cids) {
getMany (cids, options) {
if (!Array.isArray(cids)) {
throw new Error('first arg must be an array of cids')
}

if (this.hasExchange()) {
return this._bitswap.getMany(cids)
return this._bitswap.getMany(cids, options)
} else {
const getRepoBlocks = map((cid) => this._repo.blocks.get(cid))
const getRepoBlocks = map((cid) => this._repo.blocks.get(cid, options))
return getRepoBlocks(cids)
}
}
Expand All @@ -115,10 +123,12 @@ class BlockService {
* Delete a block from the blockstore.
*
* @param {CID} cid
* @param {Object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
*/
delete (cid) {
return this._repo.blocks.delete(cid)
delete (cid, options) {
return this._repo.blocks.delete(cid, options)
}
}

Expand Down
86 changes: 86 additions & 0 deletions test/aborting-requests.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
chai.use(require('dirty-chai'))
chai.use(require('chai-as-promised'))
const expect = chai.expect

const { collect } = require('streaming-iterables')
const AbortController = require('abort-controller')

const BlockService = require('../src')

describe('aborting requests', () => {
let abortedErr
let r

beforeEach(() => {
abortedErr = new Error('Aborted!')
const abortOnSignal = (...args) => {
const { signal } = args[args.length - 1]

return new Promise((resolve, reject) => {
signal.addEventListener('abort', () => {
reject(abortedErr)
})
})
}

const repo = {
blocks: {
put: abortOnSignal,
putMany: abortOnSignal,
get: abortOnSignal,
delete: abortOnSignal,
deleteMany: abortOnSignal
}
}
r = new BlockService(repo)
})

it('put - supports abort signals', async () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(r.put('block', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
})

it('putMany - supports abort signals', async () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(r.putMany(['block'], {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
})

it('get - supports abort signals', async () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(r.get('cid', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
})

it('getMany - supports abort signals', async () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(collect(r.getMany(['cid'], {
signal: controller.signal
}))).to.eventually.rejectedWith(abortedErr)
})

it('remove - supports abort signals', async () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(r.delete('cid', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
})
})