def start(self): from logs import lg from transport import callback from main import events from contacts import contactsdb from storage import accounting from services import driver from supplier import customer_space callback.append_inbox_callback(self._on_inbox_packet_received) events.add_subscriber(customer_space.on_identity_url_changed, 'identity-url-changed') events.add_subscriber(customer_space.on_customer_accepted, 'existing-customer-accepted') events.add_subscriber(customer_space.on_customer_accepted, 'new-customer-accepted') events.add_subscriber(customer_space.on_customer_terminated, 'existing-customer-denied') events.add_subscriber(customer_space.on_customer_terminated, 'existing-customer-terminated') space_dict, _ = accounting.read_customers_quotas() for customer_idurl in contactsdb.customers(): known_customer_meta_info = contactsdb.get_customer_meta_info(customer_idurl) events.send('existing-customer-accepted', data=dict( idurl=customer_idurl, allocated_bytes=space_dict.get(customer_idurl.to_bin()), ecc_map=known_customer_meta_info.get('ecc_map'), position=known_customer_meta_info.get('position'), )) if driver.is_on('service_entangled_dht'): self._do_connect_suppliers_dht_layer() else: lg.warn('service service_entangled_dht is OFF') events.add_subscriber(self._on_dht_layer_connected, event_id='dht-layer-connected') return True
def _do_create_revision_from_another_supplier(self, another_revision, another_suppliers, another_ecc_map): local_customer_meta_info = contactsdb.get_customer_meta_info( self.customer_idurl) possible_position = local_customer_meta_info.get('position', -1) or -1 if possible_position >= 0: try: another_suppliers[possible_position] = my_id.getLocalIDURL() except: lg.exc() contactsdb.add_customer_meta_info( self.customer_idurl, { 'ecc_map': another_ecc_map, 'position': possible_position, 'family_snapshot': another_suppliers, }) return { 'revision': int(another_revision), 'publisher_idurl': my_id.getLocalIDURL(), # I will be a publisher of that revision 'suppliers': another_suppliers, 'ecc_map': another_ecc_map, 'customer_idurl': self.customer_idurl, }
def start(self): from transport import callback from main import events from contacts import contactsdb from storage import accounting callback.append_inbox_callback(self._on_inbox_packet_received) events.add_subscriber(self._on_customer_accepted, 'existing-customer-accepted') events.add_subscriber(self._on_customer_accepted, 'new-customer-accepted') events.add_subscriber(self._on_customer_terminated, 'existing-customer-denied') events.add_subscriber(self._on_customer_terminated, 'existing-customer-terminated') space_dict = accounting.read_customers_quotas() for customer_idurl in contactsdb.customers(): known_customer_meta_info = contactsdb.get_customer_meta_info( customer_idurl) events.send('existing-customer-accepted', data=dict( idurl=customer_idurl, allocated_bytes=space_dict.get(customer_idurl), ecc_map=known_customer_meta_info.get('ecc_map'), position=known_customer_meta_info.get('position'), )) return True
def start(self): from logs import lg from main import events from contacts import contactsdb from supplier import family_member from transport import callback # TODO: check all imports.! my_id must be loaded latest as possible! from userid import my_id callback.append_inbox_callback(self._on_inbox_packet_received) for customer_idurl in contactsdb.customers(): if not customer_idurl: continue if customer_idurl == my_id.getLocalIDURL(): lg.warn('skipping my own identity') continue fm = family_member.by_customer_idurl(customer_idurl) if not fm: fm = family_member.create_family(customer_idurl) fm.automat('init') local_customer_meta_info = contactsdb.get_customer_meta_info(customer_idurl) fm.automat('family-join', { 'supplier_idurl': my_id.getLocalIDURL(), 'ecc_map': local_customer_meta_info.get('ecc_map'), 'position': local_customer_meta_info.get('position', -1), 'family_snapshot': local_customer_meta_info.get('family_snapshot'), }) events.add_subscriber(self._on_existing_customer_accepted, 'existing-customer-accepted') events.add_subscriber(self._on_new_customer_accepted, 'new-customer-accepted') events.add_subscriber(self._on_existing_customer_terminated, 'existing-customer-terminated') return True
def __init__(self, supplier_idurl, customer_idurl, needed_bytes, key_id=None, queue_subscribe=True): """ """ self.supplier_idurl = supplier_idurl self.customer_idurl = customer_idurl self.needed_bytes = needed_bytes self.key_id = key_id self.queue_subscribe = queue_subscribe if self.needed_bytes is None: total_bytes_needed = diskspace.GetBytesFromString( settings.getNeededString(), 0) num_suppliers = -1 if self.customer_idurl == my_id.getLocalIDURL(): num_suppliers = settings.getSuppliersNumberDesired() else: known_ecc_map = contactsdb.get_customer_meta_info( customer_idurl).get('ecc_map') if known_ecc_map: num_suppliers = eccmap.GetEccMapSuppliersNumber( known_ecc_map) if num_suppliers > 0: self.needed_bytes = int( math.ceil(2.0 * total_bytes_needed / float(num_suppliers))) else: raise Exception( 'not possible to determine needed_bytes value to be requested from that supplier' ) # self.needed_bytes = int(math.ceil(2.0 * settings.MinimumNeededBytes() / float(settings.DefaultDesiredSuppliers()))) name = 'supplier_%s_%s' % ( nameurl.GetName(self.supplier_idurl), diskspace.MakeStringFromBytes(self.needed_bytes).replace(' ', ''), ) self.request_packet_id = None self.callbacks = {} try: st = bpio.ReadTextFile( settings.SupplierServiceFilename( idurl=self.supplier_idurl, customer_idurl=self.customer_idurl, )).strip() except: st = 'DISCONNECTED' automat.Automat.__init__( self, name, state=st, debug_level=_DebugLevel, log_events=_Debug, log_transitions=_Debug, ) for cb in self.callbacks.values(): cb(self.supplier_idurl, self.state, self.state)
def do_calculate_needed_bytes(self): if self.needed_bytes is None: total_bytes_needed = diskspace.GetBytesFromString(settings.getNeededString(), 0) num_suppliers = -1 if self.customer_idurl == my_id.getLocalIDURL(): num_suppliers = settings.getSuppliersNumberDesired() else: known_ecc_map = contactsdb.get_customer_meta_info(self.customer_idurl).get('ecc_map') if known_ecc_map: num_suppliers = eccmap.GetEccMapSuppliersNumber(known_ecc_map) if num_suppliers > 0: self.needed_bytes = int(math.ceil(2.0 * total_bytes_needed / float(num_suppliers))) else: raise Exception('not possible to determine needed_bytes value to be requested from that supplier')
def _do_merge_revisions(self, dht_info, my_info, latest_revision): if dht_info is None or not isinstance(dht_info, dict): merged_info = my_info else: if latest_revision == int(dht_info['revision']): if my_info is not None: if latest_revision == int(my_info['revision']): # I have same revision as info from DHT merged_info = dht_info else: if int(my_info['revision']) > int( dht_info['revision']): # here my revision is higher, so I have some changes that needs to be published already merged_info = my_info else: # here my revision is lower, I need to take info from DHT merged_info = dht_info else: merged_info = dht_info else: # here my revision is higher, so I have some changes that needs to be published already merged_info = my_info if not merged_info: return None # make sure list of suppliers have correct length according to ecc_map if not merged_info['ecc_map']: known_ecc_map = contactsdb.get_customer_meta_info( self.customer_idurl).get('ecc_map', None) lg.warn('unknown ecc_map, will populate known value: %s' % known_ecc_map) merged_info['ecc_map'] = known_ecc_map if merged_info['ecc_map']: expected_suppliers_count = eccmap.GetEccMapSuppliersNumber( merged_info['ecc_map']) if len(merged_info['suppliers']) < expected_suppliers_count: merged_info['suppliers'] += [ b'', ] * (expected_suppliers_count - len(merged_info['suppliers'])) elif len(merged_info['suppliers']) > expected_suppliers_count: merged_info['suppliers'] = merged_info[ 'suppliers'][:expected_suppliers_count] if merged_info['revision'] != latest_revision: lg.info('will switch known revision %d to the latest: %d' % ( merged_info['revision'], latest_revision, )) merged_info['revision'] = latest_revision return merged_info
def publish_customer_supplier_relation(customer_idurl, supplier_idurl=None): if not supplier_idurl: supplier_idurl = my_id.getLocalID() meta_info = contactsdb.get_customer_meta_info(customer_idurl) if _Debug: lg.out(_DebugLevel, 'dht_relations.publish_customer_supplier_relation: customer:%s supplier:%s meta:%s' % ( customer_idurl, supplier_idurl, meta_info, )) new_data = { 'customer_idurl': customer_idurl, 'supplier_idurl': supplier_idurl, 'ecc_map': meta_info.get('ecc_map', None), 'time': utime.utcnow_to_sec1970(), 'signature': '', # TODO: add signature and verification methods } return RelationsLookup(customer_idurl, new_data=new_data, publish=True).start()
def _do_create_possible_revision(self, latest_revision): local_customer_meta_info = contactsdb.get_customer_meta_info( self.customer_idurl) possible_position = local_customer_meta_info.get('position', -1) possible_suppliers = local_customer_meta_info.get('family_snapshot') if possible_position > 0 and my_id.getLocalIDURL( ) not in possible_suppliers: if len(possible_suppliers) > possible_position: possible_suppliers[possible_position] = my_id.getLocalIDURL() return { 'revision': latest_revision, 'publisher_idurl': my_id.getLocalIDURL(), # I will be a publisher of that revision 'suppliers': possible_suppliers, 'ecc_map': local_customer_meta_info.get('ecc_map'), 'customer_idurl': self.customer_idurl, }
def start(self): from twisted.internet import reactor # @UnresolvedImport from logs import lg from main import events from contacts import contactsdb from userid import id_url from supplier import family_member from transport import callback from userid import my_id callback.append_inbox_callback(self._on_inbox_packet_received) for customer_idurl in contactsdb.customers(): if not customer_idurl: continue if not id_url.is_cached(customer_idurl): continue if customer_idurl == my_id.getLocalID(): lg.warn('skipping my own identity') continue fm = family_member.by_customer_idurl(customer_idurl) if not fm: fm = family_member.create_family(customer_idurl) fm.automat('init') local_customer_meta_info = contactsdb.get_customer_meta_info( customer_idurl) reactor.callLater(0, fm.automat, 'family-join', { # @UndefinedVariable 'supplier_idurl': my_id.getLocalID().to_bin(), 'ecc_map': local_customer_meta_info.get('ecc_map'), 'position': local_customer_meta_info.get('position', -1), 'family_snapshot': id_url.to_bin_list(local_customer_meta_info.get('family_snapshot')), }) events.add_subscriber(self._on_identity_url_changed, 'identity-url-changed') events.add_subscriber(self._on_existing_customer_accepted, 'existing-customer-accepted') events.add_subscriber(self._on_new_customer_accepted, 'new-customer-accepted') events.add_subscriber(self._on_existing_customer_terminated, 'existing-customer-terminated') return True