Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit f11220e

Browse files
authored
fix: remove client-side timeout from http rpc calls (#3178)
Do not set up a client-side timeout, instead rely on the server-side version. The global timeout is still respected, users can use an AbortSignal to do timeouts on a per-call basis if desired. Also brings refs API in line with go-IPFS - timeouts are recorded in the `.err` prop of the output instead of the whole API call throwing a `TimeoutError` fixes: #3161
1 parent eba5fe6 commit f11220e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+45
-112
lines changed

Diff for: packages/interface-ipfs-core/src/refs.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ function getRefsTests () {
323323
'should print nothing for non-existent hashes': {
324324
path: () => 'QmYmW4HiZhotsoSqnv2o1oSssvkRM8b9RweBoH7ao5nki2',
325325
params: { timeout: 2000 },
326-
expected: [],
327-
expectTimeout: true
326+
expected: ['']
328327
}
329328
}
330329
}

Diff for: packages/ipfs-core/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@ipld/dag-pb": "^2.1.3",
6363
"@multiformats/murmur3": "^1.0.1",
6464
"abort-controller": "^3.0.0",
65+
"any-signal": "^2.1.2",
6566
"array-shuffle": "^2.0.0",
6667
"blockstore-datastore-adapter": "^1.0.0",
6768
"datastore-core": "^5.0.1",
@@ -126,6 +127,7 @@
126127
"parse-duration": "^1.0.0",
127128
"peer-id": "^0.15.1",
128129
"streaming-iterables": "^6.0.0",
130+
"timeout-abort-controller": "^1.1.1",
129131
"uint8arrays": "^3.0.0"
130132
},
131133
"devDependencies": {

Diff for: packages/ipfs-core/src/components/refs/index.js

+30-10
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
const dagPb = require('@ipld/dag-pb')
44
const { Errors } = require('interface-datastore')
55
const ERR_NOT_FOUND = Errors.notFoundError().code
6-
const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option')
76
const toCIDAndPath = require('ipfs-core-utils/src/to-cid-and-path')
87
const { CID } = require('multiformats/cid')
8+
// @ts-expect-error no types
9+
const TimeoutController = require('timeout-abort-controller')
10+
const { anySignal } = require('any-signal')
911

1012
const Format = {
1113
default: '<dst>',
@@ -21,6 +23,8 @@ const Format = {
2123
* @property {Node} parent
2224
* @property {Node} node
2325
* @property {boolean} isDuplicate
26+
*
27+
* @typedef {import('ipfs-core-types/src/utils').AbortOptions} AbortOptions
2428
*/
2529

2630
/**
@@ -49,17 +53,30 @@ module.exports = function ({ repo, codecs, resolve, preload }) {
4953
options.maxDepth = options.recursive ? Infinity : 1
5054
}
5155

56+
if (options.timeout) {
57+
const controller = new TimeoutController(options.timeout)
58+
59+
options.signal = anySignal([options.signal, controller.signal])
60+
}
61+
5262
/** @type {(string|CID)[]} */
5363
const rawPaths = Array.isArray(ipfsPath) ? ipfsPath : [ipfsPath]
5464

5565
const paths = rawPaths.map(p => getFullPath(preload, p, options))
5666

5767
for (const path of paths) {
58-
yield * refsStream(resolve, repo, codecs, path, options)
68+
try {
69+
yield * refsStream(resolve, repo, codecs, path, options)
70+
} catch (err) {
71+
yield {
72+
ref: '',
73+
err: err.message
74+
}
75+
}
5976
}
6077
}
6178

62-
return withTimeoutOption(refs)
79+
return refs
6380
}
6481

6582
module.exports.Format = Format
@@ -93,7 +110,7 @@ function getFullPath (preload, ipfsPath, options) {
93110
*/
94111
async function * refsStream (resolve, repo, codecs, path, options) {
95112
// Resolve to the target CID of the path
96-
const resPath = await resolve(path)
113+
const resPath = await resolve(path, options)
97114
const {
98115
cid
99116
} = toCIDAndPath(resPath)
@@ -102,7 +119,7 @@ async function * refsStream (resolve, repo, codecs, path, options) {
102119
const unique = options.unique || false
103120

104121
// Traverse the DAG, converting it into a stream
105-
for await (const obj of objectStream(repo, codecs, cid, maxDepth, unique)) {
122+
for await (const obj of objectStream(repo, codecs, cid, maxDepth, unique, options)) {
106123
// Root object will not have a parent
107124
if (!obj.parent) {
108125
continue
@@ -144,8 +161,9 @@ function formatLink (srcCid, dstCid, linkName = '', format = Format.default) {
144161
* @param {CID} rootCid
145162
* @param {number} maxDepth
146163
* @param {boolean} uniqueOnly
164+
* @param {AbortOptions} options
147165
*/
148-
async function * objectStream (repo, codecs, rootCid, maxDepth, uniqueOnly) { // eslint-disable-line require-await
166+
async function * objectStream (repo, codecs, rootCid, maxDepth, uniqueOnly, options) { // eslint-disable-line require-await
149167
const seen = new Set()
150168

151169
/**
@@ -164,7 +182,7 @@ async function * objectStream (repo, codecs, rootCid, maxDepth, uniqueOnly) { //
164182
// Get this object's links
165183
try {
166184
// Look at each link, parent and the new depth
167-
for await (const link of getLinks(repo, codecs, parent.cid)) {
185+
for await (const link of getLinks(repo, codecs, parent.cid, options)) {
168186
yield {
169187
parent: parent,
170188
node: link,
@@ -195,14 +213,16 @@ async function * objectStream (repo, codecs, rootCid, maxDepth, uniqueOnly) { //
195213
* @param {import('ipfs-repo').IPFSRepo} repo
196214
* @param {import('ipfs-core-utils/src/multicodecs')} codecs
197215
* @param {CID} cid
198-
* @param {Array<string|number>} base
216+
* @param {AbortOptions} options
199217
* @returns {AsyncGenerator<{ name: string, cid: CID }, void, undefined>}
200218
*/
201-
async function * getLinks (repo, codecs, cid, base = []) {
202-
const block = await repo.blocks.get(cid)
219+
async function * getLinks (repo, codecs, cid, options) {
220+
const block = await repo.blocks.get(cid, options)
203221
const codec = await codecs.getCodec(cid.code)
204222
const value = codec.decode(block)
205223
const isDagPb = cid.code === dagPb.code
224+
/** @type {Array<string|number>} */
225+
const base = []
206226

207227
for (const [name, cid] of links(value, base)) {
208228
// special case for dag-pb - use the name of the link

Diff for: packages/ipfs-http-client/src/add-all.js

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ module.exports = configure((api) => {
4343
...options,
4444
progress: Boolean(progressFn)
4545
}),
46-
timeout: options.timeout,
4746
onUploadProgress,
4847
signal,
4948
headers,

Diff for: packages/ipfs-http-client/src/bitswap/stat.js

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module.exports = configure(api => {
1616
async function stat (options = {}) {
1717
const res = await api.post('bitswap/stat', {
1818
searchParams: toUrlSearchParams(options),
19-
timeout: options.timeout,
2019
signal: options.signal,
2120
headers: options.headers
2221
})

Diff for: packages/ipfs-http-client/src/bitswap/unwant.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function unwant (cid, options = {}) {
1616
const res = await api.post('bitswap/unwant', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
arg: cid.toString(),

Diff for: packages/ipfs-http-client/src/bitswap/wantlist-for-peer.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function wantlistForPeer (peerId, options = {}) {
1717
const res = await (await api.post('bitswap/wantlist', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
...options,

Diff for: packages/ipfs-http-client/src/bitswap/wantlist.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function wantlist (options = {}) {
1717
const res = await (await api.post('bitswap/wantlist', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams(options),
2120
headers: options.headers

Diff for: packages/ipfs-http-client/src/block/get.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function get (cid, options = {}) {
1616
const res = await api.post('block/get', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
arg: cid.toString(),

Diff for: packages/ipfs-http-client/src/block/put.js

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ module.exports = configure(api => {
2424
let res
2525
try {
2626
const response = await api.post('block/put', {
27-
timeout: options.timeout,
2827
signal: signal,
2928
searchParams: toUrlSearchParams(options),
3029
...(

Diff for: packages/ipfs-http-client/src/block/rm.js

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ module.exports = configure(api => {
2020
}
2121

2222
const res = await api.post('block/rm', {
23-
timeout: options.timeout,
2423
signal: options.signal,
2524
searchParams: toUrlSearchParams({
2625
arg: cid.map(cid => cid.toString()),

Diff for: packages/ipfs-http-client/src/block/stat.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function stat (cid, options = {}) {
1717
const res = await api.post('block/stat', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
arg: cid.toString(),

Diff for: packages/ipfs-http-client/src/bootstrap/add.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function add (addr, options = {}) {
1717
const res = await api.post('bootstrap/add', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
arg: addr,

Diff for: packages/ipfs-http-client/src/bootstrap/clear.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function clear (options = {}) {
1717
const res = await api.post('bootstrap/rm', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
...options,

Diff for: packages/ipfs-http-client/src/bootstrap/list.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function list (options = {}) {
1717
const res = await api.post('bootstrap/list', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams(options),
2120
headers: options.headers

Diff for: packages/ipfs-http-client/src/bootstrap/reset.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function reset (options = {}) {
1717
const res = await api.post('bootstrap/add', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
...options,

Diff for: packages/ipfs-http-client/src/bootstrap/rm.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function rm (addr, options = {}) {
1717
const res = await api.post('bootstrap/rm', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
arg: addr,

Diff for: packages/ipfs-http-client/src/cat.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function * cat (path, options = {}) {
1616
const res = await api.post('cat', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
arg: path.toString(),

Diff for: packages/ipfs-http-client/src/commands.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
const commands = async (options = {}) => {
1616
const res = await api.post('commands', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams(options),
2019
headers: options.headers

Diff for: packages/ipfs-http-client/src/config/get.js

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ module.exports = configure(api => {
1818
}
1919

2020
const res = await api.post('config', {
21-
timeout: options.timeout,
2221
signal: options.signal,
2322
searchParams: toUrlSearchParams({
2423
arg: key,

Diff for: packages/ipfs-http-client/src/config/getAll.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
const getAll = async (options = {}) => {
1616
const res = await api.post('config/show', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
...options

Diff for: packages/ipfs-http-client/src/config/profiles/apply.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function apply (profile, options = {}) {
1616
const res = await api.post('config/profile/apply', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
arg: profile,

Diff for: packages/ipfs-http-client/src/config/profiles/list.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
async function list (options = {}) {
1717
const res = await api.post('config/profile/list', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams(options),
2120
headers: options.headers

Diff for: packages/ipfs-http-client/src/config/replace.js

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ module.exports = configure(api => {
2222
const signal = abortSignal(controller.signal, options.signal)
2323

2424
const res = await api.post('config/replace', {
25-
timeout: options.timeout,
2625
signal,
2726
searchParams: toUrlSearchParams(options),
2827
...(

Diff for: packages/ipfs-http-client/src/config/set.js

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ module.exports = configure(api => {
2323
}
2424

2525
const res = await api.post('config', {
26-
timeout: options.timeout,
2726
signal: options.signal,
2827
searchParams: toUrlSearchParams(params),
2928
headers: options.headers

Diff for: packages/ipfs-http-client/src/dag/export.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function * dagExport (root, options = {}) {
1616
const res = await api.post('dag/export', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams({
2019
arg: root.toString()

Diff for: packages/ipfs-http-client/src/dag/import.js

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ module.exports = configure(api => {
2222
const { headers, body } = await multipartRequest(source, controller, options.headers)
2323

2424
const res = await api.post('dag/import', {
25-
timeout: options.timeout,
2625
signal,
2726
headers,
2827
body,

Diff for: packages/ipfs-http-client/src/dag/resolve.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ module.exports = configure(api => {
1515
*/
1616
const resolve = async (ipfsPath, options = {}) => {
1717
const res = await api.post('dag/resolve', {
18-
timeout: options.timeout,
1918
signal: options.signal,
2019
searchParams: toUrlSearchParams({
2120
arg: `${ipfsPath}${options.path ? `/${options.path}`.replace(/\/[/]+/g, '/') : ''}`,

Diff for: packages/ipfs-http-client/src/dht/find-peer.js

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module.exports = configure(api => {
1616
*/
1717
async function findPeer (peerId, options = {}) {
1818
const res = await api.post('dht/findpeer', {
19-
timeout: options.timeout,
2019
signal: options.signal,
2120
searchParams: toUrlSearchParams({
2221
arg: peerId,

Diff for: packages/ipfs-http-client/src/dht/find-provs.js

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module.exports = configure(api => {
1616
*/
1717
async function * findProvs (cid, options = {}) {
1818
const res = await api.post('dht/findprovs', {
19-
timeout: options.timeout,
2019
signal: options.signal,
2120
searchParams: toUrlSearchParams({
2221
arg: cid.toString(),

Diff for: packages/ipfs-http-client/src/dht/get.js

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ module.exports = configure(api => {
1717
*/
1818
async function get (key, options = {}) {
1919
const res = await api.post('dht/get', {
20-
timeout: options.timeout,
2120
signal: options.signal,
2221
searchParams: toUrlSearchParams({
2322
arg: key instanceof Uint8Array ? uint8ArrayToString(key) : key,

Diff for: packages/ipfs-http-client/src/dht/provide.js

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ module.exports = configure(api => {
2020
const cidArr = Array.isArray(cids) ? cids : [cids]
2121

2222
const res = await api.post('dht/provide', {
23-
timeout: options.timeout,
2423
signal: options.signal,
2524
searchParams: toUrlSearchParams({
2625
arg: cidArr.map(cid => cid.toString()),

Diff for: packages/ipfs-http-client/src/dht/put.js

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ module.exports = configure(api => {
2424
const signal = abortSignal(controller.signal, options.signal)
2525

2626
const res = await api.post('dht/put', {
27-
timeout: options.timeout,
2827
signal,
2928
searchParams: toUrlSearchParams({
3029
arg: uint8ArrayToString(key),

Diff for: packages/ipfs-http-client/src/dht/query.js

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ module.exports = configure(api => {
1616
*/
1717
async function * query (peerId, options = {}) {
1818
const res = await api.post('dht/query', {
19-
timeout: options.timeout,
2019
signal: options.signal,
2120
searchParams: toUrlSearchParams({
2221
arg: peerId.toString(),

Diff for: packages/ipfs-http-client/src/diag/cmds.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module.exports = configure(api => {
1414
*/
1515
async function cmds (options = {}) {
1616
const res = await api.post('diag/cmds', {
17-
timeout: options.timeout,
1817
signal: options.signal,
1918
searchParams: toUrlSearchParams(options),
2019
headers: options.headers

0 commit comments

Comments
 (0)