def req_op(node, actor_id=None, component=None): """ Returns any node that have the actor """ if not actor_id: #empty it = dynops.List() it.set_name("actor_nodes_empty") it.final() return it it = dynops.List() it.set_name("actor_nodes") def _got_actor(key, value): try: it.append(value['node_id']) except: pass it.final() node.storage.get_actor(actor_id=actor_id, cb=_got_actor) return it
def req_op(node, actor_id=None, component=None, replication_id=None): """ Returns any nodes that have replicas of actor """ if replication_id is None: #empty it = dynops.List() it.set_name("replica_nodes_empty") it.final() return it it = node.storage.get_index_iter(['replicas', 'nodes', replication_id]) it.set_name("replica_nodes") return it
def execute_requirements(self, application_id, cb): """ Build dynops iterator to collect all possible placements, then trigger migration. For initial deployment (all actors on the current node) """ app = None try: app = self.applications[application_id] except: _log.debug("execute_requirements did not find app %s" % (application_id, )) cb(status=response.CalvinResponse(False)) return _log.debug("execute_requirements(app=%s)" % (self.applications[application_id], )) # TODO extract groups if hasattr(app, '_org_cb'): # application deployment requirements ongoing, abort cb(status=response.CalvinResponse(False)) return app._org_cb = cb app.done_final = False app._collect_placement_counter = 0 app._collect_placement_last_value = 0 actor_placement_it = dynops.List() app.actor_placement = {} # Clean placement slate _log.analyze(self._node.id, "+ APP REQ", {}, tb=True) for actor_id in app.get_actors(): if actor_id not in self._node.am.actors.keys(): _log.debug("Only apply requirements to local actors") continue _log.analyze(self._node.id, "+ ACTOR REQ", {'actor_id': actor_id}, tb=True) actor_req = self.actor_requirements( app, actor_id).set_name("Actor" + actor_id) actor_placement_it.append((actor_id, actor_req), trigger_iter=actor_req) _log.analyze(self._node.id, "+ ACTOR REQ DONE", {'actor_id': actor_id}, tb=True) actor_placement_it.final() collect_iter = dynops.Collect(actor_placement_it) collect_iter.set_cb(self.collect_placement, collect_iter, app) self.collect_placement(collect_iter, app) _log.analyze(self._node.id, "+ DONE", {'application_id': application_id}, tb=True)
def req_op(node, port_property, actor_id=None, component=None): """ Lockup port_property returns a dynamic iterable which is a union of all possible runtimes actor_id is the actor that this is requested for component contains a list of all actor_ids of the component if the actor belongs to a component else None """ it = [] for p in port_property: it.append(node.storage.get_index_iter(['node', 'capabilities', p])) if len(it) > 1: final = dynops.Union(*it) elif len(it) == 1: final = it[0] else: # Empty list, this is bad, but somone elses problem final = dynops.List() final.final() final.set_name("port_property_match") return final
def resolve_remote(self, actor_name, info, cb=None): # FIXME: no list needed since it is only done for one actor all_desc_iters = dynops.List() store = GlobalStore(node=self.node) desc_iter = store.global_lookup_iter(info['signature'], info['args'].keys()) all_desc_iters.append((actor_name, desc_iter), trigger_iter=desc_iter) all_desc_iters.final() collect_desc_iter = dynops.Collect(all_desc_iters).set_name( "collected_desc") select_iter = dynops.Map( self.select_actor, collect_desc_iter, done=False, priority={k: [] for k in self.deployable['actors'].keys()}, eager=True).set_name("select_actor") select_iter.set_cb(self.deploy_unhandled_actor, select_iter, cb) self.deploy_unhandled_actor(select_iter, cb)
def get_concat_iter(self, prefix, key, include_key=False): """ Get multiple values for registry key: prefix+key, union of locally added but not yet distributed values and values added by others. It is assumed that the prefix and key are strings, the sum has to be an immutable object. Values are placed in returned dynamic iterable object. When the parameter include_key is True a tuple of (key, value) is placed in dynamic iterable object instead of only the retrived value. The dynamic iterable are of the List subclass to calvin.utilities.dynops.DynOps, see DynOps for details of how they are used. The final method will be called when all values are appended to the returned dynamic iterable. The registry can be eventually consistent, e.g. a removal of a value might only have reached part of a distributed registry and hence still be part of returned list of values, it may also miss values added by others but not yet distributed. """ _log.analyze(self.node.id, "+ BEGIN", {'key': key}) if prefix + key in self.localstore_sets: _log.analyze(self.node.id, "+ GET LOCAL", None) value = self.localstore_sets[prefix + key] # Return the set that we intended to append since that's all we have until it is synced local_list = list(value['+']) _log.analyze(self.node.id, "+", {'value': local_list, 'key': key}) else: local_list = [] if include_key: local_list = [(key, v) for v in local_list] it = dynops.List(local_list) try: self.storage.get_concat(key=prefix + key, cb=CalvinCB(func=self.get_concat_iter_cb, org_key=key, include_key=include_key, it=it)) except: if self.started: _log.error("Failed to get: %s" % key, exc_info=True) it.final() _log.analyze(self.node.id, "+ END", {'key': key, 'iter': str(it)}) return it
def req_op(node, actor_id=None, component=None): """ Returns any nodes that have replicas of actor """ #FIXME Need to handle when actor_id is not local actor!!! try: actor = node.am.actors[actor_id] replication_id = actor._replication_data.id if not actor._replication_data._one_per_runtime: replication_id = None except: replication_id = None if replication_id is None: #empty it = dynops.List() it.set_name("replica_nodes_empty") it.final() return it it = node.storage.get_index_iter(['replicas', 'nodes', replication_id]) it.set_name("replica_nodes") return it
def req_op(node, actor_id=None, component=None): """ current node """ it = dynops.List([node.id]) it.final() return it