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

A new server archtecture #127

Closed
kazu-yamamoto opened this issue Jul 1, 2024 · 3 comments
Closed

A new server archtecture #127

kazu-yamamoto opened this issue Jul 1, 2024 · 3 comments

Comments

@kazu-yamamoto
Copy link
Owner

kazu-yamamoto commented Jul 1, 2024

GHC 9.6 provides listThreads finally.
Watching the number of threads in http2 using listThreads revealed that a lot of threads are instantly spawn due to forkAndEnqueueWhenReady.
One waits for TBQ and the other waits for stream window.

To reduce the number of threads, I would like to propose another architecture for servers.
Stop using the worker pool model.
Rather, one thread is spawn for each stream.
The number of threads follows maxConcurrentStreams.

Each designated thread feeds an output chunk to the output queue from a file or streaming data repeatedly.
I guess that the complicatedDynaNext is not necessary anymore.
This should drastically simplify Sender.
That is, Sender just packs output chunks from the output queue.

Stream window should be taken care by each designated thread.
Connection window should be taken care by Sender.

@edsko @FinleyMcIlwaine What do you think?

@kazu-yamamoto
Copy link
Owner Author

DynaNext cannot be removed because Sender owns confWriteBuffer.
Works cannot manipulate the buffer.
But I think it is still possible to reduce the number of threads.

@edsko
Copy link
Collaborator

edsko commented Jul 3, 2024

I think in principle this makes sense. As you already point out, having threads per stream avoids the deadlock that we ran into in kazu-yamamoto/network-control#4 . Indeed, in grapesy (my gRPC library that sits on top of http2 which has been motivating all the PRs that we've been submitting the last year), I spawn two threads for each stream, one to read incoming messages and one to send outgoing messages.

The devil is always in the detail of course; some rethinking of the architecture might be useful, but without actually thinking it through completely it's hard for me to really say whether this will be an overall improvement or not.

That being said, I think if the goal is simplification of the model, and making the code easier to understand, I'm all for it; if the goal is merely to reduce the number of threads, then I'm less convinced that it's terribly useful; threads in Haskell are cheap enough. Indeed, the number of concurrent streams is significantly higher than the number of workers currently employed by http2 (*).

(*) Caveat: this is actually only true for non-streaming bodies; grapesy exclusively uses streaming requests and responses, which means that we actually have as many workers as there are streams, because http2 will spawn a new worker each time a streaming response is initiated.

@kazu-yamamoto
Copy link
Owner Author

Done via #130.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants