def staged_log(populate_with_changes=True): """Staging procedure takes manually created log items, populate them with diff and connections diff Current implementation prevents from several things to occur: - same log_action (resource.action pair) cannot not be staged multiple times - child will be staged only if diff or connections_diff is changed, and we can execute *run* action to apply that diff - in all other cases child should be staged explicitly """ log_actions = set() resources_names = set() staged_log = data.SL() without_duplicates = [] for log_item in staged_log: if log_item.log_action in log_actions: log_item.delete() continue resources_names.add(log_item.resource) log_actions.add(log_item.log_action) without_duplicates.append(log_item) utils.solar_map(lambda li: populate_log_item(li), without_duplicates, concurrency=10) # this is backward compatible change, there might better way # to "guess" child actions childs = filter(lambda child: child.name not in resources_names, resource.load_childs(list(resources_names))) child_log_items = filter( lambda li: li.diff or li.connections_diff, utils.solar_map(create_run, [c.name for c in childs], concurrency=10)) for log_item in child_log_items + without_duplicates: log_item.save_lazy() return without_duplicates + child_log_items
def connect(self, other, mapping): other_inputs = other.inputs if mapping is None: return if self == other: raise Exception('Trying to connect value-.* to itself') solar_map( lambda (my_name, other_name): self._connect_single(other_inputs, other_name, my_name), mapping.iteritems(), concurrency=2)
def disconnect(self, other, inputs): def _to_disconnect((emitter, receiver, meta)): if not receiver[0] == other_key: return False # name there? if not emitter[0] == self.key: return False key = emitter[1] if key not in converted: return False convs = converted[key] for conv in convs: if conv: if meta['tag'] == conv['tag'] \ and meta['destination_key'] == conv['destination_key']: return True else: return True return False def _convert_input(input): spl = input.split('|') spl_len = len(spl) if spl_len == 1: # normal input return input, None elif spl_len == 3: return spl[0], {'tag': spl[1], 'destination_key': spl[2]} else: raise Exception("Cannot convert input %r" % input) def _format_for_disconnect((emitter, receiver, meta)): input = receiver[1] if not meta: return "{}|{}|{}".format(receiver[1], emitter[0], emitter[1]) dest_key = meta['destination_key'] tag = meta.get('tag', other.name) return '{}:{}|{}'.format(input, dest_key, tag) converted = defaultdict(list) for k, v in map(_convert_input, inputs): converted[k].append(v) other_key = other.key edges = other.inputs._edges() edges = filter(_to_disconnect, edges) inputs = map(_format_for_disconnect, edges) solar_map(other.inputs.disconnect, inputs, concurrency=2)
def stage_changes(): for li in data.SL(): li.delete() last = LogItem.history_last() since = StrInt.greater(last.updated) if last else None staged_log = utils.solar_map(make_single_stage_item, resource.load_updated(since), concurrency=10) staged_log = filter(None, staged_log) return staged_log
def as_dict(self): items = solar_map(lambda x: (x, self._get_field_val(x)), [x for x in self], concurrency=3) return dict(items)