0

In my application I need to "simulate" a HTTP timeout. Simply put, in this scenario:

client -> myapp -> server

client makes a HTTP POST connection to myapp which forwards it to server. However, server does not respond due to network issues or similar problems. I am stuck with an open TCP session from client which I'll need to drop.

My application uses web.py, nginx and uwsgi.

I cannot return a custom HTTP error such as 418 I am a teapot - it has to be a connection timeout to mirror server's behaviour as closely as possible.

One hack-y solution could be (I guess) to just time.wait() until client disconnects but this would use a uwsgi thread and I have a feeling it could lead to resource starvation because a server timeout is likely to happen for other connections. Another approach is pointed out here however this solution implies returning something to client, which is not my case.

So my question is: is there an elegant way to kill a uwsgi worker programmatically from python code?

So far I've found

  • set_user_harakiri(N) which I could combine with a time.sleep(N+1). However in this scenario uwsgi detects the harakiri and tries re-spawning the worker.
  • worker_id() but I'm not sure how to handle it - I can't find much documentation on using it
  • A suggestion to use connection_fd() as explained here
  • disconnect() which does not seem to do anything, as the code continues and returns to client
  • suspend() does suspend the instance, but NGINX returns the boilerplate error page

Any other idea?

UPDATE

Turns out it's more complicated than that. If I just close the socket or disconnect from uwsgi the nginx web server detects a 'server error' and returns a 500 boilerplate error page. And, I do not know how to tell nginx to stop being so useful.

lorenzog
  • 3,483
  • 4
  • 29
  • 50
  • Just for the reference: Comcast can be used to simulate bad network connections, but not sure if it does dropping connections and timeout yet: https://github.com/tylertreat/Comcast – Mikko Ohtamaa Mar 27 '15 at 19:25
  • @MikkoOhtamaa thanks, but that's not exactly my problem. I said "simulate" for clarity, but what I actually need is to drop the connection altogether just like a timed-out connection would look like. It's not for testing purposes. – lorenzog Mar 28 '15 at 18:23

1 Answers1

0

The answer is a combination of both.

  1. From the python app, return 444
  2. Configure nginx as explained on this answer i.e. using the uwsgi_intercept_errors directive.
Community
  • 1
  • 1
lorenzog
  • 3,483
  • 4
  • 29
  • 50