views:

88

answers:

1

I am using App Engine and the deferred library. But every once in a while my task fail with the following error:

Permanent failure attempting to execute task
Traceback (most recent call last):
  File "/base/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", 
    line 256, in post
      run(self.request.body)
  File "/base/python_lib/versions/1/google/appengine/ext/deferred/deferred.py", 
    line 122, in run
      raise PermanentTaskFailure(e)
PermanentTaskFailure: Environment variable DJANGO_SETTINGS_MODULE is undefined.

I found a post saying the solution is to:

from google.appengine.ext.webapp import template 

But I am not using the webapp framework, I'm using Django. What can I try?

+1  A: 

Errors like this generally occur when your task depends on some Python path manipulation or other jiggery-pokery that isn't being carried out when the first request to a runtime is via deferred. You need to make sure that all your entry points - eg, the module containing the function you're deferring - import a module that does the relevant path manipulation.

Alternatively, you can write your own deferred task handler, which, being part of your framework, will already have the relevant patches applied. For that, simply register the handler and have it call deferred.run(), passing in the complete body of the request.

Nick Johnson
So do I understand correctly that I should add `use_library('django', '1.0')` To the module where the deferred method is, because a deferred call doesn't run through `main.py` ? Doesn't that make deferred calls much slower?
Noio
Yes, or better, put all your setup and path manipulation machinery in a single file that you import from any entry point. use_library won't make the code slower, but you also need to make sure you import app-engine-patch (or whatever other library you're using). Any slowdown is unavoidable - app-engine-patch is making changes to the SDK that cause it to break if it's not present.
Nick Johnson
Ok thank you. Actually, could I use `import main` ? Would that do all the stuff `main.py` does, except run `main()` because it's wrapped in `if __name__ == '__main__':`.
Noio
That would work, yes. It could lead to recursive import issues, though.
Nick Johnson