Add a global timeout that is applied to most API requests.

This commit is contained in:
Tom Hughes 2009-05-20 22:18:36 +00:00
parent 3d0ca940d2
commit b38684e59e
11 changed files with 31 additions and 7 deletions

View file

@ -43,6 +43,7 @@ class AmfController < ApplicationController
session :off
before_filter :check_api_writable
around_filter :api_call_timeout, :only => [:amf_read]
# Main AMF handlers: process the raw AMF string (using AMF library) and
# calls each action (private method) accordingly.
@ -198,7 +199,7 @@ class AmfController < ApplicationController
enlarge = [(xmax-xmin)/8,0.01].min
xmin -= enlarge; ymin -= enlarge
xmax += enlarge; ymax += enlarge
# check boundary is sane and area within defined
# see /config/application.yml
check_boundaries(xmin, ymin, xmax, ymax)
@ -228,6 +229,8 @@ class AmfController < ApplicationController
[0, ways, points, relations]
rescue OSM::APITimeoutError => err
[-1,"Sorry - I can't get the map for that area. The server said: #{err}"]
rescue Exception => err
[-2,"Sorry - I can't get the map for that area. The server said: #{err}"]
end

View file

@ -3,6 +3,7 @@ class ApiController < ApplicationController
session :off
before_filter :check_api_readable, :except => [:capabilities]
after_filter :compress_output
around_filter :api_call_handle_error, :api_call_timeout
# Help methods for checking boundary sanity and area size
include MapBoundary

View file

@ -126,6 +126,12 @@ class ApplicationController < ActionController::Base
raise OSM::APIBadMethodError.new(method) unless ok
end
def api_call_timeout
Timeout::timeout(APP_CONFIG['api_timeout'], OSM::APITimeoutError) do
yield
end
end
private
# extract authorisation credentials from headers, returns user = nil if none

View file

@ -9,7 +9,7 @@ class NodeController < ApplicationController
before_filter :check_api_writable, :only => [:create, :update, :delete]
before_filter :check_api_readable, :except => [:create, :update, :delete]
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
# Create a node from XML.
def create

View file

@ -4,7 +4,7 @@ class OldNodeController < ApplicationController
session :off
before_filter :check_api_readable
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
def history
node = Node.find(params[:id])

View file

@ -4,7 +4,7 @@ class OldRelationController < ApplicationController
session :off
before_filter :check_api_readable
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
def history
relation = Relation.find(params[:id])

View file

@ -4,7 +4,7 @@ class OldWayController < ApplicationController
session :off
before_filter :check_api_readable
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
def history
way = Way.find(params[:id])

View file

@ -7,7 +7,7 @@ class RelationController < ApplicationController
before_filter :check_api_writable, :only => [:create, :update, :delete]
before_filter :check_api_readable, :except => [:create, :update, :delete]
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
def create
assert_method :put

View file

@ -7,7 +7,7 @@ class WayController < ApplicationController
before_filter :check_api_writable, :only => [:create, :update, :delete]
before_filter :check_api_readable, :except => [:create, :update, :delete]
after_filter :compress_output
around_filter :api_call_handle_error
around_filter :api_call_handle_error, :api_call_timeout
def create
assert_method :put

View file

@ -11,6 +11,8 @@ standard_settings: &standard_settings
postcode_zoom: 15
# Zoom level to use for geonames results from the geocoder
geonames_zoom: 12
# Timeout for API calls in seconds
api_timeout: 300
development:
<<: *standard_settings

View file

@ -197,6 +197,18 @@ module OSM
end
end
##
# raised when an API call takes too long
class APITimeoutError < APIError
def render_opts
{ :text => "Request timed out", :status => :request_timeout }
end
def to_s
"Request timed out"
end
end
# Helper methods for going to/from mercator and lat/lng.
class Mercator
include Math