[X2Go-Commits] [x2gobroker] 05/05: Various improvements / fixes for session selection via the load checker daemon.

git-admin at x2go.org git-admin at x2go.org
Mon Mar 30 13:28:01 CEST 2015


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2gobroker.

commit dcf76802471010339d3c3e886ea09bd89b7acd6e
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Mon Mar 30 13:27:05 2015 +0200

    Various improvements / fixes for session selection via the load checker daemon.
---
 debian/changelog                  |    2 ++
 x2gobroker/brokers/base_broker.py |   69 +++++++++++++++++++++++++++----------
 2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index b9f05bc..dc89706 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -264,6 +264,8 @@ x2gobroker (0.0.3.0-0x2go1) UNRELEASED; urgency=low
       and number of sessions as values.
     - Fix X2GoBroker.use_load_checker(): Obtain broker-* option via
       X2GoBroker.get_profile_broker(), not via X2GoBroker.get_profile().
+    - Various improvements / fixes for session selection via the load checker
+      daemon.
   * debian/control:
     + Provide separate bin:package for SSH brokerage: x2gobroker-ssh.
     + Replace LDAP support with session brokerage support in LONG_DESCRIPTION.
diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py
index 2bcf255..94c351e 100644
--- a/x2gobroker/brokers/base_broker.py
+++ b/x2gobroker/brokers/base_broker.py
@@ -1067,6 +1067,20 @@ class X2GoBroker(object):
             server_list = profile[u'host']
             random.shuffle(server_list)
 
+            # if the load checker is in use for this profile, let's retrieve the available server loads here
+            # because:
+            #    - it is fast...
+            #    - if hosts are marked as "HOST-UNREACHABLE", we don't have to attempt
+            #      using them as a remote agent (reduce delays at session
+            #      startup/resumption)
+            #    - the retrieved load factors can be re-used in X2GoBroker.select_session().
+            load_factors = {}
+            if self.use_load_checker(profile_id):
+                load_factors = x2gobroker.loadchecker.check_load(self.backend_name, profile_id)
+                for h in [ _h for _h in load_factors.keys() if type(load_factors[_h]) != types.LongType ]:
+                    if h in server_list:
+                        server_list.remove(h)
+
             for agent in exclude_agents:
                 if agent['hostname'] in server_list:
                     server_list.remove(agent['hostname'])
@@ -1097,6 +1111,9 @@ class X2GoBroker(object):
 
             if not remote_agent:
                 logger_broker.warning('base_broker.X2GoBroker.get_remote_agent(): failed to allocate any broker agent (query-mode: {query_mode}, remote_agent: {remote_agent})'.format(query_mode=agent_query_mode, remote_agent=remote_agent))
+            else:
+                # ship the load_factors retrieved from the load checker service in the remote_agent dict
+                remote_agent[u'load_factors'] = load_factors
 
         elif agent_query_mode == u'LOCAL':
             # use a non-False value here, not used anywhere else...
@@ -1310,7 +1327,7 @@ class X2GoBroker(object):
         server_name = server_list[0]
         server_port = profile['sshport']
 
-        # try to retrieve contact to a remote broker agent
+        # try to retrieve a remote broker agent
         remote_agent = self.get_remote_agent(profile_id)
 
         # check for already running sessions for the given user (if any is given)
@@ -1328,14 +1345,18 @@ class X2GoBroker(object):
         _save_server_list = None
         _save_busy_servers = None
         initial_server_list = copy.deepcopy(server_list)
+
         while not selected_session and server_list:
 
+            if session_list:
+                matching_server_names = x2gobroker.utils.matching_hostnames(server_list, [ si.split('|')[3] for si in session_list ])
+
             if remote_agent == {}:
 
                 # we failed to contact any remote agent, so it is very likely, that all servers are down...
                 server_list = []
 
-            elif session_list:
+            elif session_list and matching_server_names:
 
                 # Obviously a remote broker agent reported an already running session
                 # on the / on one the available X2Go Server host(s)
@@ -1347,8 +1368,6 @@ class X2GoBroker(object):
                     running_sessions = []
                     suspended_sessions = []
 
-                    matching_server_names = x2gobroker.utils.matching_hostnames(server_list, [ si.split('|')[3] for si in session_list ])
-
                     for session_info in session_list:
                         if session_info.split('|')[3] in matching_server_names:
                             if session_info.split('|')[4] == 'R':
@@ -1406,7 +1425,10 @@ class X2GoBroker(object):
                 # status)
                 if busy_servers is None:
                     try:
-                        success, busy_servers = x2gobroker.agent.find_busy_servers(username=username, remote_agent=remote_agent)
+                        if remote_agent['load_factors']:
+                            success, busy_servers = x2gobroker.agent.get_servers(username=username, remote_agent=remote_agent)
+                        else:
+                            success, busy_servers = x2gobroker.agent.find_busy_servers(username=username, remote_agent=remote_agent)
                     except x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException:
                         pass
 
@@ -1444,7 +1466,8 @@ class X2GoBroker(object):
                             server_list = server_list_normalized
                             busy_servers = busy_servers_normalized
 
-                    # the list of busy_servers only shows servers with session, but not those servers that are entirely idle...
+                    # the list of busy_servers only shows servers with sessions, but not those servers that are entirely idle...
+
                     for server in server_list:
                         if server not in busy_servers.keys():
                             busy_servers[server] = 0
@@ -1454,21 +1477,29 @@ class X2GoBroker(object):
                         if busy_server not in server_list:
                             del busy_servers[busy_server]
 
+                    # dynamic load-balancing via load checker service
+                    if remote_agent['load_factors']:
 
-                    # dynamic load-balancing
-                    if self.use_load_checker(profile_id):
+                        load_factors = remote_agent['load_factors']
                         busy_servers_temp = copy.deepcopy(busy_servers)
-                        load_factors = x2gobroker.loadchecker.checkload(self.backend_name, profile_id)
-                        if load_factors:
-                            for busy_server in busy_servers_temp.keys():
-                                # FIXME: this may need love later for peculiar multi-farm setups with non-FQDN hostnames in session profile configurations
-                                if busy_server in load_factors.keys() and type(load_factors[busy_server]) == types.LongType:
-                                    # do the load-factor / relX2GoServerUsage calculation here...
-                                    busy_servers_temp[busy_server] = load_factors[busy_server] / busy_servers[busy_server]
-                                else:
-                                    # ignore the load checker, results are garbage...
-                                    busy_servers_temp = None
-                                    break
+
+                        for busy_server in busy_servers_temp.keys():
+                            if busy_server in load_factors.keys() and type(load_factors[busy_server]) is not types.LongType:
+                                # if a host cannot report its load, let's ignore it...
+                                del busy_servers_temp[busy_server]
+
+                            elif busy_server in load_factors.keys() and  ( type(load_factors[busy_server]) is types.LongType or busy_servers[busy_server] == 0):
+
+                                # when using the load checker service, then busy_servers contains the number of sessions per host
+
+                                # do the load-factor / numSessions calculation here... (avoid divison-by-zero by adding +1 to
+                                # the number of sessions here)
+                                busy_servers_temp[busy_server] = 1.0 / (load_factors[busy_server] / ( busy_servers[busy_server] +1))
+
+                            else:
+                                # ignore the load checker, results are garbage...
+                                busy_servers_temp = None
+                                break
 
                         if busy_servers_temp is not None:
                             busy_servers = copy.deepcopy(busy_servers_temp)

--
Alioth's /srv/git/code.x2go.org/x2gobroker.git//..//_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git


More information about the x2go-commits mailing list