def get_group_info(n, request): try: group = int(request) group_object = bla.get_group(group) return group_object.info() except Exception as e: logging.error("Balancer error: " + str(e) + "\n" + traceback.format_exc()) return {'Balancer error': str(e)}
def make_symm_group(n, couple): couple = tuple(couple) logging.info("writing couple info: " + str(couple)) packed = msgpack.packb(couple) logging.info("packed couple: \"%s\"" % str(packed).encode("hex")) s = elliptics.Session(n) good = [] bad = () for g in couple: try: s.add_groups([g]) s.write_data(symmetric_groups_key, packed) good.append(g) bla.get_group(g).setCouples(couple) except Exception as e: logging.error("Failed to write symm group info, group %d: %s\n%s" % (g, str(e), traceback.format_exc())) bad = (g, e) break return (good, bad)
def couple_groups(n, request): try: logging.info("----------------------------------------") logging.info("New couple groups request: " + str(request)) logging.info(request) uncoupled_groups = bla.uncoupled_groups() dc_by_group_id = {} group_by_dc = {} for group_id in uncoupled_groups: group_object = bla.get_group(group_id) dc = group_object.get_dc() dc_by_group_id[group_id] = dc groups_in_dc = group_by_dc.setdefault(dc, []) groups_in_dc.append(group_id) logging.info("dc by group: %s" % str(dc_by_group_id)) logging.info("group_by_dc: %s" % str(group_by_dc)) size = int(request[0]) mandatory_groups = [int(g) for g in request[1]] # check mandatory set for group_id in mandatory_groups: if group_id not in uncoupled_groups: raise Exception("group %d is coupled" % group_id) dc = dc_by_group_id[group_id] if dc not in group_by_dc: raise Exception("groups must be in different dcs") del group_by_dc[dc] groups_to_couple = copy.copy(mandatory_groups) # need better algorithm for this. For a while - only 1 try and random selection n_groups_to_add = size - len(groups_to_couple) if n_groups_to_add > len(group_by_dc): raise Exception("Not enough dcs") if n_groups_to_add < 0: raise Exception("Too many mandatory groups") some_dcs = group_by_dc.keys()[:n_groups_to_add] for dc in some_dcs: groups_to_couple.append(group_by_dc[dc].pop()) (good, bad) = make_symm_group(n, groups_to_couple) if bad: raise bad[1] return groups_to_couple except Exception as e: logging.error("Balancer error: " + str(e) + "\n" + traceback.format_exc()) return {'Balancer error': str(e)}
def updateSymmGroup(self, group_id): try: self.__session.add_groups([group_id]) couples = msgpack.unpackb(self.__session.read_data(symmetric_groups_key)) self.__logging.info("Read symmetric groups from group %d: %s" % (group_id, str(couples))) bla.get_group(int(group_id)).setCouples(couples) for group_id2 in couples: if group_id2 != group_id: self.__tq.hurry(get_symm_group_update_task_id(group_id2)) except Exception as e: self.__logging.error("Failed to read symmetric_groups from group %d (%s)" % (group_id, str(e))) bla.get_group(int(group_id)).unsetCouples() except: self.__logging.error("Failed to read symmetric_groups from group %d (%s)" % (group_id, sys.exc_info()[0])) bla.get_group(int(group_id)).unsetCouples()
def balance(n, request): global stats, groups, symm_groups try: logging.info("----------------------------------------") logging.info("New request" + str(len(request))) logging.info(request) weighted_groups = get_group_weights(n) target_groups = [] if manifest().get("symmetric_groups", False): lsymm_groups = weighted_groups[request[0]] for (gr_list, weight) in lsymm_groups: logging.info("gr_list: %s %d" % (str(gr_list), request[0])) grl = {'rating': weight, 'groups': gr_list} logging.info("grl: %s" % str(grl)) target_groups.append(grl) logging.info("target_groups: %s" % str(target_groups)) if target_groups: sorted_groups = sorted(target_groups, key=lambda gr: gr['rating'], reverse=True)[0] logging.info(sorted_groups) result = (sorted_groups['groups'], request[1]) else: result = ([], request[1]) else: for group_id in bla.all_group_ids(): target_groups.append(bla.get_group(int(group_id))) sorted_groups = sorted(target_groups, key=lambda gr: gr.freeSpaceInKb(), reverse=True)[:int(request[0])] logging.info(sorted_groups) result = ([g.groupId() for g in sorted_groups], request[1]) logging.info("result: %s" % str(result)) return result except Exception as e: logging.error("Balancer error: " + str(e) + "\n" + traceback.format_exc()) return {'Balancer error': str(e)}