@@ -26,6 +26,9 @@ writeback_host = "http://stash-xrd.osgconnect.net:1094"
2626# Global variable for nearest cache
2727nearest_cache = None
2828
29+ # Ordered list of nearest caches
30+ nearest_cache_list = []
31+
2932# Global variable for the location of the caches.json file
3033caches_json_location = None
3134
@@ -290,28 +293,18 @@ def download_with_http(source, destination, debug):
290293 Download from the nearest cache with HTTP
291294 """
292295 global nearest_cache
296+ global nearest_cache_list
293297 logging .debug ("Downloading with HTTP" )
294298
295299 payload = {}
296300 payload ['filename' ] = source
297301 sitename = os .environ .setdefault ("OSG_SITE_NAME" , "siteNotFound" )
298302 payload ['sitename' ] = sitename
299303 payload .update (parse_job_ad ())
300- # Calculate the starting time
301- start = int (time .time ()* 1000 )
302304
303305 if not nearest_cache :
304306 nearest_cache = get_best_stashcache ()
305307
306- # Parse the nearest_cache url, make sure it uses http
307- # Should really use urlparse, but python3 and python2 urlparse imports are
308- # very different
309- if nearest_cache .startswith ('root://' ):
310- nearest_cache = nearest_cache .replace ('root://' , 'http://' )
311-
312- # Append port 8000, which is just a convention for now, not set in stone
313- nearest_cache += ":8000"
314-
315308 # Ok, now run the curl command:
316309 if debug :
317310 output_mode = "-v"
@@ -331,13 +324,31 @@ def download_with_http(source, destination, debug):
331324 else :
332325 download_output = "-O"
333326 final_destination = os .path .join (dest_dir , os .path .basename (source ))
334- curl_command = "cd %s; curl %s --connect-timeout 30 --speed-limit 1024 %s --fail %s%s" % (dest_dir , output_mode , download_output , nearest_cache , source )
335- logging .debug ("About to run curl command: %s" , curl_command )
336- command_object = subprocess .Popen ([curl_command ], shell = True )
337- command_object .wait ()
327+
328+ # Try 2 nearest caches
329+ success = False
330+ start = end = 0
331+ for cache in nearest_cache_list [:2 ]:
332+ # Parse the nearest_cache url, make sure it uses http
333+ # Should really use urlparse, but python3 and python2 urlparse imports are
334+ # very different
335+ if nearest_cache .startswith ('root://' ):
336+ nearest_cache = nearest_cache .replace ('root://' , 'http://' )
337+
338+ # Append port 8000, which is just a convention for now, not set in stone
339+ nearest_cache += ":8000"
340+ curl_command = "cd %s; curl %s -L --connect-timeout 30 --speed-limit 1024 %s --fail %s%s" % (dest_dir , output_mode , download_output , nearest_cache , source )
341+ logging .debug ("About to run curl command: %s" , curl_command )
342+ start = int (time .time ()* 1000 )
343+ command_object = subprocess .Popen ([curl_command ], shell = True )
344+ command_object .wait ()
345+ end = int (time .time ()* 1000 )
346+
347+ if command_object .returncode == 0 :
348+ success = True
349+ break
338350
339- end = int (time .time ()* 1000 )
340- if command_object .returncode == 0 :
351+ if success :
341352 dlSz = os .stat (final_destination ).st_size
342353 filesize = dlSz
343354 status = 'Success'
@@ -357,7 +368,7 @@ def download_with_http(source, destination, debug):
357368 payload ['end1' ]= end
358369 payload ['cache' ]= nearest_cache
359370 es_send (payload )
360- if command_object . returncode == 0 :
371+ if success :
361372 return 0
362373 else :
363374 return 1
@@ -479,6 +490,7 @@ def get_ips(name):
479490 return ipv4s + ipv6s
480491
481492def get_best_stashcache ():
493+ global nearest_cache_list
482494
483495 # Check if the user provided a caches json file location
484496 if caches_json_location and os .path .exists (caches_json_location ):
@@ -559,13 +571,19 @@ def get_best_stashcache():
559571 ordered_list = order_str .strip ().split ("," )
560572 logging .debug ("Got order %s" , str (ordered_list ))
561573 minsite = caches_list [int (ordered_list [0 ])- 1 ]['name' ]
574+
575+ nearest_cache_list = []
576+ for ordered_index in ordered_list :
577+ nearest_cache_list .append (caches_list [int (ordered_index )- 1 ]['name' ])
562578
563579 logging .debug ("Returning closest cache: %s" , minsite )
580+ logging .debug ("Ordered list of nearest caches: %s" , str (nearest_cache_list ))
564581 return minsite
565582
566583
567584def main ():
568585 global nearest_cache
586+ global nearest_cache_list
569587 global caches_json_location
570588
571589 usage = "usage: %prog [options] source destination"
@@ -602,6 +620,7 @@ def main():
602620 # Check for manually entered cache to use
603621 if args .cache and len (args .cache ) > 0 :
604622 nearest_cache = args .cache
623+ nearest_cache_list = [ args .cache ]
605624
606625 if not args .recursive :
607626 result = doStashCpSingle (sourceFile = source , destination = destination , debug = args .debug )
0 commit comments