Comments (12)
Nope. I was not able to create a deterministic environment locally. I will try again
No need, I tracked it down.
What is happening is that undici is establishing a new connection for every POST, and we are paying the TLS price. This behavior is correct but strict, as in certain cases, the connection can be kept open.
This was introduced by @ronag in #76, and it made things too strict.
@ronag wdyt?
from undici.
Hi @mcollina
Thank you for your time. After some investigation, we found the problem. The default value of keepAliveTimeout
is 4 seconds. By scaling the number of pods in our application, requests were being distributed across too many pods causing some connections to remain idle for more than 4 seconds (and thus closed). Increasing that value to 60 seconds significantly improved the performance.
Sorry for the issue. I think we can close it 🙏🏼
from undici.
Have you got something to replicate this setup? How many http calls are you making?
from undici.
Have you got something to replicate this setup?
Nope. I was not able to create a deterministic environment locally. I will try again
How many http calls are you making?
We have 25/30 req/s (average)
from undici.
Yes, the implementation is too strict. Though it will require some thinking to make sure we don't introduce bugs by loosening it.
from undici.
I think the simplest way is to make pipelining equal to 1 a special case.
from undici.
I think the simplest way is to make pipelining equal to 1 a special case.
What about adding a new parameter to the pool configuration to let the user choose this behavior?
from undici.
@mcollina Actually I'm unsure if you are right. I don't see why it wouldn't re-use the connection, once the whole request/response cycle has completed.
from undici.
Application headers:
"Content-Type": "application/x-thrift",
"Accept": "application/x-thrift",
"Authorization": internalAuthToken,
"User-Agent": consumerKey,
from undici.
@ronag, you are right, the socket is correctly reused:
import { createServer } from 'node:http';
import { request } from './index.js';
import { setTimeout as sleep } from 'node:timers/promises';
import { strictEqual } from 'node:assert';
let lastSocket = null;
const server = createServer((req, res) => {
console.log('request ', req.url, req.method);
if (lastSocket) {
res.end(JSON.stringify({ same: lastSocket == req.socket }));
} else {
res.end(JSON.stringify({ noSocket: true }));
}
lastSocket = req.socket;
})
await new Promise((resolve) => server.listen(3000, resolve));
{
const { body } = await request('http://localhost:3000', {
method: 'POST',
body: JSON.stringify({ hello: 'world' })
});
console.log(await body.json());
}
await sleep(1000);
{
const { body } = await request('http://localhost:3000', {
method: 'POST',
body: JSON.stringify({ hello: 'world' })
});
const { same } = await body.json();
strictEqual(same, true);
console.log('same socket');
}
server.close();
So I guess that whatever combination of inputs you are using @Gigioliva is causing undici to create a new socket every time.
Can you create a small reproduction of what you are doing?
from undici.
So I guess that whatever combination of inputs
and server...
from undici.
Can you create a small reproduction of what you are doing?
I will try 😅 the system is quite complex to reproduce...I will start from a simple setup and add new steps until the problem also occurs locally
from undici.
Related Issues (20)
- Fetch fails for responses with http status 421 when the request has a body
- Issue importing RetryAgent in TypeScript HOT 2
- Object.Fetch failed cause: other side closed HOT 1
- CI: CodeCov coverage, select only one source for coverage
- web specs better util.inspect output HOT 4
- There seems to be a syntax error in the 'lib/web/fetch/util.js' file, causing a compilation error. HOT 2
- ProxyAgent sends wrong SNI to proxy HOT 2
- Benchmarks and Optimizations
- undici npm package has no readme HOT 2
- tests failing in node 21 HOT 3
- test against Node.js nightlies HOT 4
- Wasm SIMD unsupported HOT 11
- Move logic to interceptors HOT 2
- EventSource properties are not configured properly HOT 6
- test\client-request.js is consistently failing HOT 1
- TypeError: fetch failed due to ECONNREFUSED cannot be caught and handled HOT 2
- Unexpected token on class private field check with in operator HOT 21
- Option mismatch in RetryHandler HOT 2
- Uncaught TypeError: fetch failed. node:internal/deps/undici/undici:12345:11 HOT 1
- Retry with timeout HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from undici.