Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when you have an infinite loop in Django view code?

Something that I just thought about:

Say I'm writing view code for my Django site, and I make a mistake and create an infinite loop.

Whenever someone would try to access the view, the worker assigned to the request (be it a Gevent worker or a Python thread) would stay in a loop indefinitely.

If I understand correctly, the server would send a timeout error to the client after 30 seconds. But what will happen with the Python worker? Will it keep on working indefinitely? That sounds dangerous!

Imagine I've got a server in which I've allocated 10 workers. I let it run and at some point, a client tries to access the view with the infinite loop. A worker will be assigned to it, and will be effectively dead until the next server restart. The dangerous thing is that at first I wouldn't notice it, because the site would just be imperceptibly slower, having 9 workers instead of 10. But then it might happen again and again throughout a long span of time, maybe months. The site would just get progressively slower, until eventually it would be really slow with just one worker.

A server restart would solve the problem, but I'd hate to have my site's functionality depend on server restarts.

Is this a real problem that happens? Is there a way to avoid it?

Update: I'd also really appreciate a way to take a stacktrace of the thread/worker that's stuck in an infinite loop, so I could have that emailed to me so I'll be aware of the problem. (I don't know how to do this because there is no exception being raised.)

Update to people saying things to the effect of "Avoid writing code that has infinite loops": In case it wasn't obvious, I do not spend my free time intentionally putting infinite loops into my code. When these things happen, they are mistakes, and mistakes can be minimized but never completely avoided. I want to know that even when I make a mistake, there'll be a safety net that will notify me and allow me to fix the problem.

like image 490
Ram Rachum Avatar asked Apr 27 '13 13:04

Ram Rachum


People also ask

What happens if you run an infinite loop?

An infinite loop is a piece of code that keeps running forever as the terminating condition is never reached. An infinite loop can crash your program or browser and freeze your computer. To avoid such incidents it is important to be aware of infinite loops so that we can avoid them.

What is an infinite loop in code?

An infinite loop (sometimes called an endless loop ) is a piece of coding that lacks a functional exit so that it repeats indefinitely. In computer programming, a loop is a sequence of instruction s that is continually repeated until a certain condition is reached.

How do you fix an infinite loop in Python?

You can stop an infinite loop with CTRL + C .

How do you stop an infinite loop?

You can press Ctrl + C .


1 Answers

It is a real problem. In case of gevent, due to context switching, it can even immediately stop your website from responding.

Everything depends on your environment. For example, when running django in production through uwsgi you can set harakiri - that is time in seconds, after which thread handling the request will be killed if it didn't finish handling the response. It is strongly recommended to set such a value in order to deal with some faulty requests or bad code. Such event is reported in uwsgi log. I believe other solutions for running Django in production have similar options.

Otherwise, due to network architecture, client disconnection will not stop the infinite loop, and by default there will be no response at all - just infinite loading. Various timeout options (one of which harakiri is) may end up showing connection timeout - for example, php has (as far as i remember) default timeout of 30 seconds and it will return 504 gateway timeout. Socket disconnection timeout depends on http server settings and it will not stop application thread, it will only close client socket.

If not using gevent (or any other green threads), infinite loop will tend to take up 100% of available CPU power (limited to one core), possibly eating up more and more memory, so your website will work pretty slow and/or timeout really quick. Django itself is not aware of request time, so - as mentioned before - your production environment stack is the way to prevent this from happening. In case of uwsgi, http://uwsgi-docs.readthedocs.org/en/latest/Options.html#harakiri-verbose is the way to go.

Harakiri does print stack trace of the killed proces: (https://uwsgi-docs.readthedocs.org/en/latest/Tracebacker.html?highlight=harakiri) straight to uwsgi log, and due to alarm system you can get notified through e-mail (http://uwsgi-docs.readthedocs.org/en/latest/AlarmSubsystem.html)

like image 149
Krzysztof Bujniewicz Avatar answered Sep 19 '22 08:09

Krzysztof Bujniewicz