hat.monitor.server.blessing
Implementation of blessing calculation algorithms
1"""Implementation of blessing calculation algorithms""" 2 3from collections.abc import Iterable 4import collections 5import enum 6import itertools 7import time 8 9from hat.monitor import common 10 11 12_next_tokens = itertools.count(1) 13 14 15class Algorithm(enum.Enum): 16 BLESS_ALL = 'BLESS_ALL' 17 BLESS_ONE = 'BLESS_ONE' 18 19 20def calculate(components: Iterable[common.ComponentInfo], 21 group_algorithms: dict[str, Algorithm], 22 default_algorithm: Algorithm 23 ) -> Iterable[tuple[common.Mid, common.Cid, common.BlessingReq]]: 24 """Calculate blessing request changes 25 26 Args: 27 components: components state with previous blessing tokens 28 group_algorithms: association of algorithm to group 29 default_algorithm: default algorithm 30 31 Returns: 32 blessing request changes 33 34 """ 35 group_components = collections.defaultdict(collections.deque) 36 for c in components: 37 group_components[c.group].append(c) 38 39 for group, components_from_group in group_components.items(): 40 algorithm = group_algorithms.get(group, default_algorithm) 41 42 yield from _calculate_group(algorithm, components_from_group) 43 44 45def _calculate_group(algorithm, components): 46 if algorithm == Algorithm.BLESS_ALL: 47 yield from _bless_all(components) 48 49 elif algorithm == Algorithm.BLESS_ONE: 50 yield from _bless_one(components) 51 52 else: 53 raise ValueError('unsupported algorithm') 54 55 56def _bless_all(components): 57 for c in components: 58 if not c.blessing_res.ready: 59 blessing_req = common.BlessingReq(token=None, 60 timestamp=None) 61 62 elif _has_blessing(c): 63 blessing_req = c.blessing_req 64 65 else: 66 blessing_req = common.BlessingReq(token=next(_next_tokens), 67 timestamp=time.time()) 68 69 if c.blessing_req != blessing_req: 70 yield c.mid, c.cid, blessing_req 71 72 73def _bless_one(components): 74 75 def highlander_battle(highlander, c): 76 if not highlander: 77 return c 78 if c.rank < highlander.rank: 79 return c 80 if c.rank == highlander.rank: 81 if _has_blessing(c) and not _has_blessing(highlander): 82 return c 83 if _has_blessing(c) and _has_blessing(highlander): 84 if (c.blessing_req.timestamp < 85 highlander.blessing_req.timestamp): 86 return c 87 if _has_blessing(c) and _has_blessing(highlander) or ( 88 not _has_blessing(c) and 89 not _has_blessing(highlander)): 90 if c.mid < highlander.mid: 91 return c 92 return highlander 93 94 highlander = None 95 for c in components: 96 if not c.blessing_res.ready: 97 continue 98 highlander = highlander_battle(highlander, c) 99 100 if highlander and not (highlander.blessing_res.token and 101 highlander.blessing_res.token == 102 highlander.blessing_req.token): 103 for c in components: 104 if c.blessing_res.token and c != highlander: 105 highlander = None 106 break 107 108 for c in components: 109 if c != highlander: 110 blessing_req = common.BlessingReq(token=None, 111 timestamp=None) 112 113 elif not _has_blessing(c): 114 blessing_req = common.BlessingReq(token=next(_next_tokens), 115 timestamp=time.time()) 116 117 else: 118 blessing_req = c.blessing_req 119 120 if c.blessing_req != blessing_req: 121 yield c.mid, c.cid, blessing_req 122 123 124def _has_blessing(component): 125 return (component.blessing_req.token and 126 component.blessing_req.timestamp)
class
Algorithm(enum.Enum):
BLESS_ALL =
<Algorithm.BLESS_ALL: 'BLESS_ALL'>
BLESS_ONE =
<Algorithm.BLESS_ONE: 'BLESS_ONE'>
def
calculate( components: Iterable[hat.monitor.common.ComponentInfo], group_algorithms: dict[str, Algorithm], default_algorithm: Algorithm) -> Iterable[tuple[int, int, hat.monitor.common.BlessingReq]]:
21def calculate(components: Iterable[common.ComponentInfo], 22 group_algorithms: dict[str, Algorithm], 23 default_algorithm: Algorithm 24 ) -> Iterable[tuple[common.Mid, common.Cid, common.BlessingReq]]: 25 """Calculate blessing request changes 26 27 Args: 28 components: components state with previous blessing tokens 29 group_algorithms: association of algorithm to group 30 default_algorithm: default algorithm 31 32 Returns: 33 blessing request changes 34 35 """ 36 group_components = collections.defaultdict(collections.deque) 37 for c in components: 38 group_components[c.group].append(c) 39 40 for group, components_from_group in group_components.items(): 41 algorithm = group_algorithms.get(group, default_algorithm) 42 43 yield from _calculate_group(algorithm, components_from_group)
Calculate blessing request changes
Arguments:
- components: components state with previous blessing tokens
- group_algorithms: association of algorithm to group
- default_algorithm: default algorithm
Returns:
blessing request changes