I always felt that the web people were never about performance, since there were many "pure C" webdev attempts before without much success.
Nginx can very realistically handle 1-2M requests per minute on commodity hardware, and no customisation, and that's from the disk.
Were somebody really serious about web performance, I think going from millions of requests per minute, to millions of requests per second is 100% possible.
I worked on this problem around 6 years ago, when I had a task of squeezing HTTP, and network perf on some API servers close to hardware limits. The task was mostly about gluing DPDK to popular software: nginx, memcached, postgres.
I am very enthusiastic to see Libwebsockets getting glib support. Glib is a one of a kind piece of software in the C ecosystem with which you can adopt modern programming methods, and in general approach it as you do it in a big "platform" like environment like NODEJS. Glib is really undeserving neglected, and overlooked.
We all love to optimize but there is a point of diminishing returns. Scaling a cheap vm with CPU credits (i.e. it's not even supposed to have double digit CPU usage other than for short bursts) costs nothing compared to the salary involved with e.g. making something like that 2x or 3x faster. And the yields are terrible too, even if you succeed.
Say you are running 12 vms costing about 20/month. That should get you some CPU and modest amount of memory and would be something appropriate for a web server. Twelve of these means you have fail-over, multiple availability zones, and possibly even regions. Going from 12 to 6 would be a nice cost saving of about 120/month. Except now you have less bandwidth to go around and maybe a bit less resilience. That's a decent but not amazing freelance rate per hour. If you spend a week on implementing this, the return on investment (i.e. your time) would be 40 months (assuming an unreasonable 40 hour work week), or about 3 years a and a bit before you earn back the expense of your time. Now say that instead of spending that time, you simply scale to 24 servers: i.e. you double your cost from 240 to 480 per month. Or about four hours of your hypothetical hourly rate. Or about half a day. So a week of your time still adds up to nearly a year of simply running at 2x the capacity.
If you are any good, your rate might be higher and the tradeoff is even worse. Not even worth having meetings about. Using C for this stuff means hiring more expensive C developers and making a bad deal even worse. The smart way to get performance is to have those C developers work on the OSS infrastructure we all love to use. It will trickle down and get us decent performance elsewhere. Nodejs is actually built on lot of C/C++ libraries and benefits from a lot of cumulative optimizations that have gone into these libraries. That's why it is so competitive in this space. There are a gazillion other languages to consider with similarly good enough performance and throughput. C is a last resort when performance wins over security and stability concerns. Sometimes it does, but mostly it doesn't make sense from a cost point of view.
Even in categories where C/C++ are more performant, other languages are not that far behind.
If at all possible, we should not use memory unsafe languages for anything, especially something exposed as a server. No mater how careful you are, and with all the tooling available, majority of exploits in popular software happen due to memory unsafe languages.
[1] https://www.techempower.com/benchmarks/#section=data-r20&hw=...
You use C judiciously on the most performance demanding tasks, while trying to bring the overall task itself closer to some simple algorithm, on which you can later throw heavy verification, like formal verification, valgrind it to death, fuzzing etc.
The current wave of "new age" computer languages like Koltin, Go, Rust have a very noisy activist userbase which tend to extol some very simple, obvious things as ultimate virtues.
Oh, and the silicon itself becomes adapted to the paradigms presented by those programming languages, since C was designed to work on the existing silicon. Forcing entirely new hardware designs to meet an evolving and always-changing software paradigm is an expensive proposition in a commodity market and it will take either a lot of central control and will power or a lot of time.
Borrowing rules are still enforced (eg you cannot write with a read-only pointer)
Overall the experience was good. It's simple, to the point. Configuration of the library is a bit like dark magic though, not much documentation.
> Has anyone used this in a multithreaded implementation
It's an event loop based library, so the point is more to have a single asynchronous main thread that fetches the messages, which you can dispatch to threads for processing if you wish.
Disclaimer: I work at Cloudflare.
It's actually fairly simple to use openssl directly if you have a good handle of sockets in general, it's basically just a case of doing some initialisation and using SSL_write/SSL_read in place of whatever write/read functions you were using before to write to the socket
The underlying library will take care of buffering that, and the size of that buffer is unbounded. In most of them there is no way to know how much is buffered.
But with libwebsocket, it will call a callback written by you, it will call it every time it is ready to send. And then you have to call a write function that does not guarantee you it will write the whole buffer you give it.
This can be useful for web based games, you keep the last version of the position of each object, and send them one by one when the client is ready to receive. The memory usage will then be bounded to: size of message * number of objects + number of players (each player can have a message that is currently kept in memory until it is entirely sent, since multiple calls to the callback may be required to send a whole message.
The libwebsocket site claims that it is the receiving side that decides when it is ready to send. I don't know exactly how it is determined but I think the sender uses TCP ACKs, the window size...
I'd prefer this well written and working minimal example (one of many) to API documentation 99 times out of 100.
e.g. when a TLS cert is renewed/replaced, how to deal with that in an already running websocket.
https://libwebsockets.org/git/libwebsockets/tree/minimal-exa...
https://libwebsockets.org/git/libwebsockets/tree/lib/secure-...
I haven't been putting much time into it anymore lately, but I intend to create a bunch of language bindings for it soon so you can write plugins in other languages too such as Python, C++, Rust, etc. Should be interesting.