-
Notifications
You must be signed in to change notification settings - Fork 271
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
Memory growth when grpc-web streaming #511
Comments
Unfortunately that's an expected behaviour from the current implementation. Currently gRPC-Web protocol implementation builds on top of XHR API which does not actually have any concept of streaming - instead protocol parser simply slices the tail of the XHR response as new bytes arrive (see the code here: https://github.com/grpc/grpc-dart/blob/master/lib/src/client/transport/xhr_transport.dart#L80-L92), which means the browser is slowly accumulating more and more data in memory (the concatenation of all streaming responses), because it thinks that the whole response to XHR is needed and there is no way to discard already processed chunks. To address this memory leak one would need to reimplement gRPC-Web transport on top of a streaming friendly Fetch API (or WebSocket API - though WS have their own problems as far as I know). |
So I'm working on something for this and it's mostly working, but certain calls seem to be failing for some reason. There's actually hundreds of calls that are working before I get to these few that are failing. The problem seems to be that I'm creating a body string of 70 characters, but for whatever reason fetch is putting a content-length of 72 in the header so the response I get back is unexpected eof which obviously makes sense because I'm sending 70 bytes and they're expecting 72. I'm just using I used chrome developer tools and copied the request as a fetch request from xhr and my fetch code and they're both completely identical except for the content-length. An example of the data in question is:
Note that it was modeled after xhr_transport with |
Ok I have a better understanding of the problem after looking at it a bit more. I think the issue is that the dev tools only show me the body value as a string rather than in bytes. It's the bytes that are >=128 that result in more than 1 byte and the mismatching content-length which I assume is related to the encoding javascript uses for strings. The data really needs to be |
I currently have an application that streams frames over grpc to flutter mobile and web clients. When running in mobile, the memory seems stable but when doing it in web it appears the data coming from GRPC never gets garbage collected and memory just continues to grow (until the browser runs out of memory). The entirety of these messages are GC'd when the stream is closed but I need to keep the stream open (live video). Is there a way to release these messages as they are processed? I'm wondering if I'm missing something simple. I know grpc-web is done over http but surely this is possible?
Note: the code I wrote is basically the same between platforms and it uses the GrpcOrGrpcWebClientChannel.
Version information:
url: "https://github.com/grpc/grpc-dart.git"
ref: f23070e
version: "3.0.1-dev"
Repro steps
Expected result: Data is garbage collected after being processed
Actual result: Data sticks around and causes memory to grow until out of memory.
Details
Memory from Mobile (looks reasonable)
Memory from Web (constantly increasing)
The text was updated successfully, but these errors were encountered: