nodes: 0, module; 1, function_definition; 2, function_name:sort_servers_closest; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, generic_type; 8, expression_statement; 9, if_statement; 10, expression_statement; 11, comment:# these tasks should never raise, returns None on errors; 12, expression_statement; 13, comment:# block and wait tasks; 14, expression_statement; 15, expression_statement; 16, return_statement; 17, identifier:servers; 18, type; 19, identifier:Sequence; 20, type_parameter; 21, comment:"""Sorts a list of servers by http round-trip time
  
      Params:
          servers: sequence of http server urls
      Returns:
          sequence of pairs of url,rtt in seconds, sorted by rtt, excluding failed servers
          (possibly empty)
      """; 22, not_operator; 23, block; 24, assignment; 25, call; 26, assignment; 27, call; 28, identifier:sorted_servers; 29, generic_type; 30, type; 31, call; 32, raise_statement; 33, identifier:get_rtt_jobs; 34, call; 35, attribute; 36, argument_list; 37, identifier:sorted_servers; 38, type; 39, call; 40, attribute; 41, argument_list; 42, identifier:Sequence; 43, type_parameter; 44, generic_type; 45, attribute; 46, argument_list; 47, call; 48, identifier:set; 49, generator_expression; 50, identifier:gevent; 51, identifier:joinall; 52, identifier:get_rtt_jobs; 53, keyword_argument; 54, generic_type; 55, identifier:sorted; 56, argument_list; 57, identifier:log; 58, identifier:debug; 59, string; 60, keyword_argument; 61, type; 62, identifier:Tuple; 63, type_parameter; 64, set_comprehension; 65, identifier:issubset; 66, set; 67, identifier:TransportError; 68, argument_list; 69, call; 70, for_in_clause; 71, identifier:raise_error; 72, False; 73, identifier:List; 74, type_parameter; 75, generator_expression; 76, keyword_argument; 77, string_content:Matrix homeserver RTT times; 78, identifier:rtt_times; 79, identifier:sorted_servers; 80, identifier:str; 81, type; 82, type; 83, attribute; 84, for_in_clause; 85, string; 86, string; 87, string; 88, attribute; 89, argument_list; 90, identifier:server_url; 91, identifier:servers; 92, type; 93, attribute; 94, for_in_clause; 95, if_clause; 96, identifier:key; 97, call; 98, identifier:str; 99, identifier:float; 100, call; 101, identifier:scheme; 102, identifier:url; 103, identifier:servers; 104, string_content:http; 105, string_content:https; 106, string_content:Invalid server urls; 107, identifier:gevent; 108, identifier:spawn; 109, lambda; 110, identifier:server_url; 111, generic_type; 112, identifier:job; 113, identifier:value; 114, identifier:job; 115, identifier:get_rtt_jobs; 116, comparison_operator:job.value[1] is not None; 117, identifier:itemgetter; 118, argument_list; 119, identifier:urlparse; 120, argument_list; 121, lambda_parameters; 122, tuple; 123, identifier:Tuple; 124, type_parameter; 125, subscript; 126, None; 127, integer:1; 128, identifier:url; 129, identifier:url; 130, identifier:url; 131, call; 132, type; 133, type; 134, attribute; 135, integer:1; 136, identifier:get_http_rtt; 137, argument_list; 138, identifier:str; 139, identifier:float; 140, identifier:job; 141, identifier:value; 142, identifier:url
code: def sort_servers_closest(servers: Sequence[str]) -> Sequence[Tuple[str, float]]:
      """Sorts a list of servers by http round-trip time
  
      Params:
          servers: sequence of http server urls
      Returns:
          sequence of pairs of url,rtt in seconds, sorted by rtt, excluding failed servers
          (possibly empty)
      """
      if not {urlparse(url).scheme for url in servers}.issubset({'http', 'https'}):
          raise TransportError('Invalid server urls')
  
      get_rtt_jobs = set(
          gevent.spawn(lambda url: (url, get_http_rtt(url)), server_url)
          for server_url
          in servers
      )
      # these tasks should never raise, returns None on errors
      gevent.joinall(get_rtt_jobs, raise_error=False)  # block and wait tasks
      sorted_servers: List[Tuple[str, float]] = sorted(
          (job.value for job in get_rtt_jobs if job.value[1] is not None),
          key=itemgetter(1),
      )
      log.debug('Matrix homeserver RTT times', rtt_times=sorted_servers)
      return sorted_servers