CIS-LB: Randomized suboptimal load balancing implemented without low timeout features.
[living-lab-site.git] / cis / cis_lb / load_balancer / base.py
index 9586c88..f44ab1b 100644 (file)
@@ -1,8 +1,11 @@
 import threading
 import urllib
+import json
 
+import config
 import logger
 
+
 class LoadBalancer(threading.Thread):
     
     def __init__(self, id, queue):
@@ -19,16 +22,53 @@ class LoadBalancer(threading.Thread):
         
         while True:
             (request, data) = self.queue.get()
+            urls = config.CIS_URLS[:]
+            code = json.loads(data)['code']
+            success = False
+            
+            while len(urls) != 0:
+                cis = self.choose(urls)
+                
+                # Request is forwarded to the chosen CIS.
+                try:
+                    urllib.urlopen(cis + request, data)
+                except IOError:
+                    logger.log_msg('#%s: Failed to forward request to %s' \
+                            % (code, cis), \
+                            logger.LOG_LEVEL_ERROR)
+                    continue
+                
+                success = True
+                logger.log_msg('#%s: Request forwarded to %s' \
+                            % (code, cis), \
+                        logger.LOG_LEVEL_INFO)
+                break
             
-            cis = self.choose()
-            logger.log_msg('Forwarding to %s' % cis, logger.LOG_LEVEL_DEBUG)
-            urllib.urlopen(cis + request, data)
+            if len(urls) == 0 and not success:
+                logger.log_msg('#%s: Failed to forward request to any CIS' \
+                            % code, \
+                            logger.LOG_LEVEL_FATAL)
+                self.notify_error(code)
             
             self.queue.task_done()
+    
+    def notify_error(self, code):
+        logger.log_msg('#%s: notifying web server about the error...'\
+                % code)
+        
+        if config.WS_ERROR[len(config.WS_ERROR) - 1] == '/':
+            url = config.WS_ERROR + code
+        else:
+            url = config.WS_ERROR + '/' + code
+        url = url + '/' + 'unreachable'
+        
+        f = urllib.urlopen(url)
+        f.read()
         
-    def choose(self):
+    def choose(self, urls):
         """
         Implement load balancing policy in this method for child classes which
-        choses a CIS from config.CIS_URLS .
+        choses a CIS from urls parameter. The chosen URL should be deleted from
+        urls list.
         """        
         pass
\ No newline at end of file