Do not retry a request if the body is a stream (#1143)

* Do not retry a request if the body is a stream

Refactored the trnasport.request method to not use stream for gzipping
the body, but use the callback API instead. The maxRetries will be 0 in
case of a stream body and cached the Accept-Encoding header.

* Updated dependencies

* Updated test
This commit is contained in:
Tomas Della Vedova
2020-04-06 12:16:21 +02:00
committed by GitHub
parent d10e8bb9f3
commit e67b55d163
4 changed files with 209 additions and 99 deletions

View File

@ -32,10 +32,7 @@ test('Should emit a request event when a request is performed', t => {
method: 'GET',
path: '/test/_search',
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Length': '0'
}
querystring: 'q=foo%3Abar'
},
options: {},
id: 1
@ -83,10 +80,7 @@ test('Should emit a response event in case of a successful response', t => {
method: 'GET',
path: '/test/_search',
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Length': '0'
}
querystring: 'q=foo%3Abar'
},
options: {},
id: 1
@ -132,10 +126,7 @@ test('Should emit a response event with the error set', t => {
method: 'GET',
path: '/test/_search',
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Length': '0'
}
querystring: 'q=foo%3Abar'
},
options: {
requestTimeout: 500

View File

@ -619,6 +619,57 @@ test('Retry mechanism', t => {
})
})
test('Should not retry if the body is a stream', t => {
t.plan(2)
var count = 0
function handler (req, res) {
res.setHeader('Content-Type', 'application/json;utf=8')
if (count > 0) {
res.end(JSON.stringify({ hello: 'world' }))
} else {
setTimeout(() => {
res.end(JSON.stringify({ hello: 'world' }))
}, 1000)
}
count++
}
buildServer(handler, ({ port }, server) => {
const pool = new ConnectionPool({ Connection })
pool.addConnection([{
url: new URL(`http://localhost:${port}`),
id: 'node1'
}, {
url: new URL(`http://localhost:${port}`),
id: 'node2'
}, {
url: new URL(`http://localhost:${port}`),
id: 'node3'
}])
const transport = new Transport({
emit: () => {},
connectionPool: pool,
serializer: new Serializer(),
maxRetries: 1,
requestTimeout: 10,
sniffInterval: false,
sniffOnStart: false
})
transport.request({
method: 'POST',
path: '/hello',
body: intoStream(JSON.stringify({ hello: 'world' }))
}, (err, { body }) => {
t.ok(err instanceof TimeoutError)
t.strictEqual(count, 1)
server.stop()
})
})
})
test('Custom retry mechanism', t => {
t.plan(2)
@ -1956,6 +2007,62 @@ test('Compress request', t => {
})
})
t.test('Retry a gzipped body', t => {
t.plan(7)
var count = 0
function handler (req, res) {
t.match(req.headers, {
'content-type': 'application/json',
'content-encoding': 'gzip'
})
var json = ''
req
.pipe(createGunzip())
.on('data', chunk => { json += chunk })
.on('error', err => t.fail(err))
.on('end', () => {
t.deepEqual(JSON.parse(json), { you_know: 'for search' })
res.setHeader('Content-Type', 'application/json;utf=8')
if (count++ > 0) {
res.end(JSON.stringify({ you_know: 'for search' }))
} else {
setTimeout(() => {
res.end(JSON.stringify({ you_know: 'for search' }))
}, 1000)
}
})
}
buildServer(handler, ({ port }, server) => {
const pool = new ConnectionPool({ Connection })
pool.addConnection(`http://localhost:${port}`)
const transport = new Transport({
emit: () => {},
connectionPool: pool,
serializer: new Serializer(),
maxRetries: 3,
requestTimeout: 250,
sniffInterval: false,
sniffOnStart: false
})
transport.request({
method: 'POST',
path: '/hello',
body: { you_know: 'for search' }
}, {
compression: 'gzip'
}, (err, { body, meta }) => {
t.error(err)
t.deepEqual(body, { you_know: 'for search' })
t.strictEqual(count, 2)
server.stop()
})
})
})
t.end()
})