Live data from Hacker News

Websocketd

websocketd.com

191–200 of 233 posts

Re: Websocketd

#191
post #125
post #115

Earlier quoted context omitted.

The myth that fork is expensive is pervasive, and speaking to the ways that it is true†, well: performance is relative. fork() only takes around 8ms on my Linux machine and I can get 100,000 posix_spawn() per second there with 100MB RSS. That's "fast enough" for a large number of applications. †: fork() is a lot slower (over 20x) on Windows

8ms per fork means you can only accept 125 connections per second. (per core) That means it's only viable for connections where the connection is very long lived and messages are very sparse (because context switches).

125 connections per second is vastly more than most business applications will ever see in their entire lifetimes. That means this approach is viable most of the time for most of the things people write.

Everyone likes to think they're the next big unicorn and code for it; you're wasting your time, you're not.

Re: Websocketd

#192
post #11
post #2

So, all of the same sorts of scaling problems as inetd?

Well, unless it's doing something exceedingly clever, it looks like it will be launching one process per connection. For communication servers, this could prove a challenge – you'll probably want to use some kind of pub-sub architecture. By the time you've gone down that road, you could've gone down one of the more robust paths. Still, this looks great for smaller apps. And, it seems a great way to prototype – especi…

> Still, this looks great for smaller apps. And, it seems a great way to prototype – especially if your favourite language doesn't have great websocket support.

Totally agree. inetd is a pretty good model, it just falls down in the face of thousands of slow, low-computational effort connections tying up gigabytes of RAM. That and most schedulers seem to struggle with that number of threads.

Re: Websocketd

#193
This is really useful for building one of utility websites. I used this in one of my previous companies to tail the logs on our little QA server and push them via websocktd to an internal web page.

Re: Websocketd

#194
post #56

Doesn’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...

Which is a common anti-pattern. You take a medium that is fully transparent to binary data, and then needlessly restrict it to text. There are excellent ways of packetizing binary data in a stream, most notably SLIP.

Re: Websocketd

#195
post #164

Earlier quoted context omitted.

Yeah, people just seemingly realized that there's nothing special about FastCGI that couldn't be done with plain http. And as a bonus, the app itself can work as a server in the dev env, and testing is simpler. (Only, CGI managed to get headers sorta right by embedding them in protocol vars and not the other way around.)

But I already do this and that doesn't answer the question about the difference between fastCGI and what everyone else seems to be using, but not explaining, is a method of direct integration or ability to talk with the server without CGI/fastCGI. After doing a little research, it appears this can be done by implementing or writing modules that will talk directly to server internals if I'm understanding this correctl…

You don't usually need to talk to the server from the app. Pretty much the only thing needed in practice is returning an internal redirect that ends up served by another path (with error pages being variations of this). This is solved fine with an HTTP header in the response.

CGI and FastCGI actually have the exact same flow of information as HTTP (to my knowledge). Anything else is either implemented on top of that, or you'll need a module reaching into internal functions.

Re: Websocketd

#196

Earlier quoted context omitted.

I was going to mention CPU context switching as well, it's very expensive even when you don't account for the initial fork overhead but I guess it's definitely a better idea than CGI for HTTP given the long lived connection. In an ideal scenario, you shouldn't have more active processes than you have CPU cores. As soon as that happens, context switching kicks in and performance degrades sharply.

Does this concern hold for containers per machine?

Yes I would think so because containers run on top of the OS.

If you can run multiple containerized apps side-by-side on the same machine at the same time on a single CPU core, then you can be sure that there is some kind of context switching happening.

Modern Operating Systems are good at minimizing the amount of context switching. If you run 4 CPU-intensive processes at the same time on a machine which has 4 CPU cores, then the OS will typically assign each process to a different CPU core (with minimal context switching). Then if you launch a 5th CPU-intensive process, then the OS will have no choice but to start doing context switching since it doesn't have any idle cores left.

On Linux, based on tests I did a couple of years ago with a multi-process WebSocket server, I can confirm that the penalty of context switching is proportional to the CPU usage of each process. So for example, if you have a very CPU-intensive process sharing a CPU core with a non-intensive process, then the penalty will be small, but if you have two intensive processes sharing the same core, the penalty will be high.

Re: Websocketd

#197

Earlier quoted context omitted.

It's closer to FCGI, since Lambda processes aren't restarted for each new request.

Question: why doesn't Amazon just use the standard FCGI interface, then?

Maybe they are; as far as I know, the protocol they use to communicate with the worker isn't specified, all they say is "implement a function with this signature, then import our SDK, and it will call your function". This gives them the flexibility to switch protocols at will, at the cost of having to implement these SDKs.

That said, building a FCGI "bridge" isn't hard, it's just that nobody cared enough to do it.

Re: Websocketd

#198
post #107

Earlier quoted context omitted.

> I have extreme doubts that threads beat goroutines Why? Goroutines use the same syscall heavy non-blocking IO as event loops, just with coroutines for programmer convenience. The biggest difference between Goroutines and pthreads is that Goroutines only have a 2kb default stack size and pthreads have a 2MB stack. In high thread concurrency situations it's common to turn the pthread stack size down to 48 or 64kb to…

1, because the Goroutine context switch is Insanely cheap. There's no preempting, the scheduler runs on function calls and the context switches are very cheap - just swapping a few registers I believe. This means a single thread could blow through an enormous amount of goroutines in no time. I know, kernel mode switches are fast, we optimize this all the time, but doing nothing in place of doing something will always…

Completely true, but in a realistic small workload situation with a 0.5ms response time the pthread context switch is already only 2usec or 0.4% of the total time. Goroutines can be infinitely faster and not be able to meaningfully improve overall performance.

This is why thread per request servers like jlhttp are right up there with fasthttp etc in terms of total throughput.

https://www.techempower.com/benchmarks/#section=data-r17&hw=...

Re: Websocketd

#199

Earlier quoted context omitted.

Traditionally in Unix and Windows contexts, "processes" means separate memory address spaces and OS-guaranteed isolation, and "threads" mean threads of execution that have shared access to one address space. Erlang processes are threads as seen by the OS, but the Erlang runtime implements process-y restrictions that enforce isolation and forbid shared memory between Erlang processes that do infact exist as threads in…

> Erlang processes are threads as seen by the OS Not true, Erlang processes are userspace threads, not kernel threads. It's an M:N model -- you can run thousands of Erlang processes on a single OS thread. See: http://erlang.org/euc/08/euc_smp.pdf and note that each "scheduler" runs on a single OS thread, whereas many processes can run on each scheduler.

Good correction. But for the purpouses of this discussion re the processy-nature of Erlang processes, it's an implementation detail without difference in programming semantics.

Re: Websocketd

#200
post #89

Earlier quoted context omitted.

> I wonder why Go is working where the others went away from it? Quite frankly, because Go developers don't learn from other's mistakes and reinvent square wheels. Kernel threads will always be better and faster than usermode threads. This is because any inefficiency in threading comes from the scheduler. Your usermode scheduler will always necessarily be slower and worse; it just makes so much sense to put your sche…

>Quite frankly, because Go developers don't learn from other's mistakes and reinvent square wheels. Your response doesn't even start on the right foot, since Java never used green threads for performance and therefore is not a good place to hedge this argument at. Citation needed if you're going to start with that. You can also go ahead and insult the Erlang developers for Processes since they did it first: http://er…

Goroutines only have a 2kb initial stack since 1.4, AFAIK? It was originally 4kb, then 8kb to avoid split stacks, then back to 2kb, I think?
Post reply on HN