mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Avoid ECONNRESET errors on idle timeout (#162947)
### Summary Address https://github.com/elastic/kibana/issues/82002 and https://github.com/elastic/kibana/issues/75440 I think I found a breakthrough for this flaky behavior. I run the integration test 800x locally, with different settings: Adjusting both the delayed emission (send 1 char at a time), and the socket idle timeout to have exacly the same value (e.g. `10 millis`), I managed to get the `ECONNRESET` 100% of the times. Thus, IIUC the ECONNRESET happens when the client tries to send a character over the socket and at the same time the server responds with the idle timeout. Adjusting the values so that the delay between character emissions is significantly larger than the idle timeout, e.g. 20 vs 5, I get `socket hang up` 100% of the times. Flaky Test Runner Pipeline - 300x 🟢 https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4030
This commit is contained in:
parent
0e904b8c5d
commit
721d68a890
3 changed files with 20 additions and 42 deletions
|
@ -408,7 +408,7 @@ describe('Options', () => {
|
|||
});
|
||||
|
||||
describe('idleSocket', () => {
|
||||
it.skip('should timeout if payload sending has too long of an idle period', async () => {
|
||||
it('should timeout if payload sending has too long of an idle period', async () => {
|
||||
const { server: innerServer, createRouter } = await server.setup(setupDeps);
|
||||
const router = createRouter('/');
|
||||
|
||||
|
@ -420,7 +420,7 @@ describe('Options', () => {
|
|||
body: {
|
||||
accepts: ['application/json'],
|
||||
},
|
||||
timeout: { idleSocket: 10 },
|
||||
timeout: { idleSocket: 5 },
|
||||
},
|
||||
},
|
||||
async (context, req, res) => {
|
||||
|
|
|
@ -53,7 +53,7 @@ export class CorePluginRouteTimeoutsPlugin implements Plugin {
|
|||
body: {
|
||||
accepts: ['application/json'],
|
||||
},
|
||||
timeout: { idleSocket: 10 },
|
||||
timeout: { idleSocket: 5 },
|
||||
},
|
||||
path: '/short_idle_socket_timeout',
|
||||
validate: {
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { Test } from 'supertest';
|
||||
import { PluginFunctionalProviderContext } from '../../services';
|
||||
import type { Test } from 'supertest';
|
||||
import type { PluginFunctionalProviderContext } from '../../services';
|
||||
|
||||
export default function ({ getService }: PluginFunctionalProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/75440
|
||||
describe.skip('route', function () {
|
||||
describe('route', function () {
|
||||
describe('timeouts', function () {
|
||||
const writeBodyCharAtATime = (request: Test, body: string, interval: number) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -45,7 +44,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
.set('Transfer-Encoding', 'chunked')
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 10);
|
||||
const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 20);
|
||||
|
||||
await result.then(
|
||||
(res) => {
|
||||
|
@ -65,7 +64,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
.set('Transfer-Encoding', 'chunked')
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 10);
|
||||
const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 20);
|
||||
|
||||
await result.then(
|
||||
(res) => {
|
||||
|
@ -107,7 +106,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
.set('Transfer-Encoding', 'chunked')
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const result = writeBodyCharAtATime(request, '{"responseDelay":0}', 10);
|
||||
const result = writeBodyCharAtATime(request, '{"responseDelay":0}', 20);
|
||||
|
||||
await result.then(
|
||||
(res) => {
|
||||
|
@ -119,44 +118,23 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
);
|
||||
});
|
||||
|
||||
it('should timeout if servers response is too slow', async function () {
|
||||
// start the request
|
||||
const request = supertest
|
||||
it('should timeout if servers response is too slow', async () => {
|
||||
await supertest
|
||||
.post('/short_idle_socket_timeout')
|
||||
.send({ responseDelay: 100 })
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Transfer-Encoding', 'chunked')
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const result = writeBodyCharAtATime(request, '{"responseDelay":100}', 0);
|
||||
|
||||
await result.then(
|
||||
(res) => {
|
||||
expect(res).to.be(undefined);
|
||||
},
|
||||
(err) => {
|
||||
expect(err.message).to.be('socket hang up');
|
||||
}
|
||||
);
|
||||
.set('kbn-xsrf', 'true')
|
||||
.then(() => expect('to throw').to.be('but it did NOT'))
|
||||
.catch((error) => expect(error.message).to.be('socket hang up'));
|
||||
});
|
||||
|
||||
it('should not timeout if servers response is fast enough', async function () {
|
||||
// start the request
|
||||
const request = supertest
|
||||
it('should not timeout if servers response is fast enough', async () => {
|
||||
await supertest
|
||||
.post('/longer_idle_socket_timeout')
|
||||
.send({ responseDelay: 100 })
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Transfer-Encoding', 'chunked')
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const result = writeBodyCharAtATime(request, '{"responseDelay":100}', 0);
|
||||
|
||||
await result.then(
|
||||
(res) => {
|
||||
expect(res).to.have.property('statusCode', 200);
|
||||
},
|
||||
(err) => {
|
||||
expect(err).to.be(undefined);
|
||||
}
|
||||
);
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue