def __init__(self, remote_idurl, ack_timeout, cache_timeout, cache_retries, ping_retries, skip_outbox, keep_alive, fake_identity, channel, channel_counter, debug_level=0, log_events=False, log_transitions=False, publish_events=False, **kwargs): """ Builds `handshaker()` state machine. """ global _KnownChannels self.remote_idurl = strng.to_bin(remote_idurl) self.remote_global_id = global_id.idurl2glob(self.remote_idurl) self.ack_timeout = ack_timeout self.cache_timeout = cache_timeout self.cache_retries = cache_retries self.ping_retries = ping_retries self.skip_outbox = skip_outbox self.keep_alive = keep_alive self.fake_identity = fake_identity self.channel = channel self.channel_counter = channel_counter if self.channel not in _KnownChannels: _KnownChannels[self.channel] = 0 _KnownChannels[self.channel] += 1 super(Handshaker, self).__init__( name="handshake_%s%d_%s" % (self.channel.replace('_', ''), _KnownChannels[self.channel], self.remote_global_id), state="AT_STARTUP", debug_level=debug_level, log_events=log_events, log_transitions=log_transitions, publish_events=publish_events, **kwargs )
def _do_remember_brokers(self, event, *args, **kwargs): if _Debug: lg.args(_DebugLevel, event, *args, **kwargs) self.active_broker_id = None self.active_queue_id = None for position in range(groups.REQUIRED_BROKERS_COUNT): broker_idurl = self.connected_brokers.get(position) if not broker_idurl: groups.clear_broker(self.group_creator_id, position) continue broker_id = global_id.idurl2glob(broker_idurl) groups.set_broker(self.group_creator_id, broker_id, position) if position == 0: self.dead_broker_id = None self.active_broker_id = broker_id self.active_queue_id = global_id.MakeGlobalQueueID( queue_alias=self.group_queue_alias, owner_id=self.group_creator_id, supplier_id=self.active_broker_id, ) if self.active_broker_id is None: if 0 in self.hired_brokers: self.active_broker_id = self.hired_brokers[0] self.active_queue_id = global_id.MakeGlobalQueueID( queue_alias=self.group_queue_alias, owner_id=self.group_creator_id, supplier_id=self.active_broker_id, ) if self.active_broker_id is None: raise Exception('no active broker is connected after event %r' % event) self.rotated_brokers = [] self.hired_brokers.clear() self.missing_brokers.clear() self.connecting_brokers.clear()
def _do_prepare_service_request_params(self, possible_broker_idurl, desired_broker_position=-1, action='queue-connect'): queue_id = global_id.MakeGlobalQueueID( queue_alias=self.group_queue_alias, owner_id=self.group_creator_id, supplier_id=global_id.idurl2glob(possible_broker_idurl), ) group_key_info = my_keys.get_key_info(self.group_key_id, include_private=False, include_signature=True) service_request_params = { 'action': action, 'queue_id': queue_id, 'consumer_id': self.member_id, 'producer_id': self.member_id, 'group_key': group_key_info, 'last_sequence_id': self.last_sequence_id, 'archive_folder_path': groups.get_archive_folder_path(self.group_key_id), } if desired_broker_position >= 0: service_request_params['position'] = desired_broker_position if _Debug: lg.args(_DebugLevel, service_request_params=service_request_params) return service_request_params
def doSelectOneUser(self, *args, **kwargs): """ Action method. """ if 'remote_idurl' in kwargs: self.target_idurl = kwargs['remote_idurl'] else: self.target_idurl = args[0][0] self.target_id = global_id.idurl2glob(self.target_idurl)
def doRememberNode(self, *args, **kwargs): """ Action method. """ self.possible_router_idurl = None self.router_idurl = id_url.field(args[0]) self.router_id = global_id.idurl2glob(self.router_idurl) self.router_identity = None self.router_proto_host = None if _Debug: lg.out(_DebugLevel, 'proxy_receiver.doRememberNode %r' % self.router_idurl)
def doLoadRouterInfo(self, *args, **kwargs): """ Action method. """ s = config.conf().getString('services/proxy-transport/current-router').strip() try: self.router_idurl = id_url.field(s.split(' ')[0]) self.router_id = global_id.idurl2glob(self.router_idurl) except: lg.exc() if _Debug: lg.out(_DebugLevel, 'proxy_receiver.doLoadRouterInfo : %s' % self.router_idurl)
def on_customer_accepted(evt): customer_idurl = id_url.field(evt.data.get('idurl')) if not customer_idurl: lg.warn('unknown customer idurl in event data payload') return False customer_glob_id = global_id.idurl2glob(customer_idurl) queue_id = global_id.MakeGlobalQueueID( queue_alias='supplier-file-modified', owner_id=customer_glob_id, supplier_id=my_id.getGlobalID(), ) if not p2p_queue.is_queue_exist(queue_id): customer_key_id = global_id.MakeGlobalID(customer=customer_glob_id, key_alias='customer') if my_keys.is_key_registered(customer_key_id): try: p2p_queue.open_queue(queue_id) except Exception as exc: lg.warn('failed to open queue %s : %s' % (queue_id, str(exc))) else: lg.warn('customer key %r for supplier queue not registered' % customer_key_id) if p2p_queue.is_queue_exist(queue_id): if not p2p_queue.is_producer_exist(my_id.getGlobalID()): try: p2p_queue.add_producer(my_id.getGlobalID()) except Exception as exc: lg.warn('failed to add producer: %s' % str(exc)) if p2p_queue.is_producer_exist(my_id.getGlobalID()): if not p2p_queue.is_producer_connected(my_id.getGlobalID(), queue_id): try: p2p_queue.connect_producer(my_id.getGlobalID(), queue_id) except Exception as exc: lg.warn('failed to connect producer: %s' % str(exc)) if p2p_queue.is_producer_connected(my_id.getGlobalID(), queue_id): if not p2p_queue.is_event_publishing(my_id.getGlobalID(), 'supplier-file-modified'): try: p2p_queue.start_event_publisher( my_id.getGlobalID(), 'supplier-file-modified') except Exception as exc: lg.warn('failed to start event publisher: %s' % str(exc)) return True
def _on_customer_accepted(self, e): from logs import lg from userid import my_id from userid import global_id from p2p import p2p_queue customer_idurl = e.data.get('idurl') if not customer_idurl: lg.warn('unknown customer idurl in event data payload') return customer_glob_id = global_id.idurl2glob(customer_idurl) queue_id = global_id.MakeGlobalQueueID( queue_alias='supplier-file-modified', owner_id=customer_glob_id, supplier_id=my_id.getGlobalID(), ) if not p2p_queue.is_queue_exist(queue_id): try: p2p_queue.open_queue(queue_id) except Exception as exc: lg.warn('failed to open queue %s : %s' % (queue_id, str(exc))) if p2p_queue.is_queue_exist(queue_id): if not p2p_queue.is_producer_exist(my_id.getGlobalID()): try: p2p_queue.add_producer(my_id.getGlobalID()) except Exception as exc: lg.warn('failed to add producer: %s' % str(exc)) if p2p_queue.is_producer_exist(my_id.getGlobalID()): if not p2p_queue.is_producer_connected(my_id.getGlobalID(), queue_id): try: p2p_queue.connect_producer(my_id.getGlobalID(), queue_id) except Exception as exc: lg.warn('failed to connect producer: %s' % str(exc)) if p2p_queue.is_producer_connected(my_id.getGlobalID(), queue_id): if not p2p_queue.is_event_publishing( my_id.getGlobalID(), 'supplier-file-modified'): try: p2p_queue.start_event_publisher( my_id.getGlobalID(), 'supplier-file-modified') except Exception as exc: lg.warn('failed to start event publisher: %s' % str(exc))
def _on_customer_terminated(self, e): from logs import lg from userid import my_id from userid import global_id from p2p import p2p_queue customer_idurl = e.data.get('idurl') if not customer_idurl: lg.warn('unknown customer idurl in event data payload') return customer_glob_id = global_id.idurl2glob(customer_idurl) queue_id = global_id.MakeGlobalQueueID( queue_alias='supplier-file-modified', owner_id=customer_glob_id, supplier_id=my_id.getGlobalID(), ) # TODO: need to decide when to stop producing # might be that other customers needs that info still if p2p_queue.is_event_publishing(my_id.getGlobalID(), 'supplier-file-modified'): try: p2p_queue.stop_event_publisher(my_id.getGlobalID(), 'supplier-file-modified') except Exception as exc: lg.warn('failed to stop event publisher: %s' % str(exc)) if p2p_queue.is_producer_connected(my_id.getGlobalID(), queue_id): try: p2p_queue.disconnect_producer(my_id.getGlobalID(), queue_id) except Exception as exc: lg.warn('failed to disconnect producer: %s' % str(exc)) if p2p_queue.is_producer_exist(my_id.getGlobalID()): try: p2p_queue.remove_producer(my_id.getGlobalID()) except Exception as exc: lg.warn('failed to remove producer: %s' % str(exc)) if p2p_queue.is_queue_exist(queue_id): try: p2p_queue.close_queue(queue_id) except Exception as exc: lg.warn('failed to stop queue %s : %s' % (queue_id, str(exc)))
def on_identity_url_changed(evt): from access import group_member service_dir = settings.ServiceDir('service_private_groups') groups_dir = os.path.join(service_dir, 'groups') brokers_dir = os.path.join(service_dir, 'brokers') old_idurl = id_url.field(evt.data['old_idurl']) new_idurl = id_url.field(evt.data['new_idurl']) active_group_keys = list(active_groups()) to_be_reconnected = [] for group_key_id in active_group_keys: if not group_key_id: continue group_creator_idurl = global_id.glob2idurl(group_key_id) if id_url.is_the_same(group_creator_idurl, old_idurl): old_group_path = os.path.join(groups_dir, group_key_id) latest_group_key_id = my_keys.latest_key_id(group_key_id) latest_group_path = os.path.join(groups_dir, latest_group_key_id) lg.info('going to rename rotated group file: %r -> %r' % (old_group_path, latest_group_path, )) if os.path.isfile(old_group_path): try: os.rename(old_group_path, latest_group_path) except: lg.exc() continue else: lg.warn('key file %r was not found, key was not renamed' % old_group_path) active_groups()[latest_group_key_id] = active_groups().pop(group_key_id) group_member.rotate_active_group_memeber(group_key_id, latest_group_key_id) gm = group_member.get_active_group_member(group_key_id) if gm and gm.connected_brokers and id_url.is_in(old_idurl, gm.connected_brokers.values()): lg.info('connected broker %r IDURL is rotated, going to reconnect %r' % (old_idurl, gm, )) if group_key_id not in to_be_reconnected: to_be_reconnected.append(group_key_id) known_customers = list(known_brokers().keys()) for customer_id in known_customers: latest_customer_id = global_id.idurl2glob(new_idurl) customer_idurl = global_id.glob2idurl(customer_id) if id_url.is_the_same(customer_idurl, old_idurl): latest_customer_dir = os.path.join(brokers_dir, latest_customer_id) lg.info('going to rename rotated customer id: %r -> %r' % (customer_id, latest_customer_id, )) old_customer_dir = os.path.join(brokers_dir, customer_id) if os.path.isdir(old_customer_dir): try: bpio.move_dir_recursive(old_customer_dir, latest_customer_dir) bpio.rmdir_recursive(old_customer_dir) except: lg.exc() continue known_brokers()[latest_customer_id] = known_brokers().pop(customer_id) for broker_pos, broker_id in enumerate(known_brokers(latest_customer_id)): if not broker_id: continue broker_idurl = global_id.glob2idurl(broker_id) if broker_idurl == old_idurl: latest_broker_id = global_id.idurl2glob(new_idurl) latest_broker_path = os.path.join(latest_customer_dir, latest_broker_id) lg.info('going to rename rotated broker id: %r -> %r' % (broker_id, latest_broker_id, )) old_broker_path = os.path.join(latest_customer_dir, broker_id) if os.path.isfile(old_broker_path): try: os.rename(old_broker_path, latest_broker_path) except: lg.exc() continue if latest_broker_id in known_brokers(latest_customer_id): lg.warn('broker %r already exist' % latest_broker_id) continue known_brokers()[latest_customer_id][broker_pos] = latest_broker_id if _Debug: lg.args(_DebugLevel, to_be_reconnected=to_be_reconnected) for group_key_id in to_be_reconnected: gm = group_member.get_active_group_member(group_key_id) if gm: gm.automat('reconnect')