<s> import lixian_logging <EOL> import urllib2 <EOL> import re <EOL> VOD_RANGE = '<STR_LIT>' <EOL> def resolve_node_url ( url , gdriveid , timeout = <NUM_LIT> ) : <EOL> request = urllib2 . Request ( url , headers = { '<STR_LIT>' : '<STR_LIT>' + gdriveid } ) <EOL> response = urllib2 . urlopen ( request , timeout = timeout ) <EOL> response . close ( ) <EOL> return response . geturl ( ) <EOL> def switch_node_in_url ( node_url , node ) : <EOL> return re . sub ( r'<STR_LIT>' , r'<STR_LIT>' % node , node_url ) <EOL> def switch_node ( url , node , gdriveid ) : <EOL> assert re . match ( r'<STR_LIT>' , node ) <EOL> logger = lixian_logging . get_logger ( ) <EOL> logger . debug ( '<STR_LIT>' + url ) <EOL> try : <EOL> url = resolve_node_url ( url , gdriveid , timeout = <NUM_LIT> ) <EOL> logger . debug ( '<STR_LIT>' + url ) <EOL> except : <EOL> import traceback <EOL> logger . debug ( traceback . format_exc ( ) ) <EOL> return url <EOL> url = switch_node_in_url ( url , node ) <EOL> logger . debug ( '<STR_LIT>' + url ) <EOL> return url <EOL> def test_response_speed ( response , max_size , max_duration ) : <EOL> import time <EOL> current_duration = <NUM_LIT:0> <EOL> current_size = <NUM_LIT:0> <EOL> start = time . clock ( ) <EOL> while current_duration < max_duration and current_size < max_size : <EOL> data = response . read ( max_size - current_size ) <EOL> if not data : <EOL> break <EOL> current_size += len ( data ) <EOL> end = time . clock ( ) <EOL> current_duration = end - start <EOL> if current_size < <NUM_LIT> : <EOL> raise Exception ( "<STR_LIT>" % current_size ) <EOL> return current_size / current_duration , current_size , current_duration <EOL> def get_node_url_speed ( url , gdriveid ) : <EOL> request = urllib2 . Request ( url , headers = { '<STR_LIT>' : '<STR_LIT>' + gdriveid } ) <EOL> response = urllib2 . urlopen ( request , timeout = <NUM_LIT:3> ) <EOL> speed , size , duration = test_response_speed ( response , <NUM_LIT:2> * <NUM_LIT:1000> * <NUM_LIT:1000> , <NUM_LIT:3> ) <EOL> response . close ( ) <EOL> return speed <EOL> def parse_vod_nodes ( vod_nodes ) : <EOL> if vod_nodes == '<STR_LIT:all>' or not vod_nodes : <EOL> vod_nodes = VOD_RANGE <EOL> nodes = [ ] <EOL> seen = set ( ) <EOL> def add ( node ) : <EOL> if node not in seen : <EOL> nodes . append ( node ) <EOL> seen . add ( node ) <EOL> for expr in re . split ( r'<STR_LIT>' , vod_nodes ) : <EOL> if re . match ( r'<STR_LIT>' , expr ) : <EOL> start , end = map ( int , expr . split ( '<STR_LIT:->' ) ) <EOL> if start <= end : <EOL> for i in range ( start , end + <NUM_LIT:1> ) : <EOL> add ( "<STR_LIT>" % i ) <EOL> else : <EOL> for i in range ( start , end - <NUM_LIT:1> , - <NUM_LIT:1> ) : <EOL> add ( "<STR_LIT>" % i ) <EOL> elif re . match ( r'<STR_LIT>' , expr ) : <EOL> add ( '<STR_LIT>' + expr ) <EOL> else : <EOL> raise Exception ( "<STR_LIT>" + expr ) <EOL> return nodes <EOL> def get_best_node_url_from ( node_url , nodes , gdriveid ) : <EOL> best = None <EOL> best_speed = <NUM_LIT:0> <EOL> logger = lixian_logging . get_logger ( ) <EOL> for node in nodes : <EOL> url = switch_node_in_url ( node_url , node ) <EOL> try : <EOL> speed = get_node_url_speed ( url , gdriveid ) <EOL> logger . debug ( "<STR_LIT>" % ( node , speed ) ) <EOL> if speed > best_speed : <EOL> best_speed = speed <EOL> best = url <EOL> except Exception , e : <EOL> logger . debug ( "<STR_LIT>" % ( node , e ) ) <EOL> return best <EOL> def get_good_node_url_from ( node_url , nodes , acceptable_speed , gdriveid ) : <EOL> best = None <EOL> best_speed = <NUM_LIT:0> <EOL> logger = lixian_logging . get_logger ( ) <EOL> for node in nodes : <EOL> url = switch_node_in_url ( node_url , node ) <EOL> try : <EOL> speed = get_node_url_speed ( url , gdriveid ) <EOL> logger . debug ( "<STR_LIT>" % ( node , speed ) ) <EOL> if speed > acceptable_speed : <EOL> return url <EOL> elif speed > best_speed : <EOL> best_speed = speed <EOL> best = url <EOL> except Exception , e : <EOL> logger . debug ( "<STR_LIT>" % ( node , e ) ) <EOL> return best <EOL> def use_node_by_policy ( url , vod_nodes , gdriveid , policy ) : <EOL> nodes = parse_vod_nodes ( vod_nodes ) <EOL> assert nodes <EOL> logger = lixian_logging . get_logger ( ) <EOL> logger . debug ( '<STR_LIT>' + url ) <EOL> try : <EOL> node_url = resolve_node_url ( url , gdriveid , timeout = <NUM_LIT> ) <EOL> logger . debug ( '<STR_LIT>' + node_url ) <EOL> except : <EOL> import traceback <EOL> logger . debug ( traceback . format_exc ( ) ) <EOL> return url <EOL> default_node = re . match ( r'<STR_LIT>' , node_url ) . group ( <NUM_LIT:1> ) <EOL> if default_node not in nodes : <EOL> nodes . insert ( <NUM_LIT:0> , default_node ) <EOL> chosen = policy ( node_url , nodes , gdriveid ) <EOL> if chosen : <EOL> logger . debug ( '<STR_LIT>' + chosen ) <EOL> return chosen <EOL> else : <EOL> return node_url <EOL> def use_fastest_node ( url , vod_nodes , gdriveid ) : <EOL> return use_node_by_policy ( url , vod_nodes , gdriveid , get_best_node_url_from ) <EOL> def use_fast_node ( url , vod_nodes , acceptable_speed , gdriveid ) : <EOL> def policy ( url , vod_nodes , gdriveid ) : <EOL> return get_good_node_url_from ( url , vod_nodes , acceptable_speed , gdriveid ) <EOL> return use_node_by_policy ( url , vod_nodes , gdriveid , policy ) </s>
