@@ -59,27 +59,38 @@ def parse_coordinate_from_path(path, extension, layer):
5959 pass
6060
6161
62- def _backoff_and_retry (num_tries = 5 , factor = 2 , interval = 1 , logger = None ):
62+ # decorates a function to back off and retry
63+ def _backoff_and_retry (ExceptionType , num_tries = 5 , retry_factor = 2 ,
64+ retry_interval = 1 , logger = None ):
6365 from time import sleep
66+ from functools import wraps
6467
65- # do the first num_tries-1 attempts wrapped in something to catch any
66- # exceptions, optionally log them, and try again.
67- for try_counter in xrange (1 , num_tries ):
68- try :
69- yield
70- break
68+ def decorator (f ):
69+ @wraps (f )
70+ def func (* args , ** kwargs ):
71+ # do the first num_tries-1 attempts wrapped in something to catch
72+ # any exceptions, optionally log them, and try again.
73+ interval = retry_interval
74+ factor = retry_factor
7175
72- except Exception as e :
73- if logger :
74- logger .warning ("Failed. Backing off and retrying. Error: %s"
75- % str (e ))
76+ for _ in xrange (1 , num_tries ):
77+ try :
78+ return f (* args , ** kwargs )
7679
77- sleep (interval )
78- interval *= factor
79- else :
80- # do final attempt without try-except, so we get the exception
81- # in normal code.
82- yield
80+ except ExceptionType as e :
81+ if logger :
82+ logger .warning ("Failed. Backing off and retrying. "
83+ "Error: %s" % str (e ))
84+
85+ sleep (interval )
86+ interval *= factor
87+
88+ # do final attempt without try-except, so we get the exception
89+ # in normal code.
90+ return f (* args , ** kwargs )
91+
92+ return func
93+ return decorator
8394
8495
8596class S3 (object ):
@@ -98,14 +109,17 @@ def write_tile(self, tile_data, coord, format, layer):
98109 self .date_prefix , self .path , layer , coord , format .extension )
99110 key = self .bucket .new_key (key_name )
100111
101- for _ in _backoff_and_retry ():
112+ @_backoff_and_retry (Exception )
113+ def write_to_s3 ():
102114 key .set_contents_from_string (
103115 tile_data ,
104116 headers = {'Content-Type' : format .mimetype },
105117 policy = 'public-read' ,
106118 reduced_redundancy = self .reduced_redundancy ,
107119 )
108120
121+ write_to_s3 ()
122+
109123 def read_tile (self , coord , format , layer ):
110124 key_name = s3_tile_key (
111125 self .date_prefix , self .path , layer , coord , format .extension )
0 commit comments