views:

48

answers:

2

Hey, i was wondering if there is a way to enforce the 30 seconds limit that is being enforced online at the appengine production servers to the local dev server? its impossible to test if i reach the limit before going production.

maybe some django middlware?

+1  A: 

You could write (and insert in the WSGI stack) a useful piece of WSGI middleware which uses a threading.Timer which logs the fact that the transaction has exceeded 30 seconds (and of course calls cancel on the timer object on the way out, as there's nothing to log in that case).

I'd do it at WSGI level, not Django level, (a) because I'm more familiar with WSGI middleware and (b) because it's a more general solution (it can help a Django web app, but it can also help a web app using any other framework -- WSGI's use is guaranteed by App Engine, whatever framework you decide to lay on top of it).

You'll need to tweak the "30 seconds" a bit to calibrate, because of course the power, available RAM, disk speed, etc, of your development machine, can't just happen to be exactly identical to Google's, and also many subsystems (esp. the storage one) have very different implementations "locally on the SDK" versus "on Google's actual servers" and in any given case may happen to be substantially slower (or maybe faster!-).

Given the considerations in the previous paragraph it might actually be more helpful to have the middleware simply always log the transaction's total elapsed time -- this way you can watch for transactions that (while they may terminate within 30 seconds on your development server) are taking comparable time (say 15 or 20 seconds or more), especially if they have multiple storage transactions that might slow them down on the real production servers/

Alex Martelli
Thanks alot! nick and alex. the tasks arent user specific but background work that im trying to debug to get the deadtime exception that you cant basically get on dev server.I think ill have a look at the threading.timer to log things running more then 15 seconds or 20 seconds to try and catch.but there isnt any way to make the dev_server throw deadtimexceeded error uh?
Alon Carmel
@Alon, it's generally not possible to throw exceptions asynchronously (and in particular from one thread such as a timer into the main thread) with the exception of KeyboardInterrupt which _can_ be raised from any thread into the main thread, asynchronously, by way of `thread.interrupt_main`, http://docs.python.org/library/thread.html?highlight=interrupt_main#thread.interrupt_main . To simulate getting the timeout exception, assign `DeadlineReceivedError=KeyboardInterrupt` if running locally instead of importing the name from `google.appengine.runtime` (or edit the latter module in your SDK).
Alex Martelli
+1  A: 

It's possible, as Alex demonstrates, but it's not really a good idea: The performance characteristics of the development server are not the same as those of the production environment, so something that executes quickly locally may not be nearly as quick in production, and vice versa.

Also, your user facing tasks should definitely not be so slow as to approach the 30 second limit.

Nick Johnson
@Nick, if the OP wants to check he's properly handling `DeadlineReceivedError` (especially in a queued task -- as you say, the _user_ should never wait that long anyway;-) I think hacking his local copy of the `google.appengine.runtime` module to assign that name to `KeyboardInterrupt` (the only exception one can asynchronously raise in the main thread from another, e.g. a timer one) seems reasonable to me, see my latest comment under my own answer. Yes, won't be raised locally exactly in the same cases as it will in production, as I also said, but, better than nothing;-).
Alex Martelli
i couldnt agree more. even if it would raise an exception after 20 seconds and not 30 it would still atleast iet me test deferred mapper code i wrote.
Alon Carmel