Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

My favorite signal surprise was running nginx and/or httpd in the foreground and wondering why on earth it quit whenver i resized the window.

Turns out, they use SIGWINCH (which is sent on WINdow CHange) for graceful shutdown.

It's a silly, silly problem.



> Turns out, they use SIGWINCH (which is sent on WINdow CHange) for graceful shutdown.

That’s … that’s even worse than people who send errors with an HTTP 200 response code.


Disagree. Annoyingly there is a reasonable case for 200 but with an error, if http is your transport but not your application, then 200 says "yes, the message was transfered and understood correctly, here is your response" which may be an error response from the application


If you’re using HTTP for something other than transferring hypertext — i.e., if your application is not a hypermedia application — then you are doing something just as wrong as encoding IP in DNS packets or email messages. Don’t do that. It’s wrong, even if it is technically interesting.

If, OTOH, your application is a hypermedia application, then returning a success status for errors is just wrong.


Every JSON API under the sun disagrees, but I do agree in principle. People very much like using HTTP as a JSON (or XML) transfer protocol


This ship sailed the day the first HTTP proxy was installed, and likely well before that.


Sorry, what? HTTP is perfectly fine for APIs which are not hypermedia.


For example: Apache (httpd) replaces the 4xx and 5xx response body with its own content instead of whatever you'd returned from an external handler like wsgi. You have to use a 2xx (except for 204) to get a relevant error message back out.


> For example: Apache (httpd) replaces the 4xx and 5xx response body with its own content instead of whatever you'd returned from an external handler like wsgi.

This is the default behavior. Apache httpd can be configured to produce different responses by way of ErrorDocument[0]. From the documentation:

  Customized error responses can be defined for any HTTP
  status code designated as an error condition - that is,
  any 4xx or 5xx status.
HTH

0 - https://httpd.apache.org/docs/trunk/custom-error.html


Even with custom error documents configured in the web server, you still lose the application-specific (and probably request- and error-specific) message generated by the application itself.


Yeah, this is how we ran across it - whoever originally wrote a particular feature was trying to do the right thing by using an HTTP error code, but with a message that would be presented to the user about why that operation failed. A generic response wouldn't work, there were multiple possible reasons all fixable by the user, and tying a whole error code to one specific feature would've probably been a bad idea anyway.


Which is why "you resized the terminal window, clearly you meant to shut down this web server" is even crazier, yes


Indeed. That is particularly good at violating the principle of least astonishment


That's ... not what most people are doing. People send _application_ errors on HTTP 200 response codes, because HTTP response codes are for HTTP and not applications. Most "REST" libraries and webdev get this wrong, building ever more fragile web services.


Applications using status codes is useful because it can tell browsers and load balancers to not cache the page in a uniform way.


I don't think the distinction is as clear-cut as you're making it out to be.

For example, HTTP 409 Conflict generally means an application-level conflict (e.g. an optimistic concurrency mechanism detected a conflict).

HTTP 422 Unprocessable Entity is also usually an application-level error (e.g. hash validation failure, or identifier not recognized by the server).


Task failed successfully


y'know...what really is an error, anyway?


For what is an error, if not a success at failing?


Exactly. Gotta be happy you got a response at all!


In my day, successful commands output nothing at all, so it would seem that a blank page is the only truly error-free result.


Why? That's what SIGTERM is for.


No clue what the decision making process was.

There's a bug report for httpd dating back to 2011[0]. The nginx mailling list also has a grumpy person contemporary with that[1].

My guess is someone thought "httpd is a server running somewhere without a monitor attached, why on earth would it get a SIGWINCH!? surely it's available to use for something completely different", not considering users running it in the foreground during development. Nginx probably followed suit for convention, but that's pure speculation on my part.

Also that was before docker really took off (I'm not sure if it was around in 2011 yet; still in it's infancy maybe). Running it in the foreground didn't happen as much yet. People were still using wamp or installing it via apt and restarting via sudo.

[0] https://bz.apache.org/bugzilla/show_bug.cgi?id=50669

[1] https://mailman.nginx.org/pipermail/nginx/2011-August/028640...


> why on earth would it get a SIGWINCH!?

Reminds me of those "/* not reached */" stories.


They use SIGWINCH for gracefully shutting down workers but not the main process [0]. SIGQUIT is used for a graceful shutdown and SIGTERM for a sort of graceful shutdown (with timeouts).

SIGWINCH is apparently used for an online upgrade [1]. Because it only shuts the workers down you can quickly transition back to the old binary and old configuration if there's a problem, even after upgrading the binary or config stored on the hard drive.

I'm sure there are other ways to get a similar capability, but this set of signals is apparently what they came up with.

[0] http://nginx.org/en/docs/dev/development_guide.html#processe...

[1] https://www.digitalocean.com/community/tutorials/how-to-upgr...


I tried to find out why.

Unfortunately the change that introduces it predates the official release by a few months. And predates the mailing list by about a year:

https://trac.nginx.org/nginx/changeset/5238e93961a189c13eeff...


ok, I found a commit in 2005, coming about because linuxthreads was interfering with the SIGUSR1 signal.

It looks like they wound up making it platform specific, so BSDs and unix like operating systems might still use SIGUSR1.

https://github.com/apache/httpd/commit/395896ae8d19bbea10f82...


I don't know whether to laugh or cry.


definitely laugh! life's too short, you'll never get out alive :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: