Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unidict fetch leaked if using Request object as argument #1823

Closed
stalkerg opened this issue Dec 21, 2022 · 13 comments · Fixed by #2049
Closed

unidict fetch leaked if using Request object as argument #1823

stalkerg opened this issue Dec 21, 2022 · 13 comments · Fixed by #2049
Labels
bug Something isn't working

Comments

@stalkerg
Copy link

Bug Description

unidict leaked if using Request, for example:

export function create_fetch({ event, options, state, get_cookie_header }) {
	return async (info, init) => {
		return await fetch(new Request(info, init));
	};
}

I found it in SvelteKit inside this issue sveltejs/kit#8239

Reproducible By

See SvelteKit issue.

Environment

Ubuntu and Gentoo with the latest node 18

@stalkerg stalkerg added the bug Something isn't working label Dec 21, 2022
@stalkerg
Copy link
Author

Seems like we trying to copy AbortController signal from the income Request here:
https://github.com/nodejs/undici/blob/main/lib/fetch/request.js#L106

and after locking into the arrow function, such signal from the previous Request:
https://github.com/nodejs/undici/blob/main/lib/fetch/request.js#L351

seems like we never run finalization for the original signal. Not sure here, but a bug exists... maybe we should do clone instead copy only a few fields?

@ronag
Copy link
Member

ronag commented Dec 21, 2022

Isn't this just a case of the finalisation registry not yet running the finaliser?

@stalkerg
Copy link
Author

hmm seems like it's never running, and at the same time this:

export function create_fetch({ event, options, state, get_cookie_header }) {
	return async (info, init) => {
		return await fetch(info, init);
	};
}

working prefect.

@stalkerg
Copy link
Author

Seems like this https://github.com/nodejs/undici/blob/main/lib/fetch/request.js#L337 is needed only if init.signal exist, for the case when we just copy the ac signal from the original Request we shouldn't follow it.

ronag added a commit that referenced this issue Dec 21, 2022
@stalkerg
Copy link
Author

As I understand, we shouldn't recreate the Request inside fetch if we have already received the Request.
Even if we made Request based on a Request, it should be copied without the following:
https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#parameters

Maybe I do not fully understand the concept behind this, but it seems like we are doing something wrong now.

@stalkerg
Copy link
Author

Sorry, for too many words here. I checked the specification https://fetch.spec.whatwg.org/#fetch-method and it seems like, currently, everything is implemented right. I still have questions about such specifications but this question is outside this issue.
Also, seems like SveltKit fetch like wrapper is not fully correct just because it's not a fetch anymore, but it's also a different topic.

@ronag big thanks for a fast fix.

@stalkerg
Copy link
Author

@ronag can you reopen? The latest changes make memory leak again.

@ronag ronag reopened this Mar 25, 2023
@ronag
Copy link
Member

ronag commented Mar 25, 2023

@stalkerg We need a minimal repro to properly solve this.

@stalkerg
Copy link
Author

stalkerg commented Mar 25, 2023

@ronag can you try repro from #46435 ? But seems like this time, the reason for the memory leaks is not in undici but I am still trying to find. It's surprisingly coincident with SvelteKit update to the latest undici version which was reverting previous changes. :)
sveltejs/kit#9512

@stalkerg
Copy link
Author

stalkerg commented Mar 25, 2023

Okey, it's undici again because the new version is now merged into shims.js of adapter-node in SvelteKit. https://github.com/sveltejs/kit/blob/master/packages/adapter-node/src/shims.js

Yes, I can confirm now the new undici memory leaked again.

@jamesdiacono
Copy link

The reproduction in #46435 causes a memory leak in Node.js v19.8.1.

@stalkerg
Copy link
Author

@jamesdiacono thanks, I had a theory that it was fixed in v19.3 but seems like no, and we have some GC issue that can't collect self-linked things properly.
Interesting can we make repro without undici code?

@jamesdiacono
Copy link

The problem was fixed, but has now regressed. I have only experienced the leak in relation to fetch.

ronag added a commit that referenced this issue Apr 7, 2023
@ronag ronag mentioned this issue Apr 7, 2023
ronag added a commit that referenced this issue Apr 8, 2023
ronag added a commit that referenced this issue Apr 8, 2023
ronag added a commit that referenced this issue Apr 8, 2023
ronag added a commit that referenced this issue Apr 8, 2023
ronag added a commit that referenced this issue Apr 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants