CIS-LB: Randomized suboptimal load balancing implemented without low timeout features.
[living-lab-site.git] / cis / cis_lb / load_balancer / base.py
1 import threading
2 import urllib
3 import json
4
5 import config
6 import logger
7
8
9 class LoadBalancer(threading.Thread):
10     
11     def __init__(self, id, queue):
12         """
13         Initialize Load Balancer,
14         """
15
16         threading.Thread.__init__(self, \
17                 name = '%s%02d' % (self.__class__.__name__, id))
18         
19         self.queue = queue
20     
21     def run(self):
22         
23         while True:
24             (request, data) = self.queue.get()
25             urls = config.CIS_URLS[:]
26             code = json.loads(data)['code']
27             success = False
28             
29             while len(urls) != 0:
30                 cis = self.choose(urls)
31                 
32                 # Request is forwarded to the chosen CIS.
33                 try:
34                     urllib.urlopen(cis + request, data)
35                 except IOError:
36                     logger.log_msg('#%s: Failed to forward request to %s' \
37                             % (code, cis), \
38                             logger.LOG_LEVEL_ERROR)
39                     continue
40                 
41                 success = True
42                 logger.log_msg('#%s: Request forwarded to %s' \
43                             % (code, cis), \
44                         logger.LOG_LEVEL_INFO)
45                 break
46             
47             if len(urls) == 0 and not success:
48                 logger.log_msg('#%s: Failed to forward request to any CIS' \
49                             % code, \
50                             logger.LOG_LEVEL_FATAL)
51                 self.notify_error(code)
52             
53             self.queue.task_done()
54     
55     def notify_error(self, code):
56         logger.log_msg('#%s: notifying web server about the error...'\
57                 % code)
58         
59         if config.WS_ERROR[len(config.WS_ERROR) - 1] == '/':
60             url = config.WS_ERROR + code
61         else:
62             url = config.WS_ERROR + '/' + code
63         url = url + '/' + 'unreachable'
64         
65         f = urllib.urlopen(url)
66         f.read()
67         
68     def choose(self, urls):
69         """
70         Implement load balancing policy in this method for child classes which
71         choses a CIS from urls parameter. The chosen URL should be deleted from
72         urls list.
73         """        
74         pass