Add a global timeout that is applied to most API requests.
authorTom Hughes <tom@compton.nu>
Wed, 20 May 2009 22:18:36 +0000 (22:18 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 20 May 2009 22:18:36 +0000 (22:18 +0000)
app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/controllers/application.rb
app/controllers/node_controller.rb
app/controllers/old_node_controller.rb
app/controllers/old_relation_controller.rb
app/controllers/old_way_controller.rb
app/controllers/relation_controller.rb
app/controllers/way_controller.rb
config/application.yml
lib/osm.rb

index 41f724a34fb2fe11810116a915af44d9f56afefe..f11700718556b95eec0b9f1a932dd027c64a43ed 100644 (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
index ec5674e94542487074ca29d986161762b357fea8..285558bcfc490537e54a22c3c55d61b0c27e0a30 100644 (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
index 082c5cf65a28aceac9863bede1e0732e8f976b51..f166df21d6075be39651f9350e54106e3f85703b 100644 (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
index 3b288e29bb3026afdbc1f22c87c26317f8927bd0..eeaba6199a9ad346970e0688e7bcd70907534045 100644 (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
index e57623daed86fead2832a2dfdae63849d69d47c9..5de39fdb60a1f5ddb45a125b36c4b83e1749518c 100644 (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])
index b98c9da4952b3a54840127e0ea454a0e0f70fe42..5bde0fe6c9367c7c11b0fedf1632383dd0e7d23d 100644 (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])
index 6131c9c3fac36f0a019f27ff197c5c41cc10abc8..1e3546a0d0f09b3bdf6e25b6de67ae6a0952cb83 100644 (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])
index f3c4c9f791357d7f046064794b6e6fd2a594627b..e1f23ac74b7301c3207930530bd30352f56e12e8 100644 (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
index d413407541a51c9de9708b1d83b864f00e4a02d4..cc4f1fa38d6c8279b3a1f2a39ef0e6abaa87ab81 100644 (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
index 67d51e375210eff850afc228a9bdae275e4a4588..6241fb621f5379ddda1c1dbce1c83b3ea7d5c301 100644 (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
index 2745762064c5f342d67d8a13d6146df3a65786c1..f3a625c4eba61b90aef57ccb198a62d7fe96a959 100644 (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