nodes: 0, module; 1, function_definition; 2, function_name:get_available_urls; 3, parameters; 4, block; 5, identifier:self; 6, identifier:urls; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, comment:# List of pairs (host, time in ms).; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, return_statement; 16, comment:"""Return reachable urls sorted by their ping times."""; 17, assignment; 18, assignment; 19, call; 20, assignment; 21, assignment; 22, call; 23, identifier:available_urls; 24, identifier:baseurl_to_urls; 25, dictionary_comprehension; 26, identifier:pingtimes; 27, call; 28, attribute; 29, argument_list; 30, identifier:sorted_pingtimes; 31, call; 32, identifier:available_urls; 33, list_comprehension; 34, attribute; 35, argument_list; 36, pair; 37, for_in_clause; 38, attribute; 39, argument_list; 40, attribute; 41, identifier:debug; 42, call; 43, identifier:sorted; 44, argument_list; 45, subscript; 46, for_in_clause; 47, if_clause; 48, attribute; 49, identifier:debug; 50, call; 51, call; 52, identifier:url; 53, identifier:url; 54, identifier:urls; 55, attribute; 56, identifier:pings; 57, call; 58, identifier:self; 59, identifier:_log; 60, attribute; 61, argument_list; 62, identifier:pingtimes; 63, keyword_argument; 64, identifier:baseurl_to_urls; 65, identifier:baseurl; 66, pattern_list; 67, identifier:sorted_pingtimes; 68, comparison_operator:pingtime < Pinger.UNREACHABLE; 69, identifier:self; 70, identifier:_log; 71, attribute; 72, argument_list; 73, attribute; 74, argument_list; 75, identifier:self; 76, identifier:_pinger; 77, identifier:list; 78, argument_list; 79, string; 80, identifier:format; 81, call; 82, identifier:key; 83, lambda; 84, identifier:baseurl; 85, identifier:pingtime; 86, identifier:pingtime; 87, attribute; 88, string; 89, identifier:format; 90, identifier:available_urls; 91, identifier:self; 92, identifier:_baseurl; 93, identifier:url; 94, call; 95, string_content:Artifact cache server ping times: {}; 96, attribute; 97, argument_list; 98, lambda_parameters; 99, subscript; 100, identifier:Pinger; 101, identifier:UNREACHABLE; 102, string_content:Available cache servers: {0}; 103, attribute; 104, argument_list; 105, string; 106, identifier:join; 107, list_comprehension; 108, identifier:x; 109, identifier:x; 110, integer:1; 111, identifier:baseurl_to_urls; 112, identifier:keys; 113, string_content:,; 114, call; 115, for_in_clause; 116, attribute; 117, argument_list; 118, identifier:p; 119, identifier:pingtimes; 120, string; 121, identifier:format; 122, list_splat; 123, string_content:{}: {:.6f} secs; 124, identifier:p
code: def get_available_urls(self, urls):
      """Return reachable urls sorted by their ping times."""
      baseurl_to_urls = {self._baseurl(url): url for url in urls}
      pingtimes = self._pinger.pings(list(baseurl_to_urls.keys()))  # List of pairs (host, time in ms).
      self._log.debug('Artifact cache server ping times: {}'
                      .format(', '.join(['{}: {:.6f} secs'.format(*p) for p in pingtimes])))
  
      sorted_pingtimes = sorted(pingtimes, key=lambda x: x[1])
      available_urls = [baseurl_to_urls[baseurl] for baseurl, pingtime in sorted_pingtimes
                        if pingtime < Pinger.UNREACHABLE]
      self._log.debug('Available cache servers: {0}'.format(available_urls))
  
      return available_urls