From b38684e59eef299e82f5858fe1e14f6cf2aaa10a Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Wed, 20 May 2009 22:18:36 +0000 Subject: [PATCH] Add a global timeout that is applied to most API requests. --- app/controllers/amf_controller.rb | 5 ++++- app/controllers/api_controller.rb | 1 + app/controllers/application.rb | 6 ++++++ app/controllers/node_controller.rb | 2 +- app/controllers/old_node_controller.rb | 2 +- app/controllers/old_relation_controller.rb | 2 +- app/controllers/old_way_controller.rb | 2 +- app/controllers/relation_controller.rb | 2 +- app/controllers/way_controller.rb | 2 +- config/application.yml | 2 ++ lib/osm.rb | 12 ++++++++++++ 11 files changed, 31 insertions(+), 7 deletions(-) diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 41f724a34..f11700718 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -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 diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index ec5674e94..285558bcf 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -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 diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 082c5cf65..f166df21d 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -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 diff --git a/app/controllers/node_controller.rb b/app/controllers/node_controller.rb index 3b288e29b..eeaba6199 100644 --- a/app/controllers/node_controller.rb +++ b/app/controllers/node_controller.rb @@ -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 diff --git a/app/controllers/old_node_controller.rb b/app/controllers/old_node_controller.rb index e57623dae..5de39fdb6 100644 --- a/app/controllers/old_node_controller.rb +++ b/app/controllers/old_node_controller.rb @@ -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]) diff --git a/app/controllers/old_relation_controller.rb b/app/controllers/old_relation_controller.rb index b98c9da49..5bde0fe6c 100644 --- a/app/controllers/old_relation_controller.rb +++ b/app/controllers/old_relation_controller.rb @@ -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]) diff --git a/app/controllers/old_way_controller.rb b/app/controllers/old_way_controller.rb index 6131c9c3f..1e3546a0d 100644 --- a/app/controllers/old_way_controller.rb +++ b/app/controllers/old_way_controller.rb @@ -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]) diff --git a/app/controllers/relation_controller.rb b/app/controllers/relation_controller.rb index f3c4c9f79..e1f23ac74 100644 --- a/app/controllers/relation_controller.rb +++ b/app/controllers/relation_controller.rb @@ -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 diff --git a/app/controllers/way_controller.rb b/app/controllers/way_controller.rb index d41340754..cc4f1fa38 100644 --- a/app/controllers/way_controller.rb +++ b/app/controllers/way_controller.rb @@ -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 diff --git a/config/application.yml b/config/application.yml index 67d51e375..6241fb621 100644 --- a/config/application.yml +++ b/config/application.yml @@ -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 diff --git a/lib/osm.rb b/lib/osm.rb index 274576206..f3a625c4e 100644 --- a/lib/osm.rb +++ b/lib/osm.rb @@ -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 -- 2.39.5