Skip to content

fasthttp: multi threading fix reads in the socket in linux#26478

Merged
spytheman merged 10 commits into
vlang:masterfrom
esquerbatua:feature/fasthttp_multithreading
Feb 4, 2026
Merged

fasthttp: multi threading fix reads in the socket in linux#26478
spytheman merged 10 commits into
vlang:masterfrom
esquerbatua:feature/fasthttp_multithreading

Conversation

@esquerbatua

@esquerbatua esquerbatua commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

fasthttp:

  • Allow to the user to select the family and max_request_buffer_size of the connection.
  • Fix read all of the data in the socket in linux.

veb:

  • Allows to run veb in multithreading with the flag: " -d new_veb"

@spytheman

Copy link
Copy Markdown
Contributor

@esquerbatua try v fmt -w vlib/fasthttp to fix the CI

@spytheman

spytheman commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

also v git-fmt-hook install can make it so that each commit also runs vfmt automatically
(has to be run while your working folder is inside the v repo)

@esquerbatua

Copy link
Copy Markdown
Contributor Author

Sorry I formatted the veb folder instead fasthttp, it's formatted now

@enghitalo

enghitalo commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

I recommend not changing the logic behind closing the client connection for now.
Or you could do it in a separate PR, so you'd have to handle things like the HTTP version and request header to make it more appropriate. In fact, the perfect solution for me would be for veb to have the power to close the connection whenever it wants, but I haven't found a clever way to do this without creating a bit of a mess. Although, regardless of how it's done, it would still be much better than dealing with request interpretation within FastHTTP

@esquerbatua

esquerbatua commented Jan 31, 2026

Copy link
Copy Markdown
Contributor Author

If I do not close the connection the client keeps waiting until timeout, tested.

@enghitalo

Copy link
Copy Markdown
Contributor

If I do not close the connection the client keeps waiting until timeout, tested.

This is the default expected behavior for http1.1

@enghitalo

Copy link
Copy Markdown
Contributor

@claude How connection should bahave in which http version? Show me the rfc reference.

@esquerbatua

Copy link
Copy Markdown
Contributor Author

• HTTP/0.9 (very old, single-request): one TCP connection, one request, server returns raw response then closes. (No formal modern RFC; historical notes only.) • No persistent connections, no headers, no request/response framing.

• HTTP/1.0 (RFC 1945): by default the server closes the TCP connection after the response; clients and servers may use the Connection: keep-alive extension to request persistence, but it is optional and not reliably supported by all implementations. • RFC: RFC 1945 (HTTP/1.0).

• HTTP/1.1 (message framing, persistent by default): connections are persistent by default (multiple requests/responses can be sent sequentially on the same TCP connection). Pipelining (sending multiple requests without waiting for responses) is defined but problematic in practice; implementations more commonly use sequential requests or upgrade to multiplexing (HTTP/2). The Connection header and hop-by-hop semantics are defined here. • Key RFCs: • RFC 7230 (HTTP/1.1 message syntax and routing) — see section on connection management and persistent connections (RFC 7230 §6).
• RFC 7231 (semantics) and the rest of the RFC723x family for HTTP/1.1.

• HTTP/2 (binary framing, multiplexed streams over one TCP connection): a single TCP connection carries many independent, interleaved request/response streams concurrently (no head-of-line blocking at the HTTP message level, though TCP-level HOL remains). Uses HPACK for header compression and has explicit stream and connection lifecycle rules. • Key RFCs: • RFC 7540 (Hypertext Transfer Protocol Version 2) — see multiplexing, streams, connection flow control.
• RFC 7541 (HPACK — header compression).

• HTTP/3 (HTTP semantics over QUIC): moves from TCP to QUIC (UDP-based transport), giving multiplexing without TCP head-of-line blocking and integrated stream- and connection-level flow/congestion control; uses QPACK for header compression with HTTP/3-specific considerations. • Key RFCs: • RFC 9114 (HTTP/3)
• RFC 9000 (QUIC: the transport)
• RFC 9204 (QPACK — header compression for HTTP/3)

Pointers / exact references to read

• HTTP/1.0: RFC 1945 — https://datatracker.ietf.org/doc/html/rfc1945
• HTTP/1.1 message framing & persistent connections: RFC 7230 — https://datatracker.ietf.org/doc/html/rfc7230 (see §6 on connection management/persistence)
• HTTP/1.1 semantics: RFC 7231 — https://datatracker.ietf.org/doc/html/rfc7231
• HTTP/2: RFC 7540 — https://datatracker.ietf.org/doc/html/rfc7540 ; HPACK: RFC 7541 — https://datatracker.ietf.org/doc/html/rfc7541
• QUIC (transport used by HTTP/3): RFC 9000 — https://datatracker.ietf.org/doc/html/rfc9000
• HTTP/3: RFC 9114 — https://datatracker.ietf.org/doc/html/rfc9114 ; QPACK: RFC 9204 — https://datatracker.ietf.org/doc/html/rfc9204

@esquerbatua

esquerbatua commented Feb 1, 2026

Copy link
Copy Markdown
Contributor Author

The point it's like if I use vweb or veb without flags, the service works as expected, if I use fast http, the connection keeps open

@spytheman

spytheman commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Can there be a separate thread, that loops over all current opened connections, every say 10 seconds, and closes them, if there were no activity on them for say 1 minute?

@enghitalo

Copy link
Copy Markdown
Contributor

@esquerbatua Can you share the code which you're facing issues?

@esquerbatua

esquerbatua commented Feb 1, 2026

Copy link
Copy Markdown
Contributor Author

@esquerbatua Can you share the code which you're facing issues?

The simplest veb server should give timeout in all of the request. I didn't have time to test it changing the handing of the connection close.

module main

import veb { Result }

pub struct Context {
	veb.Context
}

struct App {
}

fn main() {
	mut app := App{}

	veb.run_at[App, Context](
		mut app,
		host: '0.0.0.0',
		port: 8080,
		family: .ip,
	) or { panic(err) }
}

@['/']
pub fn (app &App) index(mut ctx Context) Result {
	return ctx.ok('')
}

@esquerbatua

Copy link
Copy Markdown
Contributor Author

Can there be a separate thread, that loops over all current opened connections, every say 10 seconds, and closes them, if there were no activity on them for say 1 minute?

Sorry if I'm wrong:

If we do that, always we are going to give extra time to all of the request, making veb or fasthttp so slow, make them useless with big load time and extra handle of the connection.
We should check if the connection have X request, process it in the same order that arrived. But that logic needs to be implemented.
Changing only the way that we close the connection we make fasthttp unusable.

@enghitalo

enghitalo commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Why not just close the connection at client side, as usual or handle Connection: close header at server veb side?

@enghitalo

Copy link
Copy Markdown
Contributor

The point it's like if I use vweb or veb without flags, the service works as expected, if I use fast http, the connection keeps open

I'm sorry, but I'm still struggling to understand how the connection remaining active after sending the reply could be a problem

@enghitalo

Copy link
Copy Markdown
Contributor

@esquerbatua

If I do not close the connection the client keeps waiting until timeout, tested.

The client doesn't have to wait for the connection timeout; it simply receives all the responses, check content-lenght and then closes automatically. Unless there's a problem with your client or the response you're sending.

@esquerbatua

Copy link
Copy Markdown
Contributor Author

I reverted the changes in the clousure as they are, shouldn't modify the old behaviour @enghitalo

@enghitalo

Copy link
Copy Markdown
Contributor

Thanks

@spytheman spytheman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it all ready now?

@esquerbatua

Copy link
Copy Markdown
Contributor Author

Is it all ready now?

yes

Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
Comment thread vlib/fasthttp/fasthttp_linux.v Outdated
// Read all available data from the socket
mut total_bytes_read := 0
mut all_data := []u8{cap: server.max_request_buffer_size}
mut readed_request_buffer := []u8{len: server.max_request_buffer_size, cap: server.max_request_buffer_size}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[]u8{len: server.max_request_buffer_size}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this it's not changed

@spytheman spytheman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @esquerbatua 🙇🏻 .

Thank you @enghitalo .

@spytheman spytheman merged commit e20a432 into vlang:master Feb 4, 2026
78 checks passed
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

Successfully merging this pull request may close these issues.

3 participants