11

Has anyone got any experience with the following exception when using GAE urlfetch?

      DownloadError: ApplicationError: 2 timed out

I'm trying to send a HTTP POST request. Like so:

      result = urlfetch.fetch('http://api.nathan.com:8080/Obj/',
                              method='POST',
                              payload=postdata,
                              deadline=10)

I've tried setting deadline to the max (10 seconds). The request from the command line (using curl or httplib2) takes about a second.

       nchong@almond ~ $ time curl
                         -d "<Obj><a>1</a><b>n</b></Obj>"
                         http://api.nathan.com:8080/Obj/
       agd1c2VyYXBpcgoLEgRTZXNzGAIM      #< key returned by call
       real 0m1.109s
       user 0m0.003s
       sys  0m0.009s

Here's the output from the dev appserver for the curl request (I'm using appengine-rest-server):

INFO     __init__.py:819] adding models from module __main__
INFO     __init__.py:867] added model Obj with type <class '__main__.Obj'>
INFO     dev_appserver.py:3243] "POST /Obj HTTP/1.1" 200 -
INFO     dev_appserver_index.py:205] Updating /path/to/index.yaml

Here's the output when I try to use urlfetch:

ERROR    __init__.py:388] ApplicationError: 2 timed out
Traceback (most recent call last):
  File "/path/to/webapp/__init__.py", line 507, in __call__
    handler.get(*groups)
  File "/path/to/myapp/main.py", line 62, in get
    result = urlfetch.fetch(...)
  File "/path/to/urlfetch.py", line 241, in fetch
    return rpc.get_result()
  File "/path/to/apiproxy_stub_map.py", line 501, in get_result
    return self.__get_result_hook(self)
  File "/path/to/urlfetch.py", line 325, in _get_fetch_result
    raise DownloadError(str(err))
DownloadError: ApplicationError: 2 timed out
INFO     dev_appserver.py:3243] "GET / HTTP/1.1" 500 -
INFO     dev_appserver.py:3243] "POST /Obj/ HTTP/1.1" 200 -
nafe
  • 379
  • 5
  • 16
  • 1
    My current workaround is to wrap the urlfetch call in a try/except pass block. – nafe Jan 07 '10 at 18:19
  • Are you able to look at what is happening on the server during this call? Is it correctly processing the payload and returning the key? Is the value in postdata what you think it is? – Adam Crossland Jan 07 '10 at 18:25
  • Hi Alex, The server is getting the POST request and it is creating a new Obj based upon the call. – nafe Jan 07 '10 at 19:02
  • Is it then completing the response? – Adam Crossland Jan 07 '10 at 19:42
  • Maybe one of the complications is that I'm using the same app instance (with different handlers) for both the API request and API response. I'll try separating them out so that I can see which is the one that is failing. – nafe Jan 07 '10 at 19:53
  • 2
    Yes! The dev appserver is single-threaded! It will never be able to complete a request to itself. – Adam Crossland Jan 07 '10 at 20:06
  • Note the maximum timeout is not 10s anymore: """The deadline can be up to a maximum of 60 seconds for request handlers and 10 minutes for tasks queue and cron job handlers. If deadline is None, the deadline is set to 5 seconds.""" Consider editing your question :) – proppy Apr 26 '12 at 16:01

1 Answers1

12

The development web server is single-threaded. You can not make a request from your application running inside it to itself. Try running two instances on different ports.

By the way, this should not be a problem once it is deployed, as the actual AppEngine server is of course able to handle multiple simultaneous requests.

Adam Crossland
  • 14,198
  • 3
  • 44
  • 54
  • Ah this sounds like a very promising line of enquiry. I'll try it out and get back to you. Thanks! – nafe Jan 07 '10 at 23:40
  • This was exactly the issue. Splitting out the sender and receiver of the urlfetch into separate servers resolved my issue. – nafe Jan 15 '10 at 04:26