This is the second or third "it's CGI again" thing I've seen in the past year. While these things are cool and definitely have their place, it's still worth noting that process per connection scales fairly poorly, simply because processes and forking are relatively expensive, and therefore it's probably unwise to deploy something like this in production anymore. It is what it is, I suppose.
Websocketd
61–70 of 233 posts
Re: Websocketd
#62Earlier quoted context omitted.
Is that a feature or a bug of *nix?
Not really; IIRC forking is more expensive on NT, and *nix processes/threads tend to be fairly cheap. It might be a generally expensive model, and threads/pools are probably the better-scaling option regardless of OS.
*On the Windows subsystem, of course. There's the lower level ZwCreateProcess function which can/could be used to fork, but it's undocumented and I believe it only existed for the old SfU. Now that that's gone and Linux Subsystem uses something called Pico Processes, I'm guessing this old fork flag is pretty much unsafe to use for anything at all.
Re: Websocketd
#63It looked simple enough, but I was curious about the threading example on https://github.com/joewalnes/websocketd/wiki/CPP-Input-Outpu... The variable `count` appears to be incremented non-atomically from two different threads. Is that safe in C++?
count++;
pthread_mutex_lock(&m);
since the reader already holds the mutex while reading `count`.Re: Websocketd
#64Earlier quoted context omitted.
But websocket connections are usually long lasting. So the cost of the fork is less important.
It probably scales better than a forking HTTP server, but probably not much; modern HTTP connections tend to be at least a little bit long lasting and few people would dare serve a large site on a forking webserver (in part thanks to the fact that most webservers have moved on to workers or event loops.) It certainly would hold up inordinately poor to a DDoS attack.
But CGI doesn't fork per TCP connection; it forks per HTTP request/response.
Re: Websocketd
#65Earlier quoted context omitted.
Not that much on modern Linux/BSD systems at least. The kernel is smart enough to just copy fewer pages when forking not the entire parent process image.
Then you run a GC and dirty all your pages.
Re: Websocketd
#66Doesn’t this have an impedance mismatch? Stdin/out are stream based. Websocket is message based. There is no guarantee you can transmit the content of a single WebSocket message inside a single os read or write call. Unless you expect that on both sides messages might be fragmented across multiple calls and callbacks. But I don’t see the docs mentioning that.
Newlines. Each line written to STDOUT is sent as one frame, and each frame received is read from STDIN followed by a synthetic newline. The FAQ explains how to escape multiline messages (or binary data, presumably). https://github.com/joewalnes/websocketd/wiki/FAQ#how-can-i-s...
That should provides reliable framing on both sides. But as shown in the linked it page it also comes with the downside of not being able to send raw websocket messages which contain a new line - so it's not possible to port existing applications from other websocket servers to this one without having to change communication.
Re: Websocketd
#67Doesn’t this have an impedance mismatch? Stdin/out are stream based. Websocket is message based. There is no guarantee you can transmit the content of a single WebSocket message inside a single os read or write call. Unless you expect that on both sides messages might be fragmented across multiple calls and callbacks. But I don’t see the docs mentioning that.
Interested to know in what situations you anticipate this would cause problems?
However it looks like the Daemon might wait for a newline until it forwards everything as a message. Which at least fixes this problem, but might have other side effects.
Re: Websocketd
#68Earlier quoted context omitted.
Not that much on modern Linux/BSD systems at least. The kernel is smart enough to just copy fewer pages when forking not the entire parent process image.
Of course any UNIX-like worth its salt is going to support Copy on Write and whatnot. But even then, forking is still quite slow relative to not doing anything at all. Here's my point of view: 1. Forking is first and foremost a system call. (To be fair, I realize even memory allocation is much of the time, but still.) The kernel is going to do a bunch of work (as fast as it can, of course) and you're going to end up…
Re: Websocketd
#69Ok I know the software-today-is-so-bloated trope is overplayed but... "the UNIX way"? The compiled Linux x86_64 binary is 7 megabytes. All of System V combined was not that big.
Re: Websocketd
#70Earlier quoted context omitted.
It probably scales better than a forking HTTP server, but probably not much; modern HTTP connections tend to be at least a little bit long lasting and few people would dare serve a large site on a forking webserver (in part thanks to the fact that most webservers have moved on to workers or event loops.) It certainly would hold up inordinately poor to a DDoS attack.
> modern HTTP connections tend to be at least a little bit long lasting But CGI doesn't fork per TCP connection; it forks per HTTP request/response.