def join_migrations(self, state, migrations_or_ids, host_cmd=None, migration_agent=None): if not migrations_or_ids: raise ValueError( "join_migration() expects a list of migration" "or it's ids to join, got: %r", migrations_or_ids ) migrations = map(self._get_migration, migrations_or_ids) for migration in migrations: if not migration.is_completable(): prob = migration.get_problem() return fiber.fail(prob) if host_cmd is None: host_cmd = self.get_configuration().default_host_cmd resp = Migration(self, host_cmd=host_cmd, migration_agent=migration_agent) recipients = list() for migration in migrations: recipients += list(migration.get_analyzed()) for entry in migration.get_checkin_entries(): resp.checkin(entry) resp.analyze(recipients) [self.forget_migration(x) for x in migrations] f = self.get_shard_structure() f.add_callback(fiber.drop_param, self._topology_fixes, resp) f.add_callback(self._register_migration) return f
def initiate(self, state): desc = state.medium.get_descriptor() for required in ['django_settings_module', 'port']: if not getattr(desc, required): return fiber.fail(error.FeatError( "Cannot start without required parameter: %r" % required)) for key, value in desc.environment.items(): self.info("Setting %s=%r environment variable.", key, value) os.environ[key] = str(value) for element in reversed(desc.python_path): self.info("Injecting %r to the python path.", element) sys.path.insert(0, element) hostname = desc.hostname or state.medium.get_hostname() stats = None if desc.elflog_path: path = desc.elflog_path if not os.path.isabs(path): path = os.path.join(configure.logdir, path) stats = webserver.ELFLog(path, desc.elflog_fields) if desc.p12_path and not os.path.isabs(desc.p12_path): p12_path = os.path.join(configure.confdir, desc.p12_path) else: p12_path = desc.p12_path security_policy = None if p12_path: if not os.path.exists(p12_path): return fiber.fail(error.FeatError( "P12 file was specified, but doesn't exist. Path: %s." % (self.p12_path, ))) fac = security.ServerContextFactory( p12_filename=p12_path, enforce_cert=desc.check_client_cert, verify_ca_from_p12=True) security_policy = security.ServerPolicy(fac) thread_stats_file = None if desc.enable_statistics: thread_stats_file = desc.statistics_db_file if (thread_stats_file != ':memory:' and not os.path.isabs(thread_stats_file)): thread_stats_file = os.path.join(configure.logdir, thread_stats_file) # enable image/png content-type and give it a higher # priority than application/json server = state.medium.agency._gateway._server server.enable_mime_type('image/png', 1) state.server = self.dependency(IServerFactory, self, desc.port, str(desc.django_settings_module), hostname, prefix=desc.prefix, interface=desc.interface, security_policy=security_policy, server_stats=stats, thread_stats_file=thread_stats_file) return fiber.wrap_defer(state.server.initiate)
def _pick_best_bid(self, state, bids): if bids is None or len(bids) == 0: return fiber.fail(EmptyBids( 'Resource allocation will fail as no suitable bids have been ' 'received.')) ret = message.Bid.pick_best(bids)[0] return ret
def establish_partnership(self, state, recp, allocation_id=None, partner_allocation_id=None, partner_role=None, our_role=None, substitute=None, allow_double=False, max_retries=0): f = fiber.succeed() found = state.partners.find(recp) default_role = getattr(self.partners_class, 'default_role', None) our_role = our_role or default_role if not allow_double and found: msg = ('establish_partnership() called for %r which is already ' 'our partner with the class %r.' % (recp, type(found), )) self.debug(msg) if substitute: f.add_callback(fiber.drop_param, state.partners.remove, substitute) f.chain(fiber.fail(partners.DoublePartnership(msg))) return f # f.add_callback(fiber.drop_param, self.initiate_protocol, # requester.Propose, recp, allocation_id, # partner_allocation_id, # our_role, partner_role, substitute) factory = retrying.RetryingProtocolFactory(requester.Propose, max_retries=max_retries) f.add_callback(fiber.drop_param, self.initiate_protocol, factory, recp, allocation_id, partner_allocation_id, our_role, partner_role, substitute) f.add_callback(fiber.call_param, "notify_finish") return f
def handling_death_requested(self, state, agent_id, instance_id): ''' I get called when some other monitoring agent demands me to fix the problem of the dead agent. ''' task = state.handler_tasks.get(agent_id, None) if task: # we already know about this death, just return the IProblem return task else: # we don't yet know about the death or we have already solved it # we need to check the instance_id to know which is the case partner = self.find_partner(agent_id) if not partner: return fiber.fail(partners.FindPartnerError( "I have been requested to solve the death of the agent %r" "which I'm not monitoring. This is weird!" % (agent_id, ))) if partner.instance_id == instance_id: # we didn't know, lets handle it task = self.initiate_protocol(HandleDeath, partner.recipient, state.notification_sender) self._register_task(agent_id, task) return task else: # already solved return AlreadySolvedDeath(self, partner.recipient.key)
def notify_finish(self): if self._failed: return fiber.fail(self._result) elif self._finished: return fiber.succeed(self._result) else: return fiber.wrap_defer(self._notifier.wait, "finished")
def apply_modification(self, state, alloc_change_id): alloc_change = state.modifications.get(alloc_change_id, None) if alloc_change == None or not isinstance(alloc_change, AllocationChange): return fiber.fail(AllocationChangeNotFound("Expired or non-existent modification_id=%s" % alloc_change_id)) self._remove_modification(alloc_change_id) f = fiber.Fiber() f.add_callback(self._modify_allocation_in_descriptor) return f.succeed(alloc_change)
def testUtils(self): def check_callback(param, expected): self.assertEqual(param, expected) return param def check_errback(failure, expected): self.assertTrue(failure.check(expected)) def check_true(value=True): self.assertTrue(value) return value def check_false(value=False): self.assertFalse(value) return value def unexpected(_param): self.fail("Unexpected") deferreds = [] # Test fiber.succeed() f = fiber.succeed(1) f.add_callbacks(check_callback, unexpected, cbargs=(1, )) deferreds.append(f.start()) # Test fiber.fail() f = fiber.fail(ValueError()) f.add_callbacks(unexpected, check_errback, ebargs=(ValueError, )) deferreds.append(f.start()) # Test fiber.drop_param f = fiber.succeed(False) f.add_callback(fiber.drop_param, check_true) deferreds.append(f.start()) # Test fiber.override_result f = fiber.succeed(False) f.add_callback(fiber.override_result, True) f.add_callback(check_true) deferreds.append(f.start()) # Test fiber.bridge_param f = fiber.succeed(False) f.add_callback(fiber.bridge_param, check_true) f.add_callback(check_false) deferreds.append(f.start()) return defer.DeferredList(deferreds)
def got_reply(self, state, reply): if reply.payload['ok']: our_role = state.our_role or reply.payload['default_role'] return state.agent.create_partner( reply.payload['desc'], reply.reply_to, state.allocation_id, our_role, substitute=state.substitute, options=state.options) else: self.info('Received error: %r', reply.payload['fail']) f = self._release_allocation() f.chain(fiber.fail(reply.payload['fail'])) return f
def allocate(self, state, **params): try: self._validate_params(params) scalar = ScalarResource(**params) allocation = Allocation(id=self._next_id(), scalar=scalar) self._validate(state.totals, self._read_allocations().values() + [allocation], state.modifications) except BaseResourceException as e: return fiber.fail(e) f = fiber.Fiber() f.add_callback(self._append_allocation_to_descriptor) return f.succeed(allocation)
def _start_monitoring(self, state, monitors): if not monitors: ex = MonitoringFailed( "No monitor agent found in shard for %s %s" % (state.agent.descriptor_type, state.agent.get_full_id()) ) return fiber.fail(ex) monitor = monitors[0] self.info("Monitor found for %s %s: %s", state.agent.descriptor_type, state.agent.get_full_id(), monitor.key) f = state.agent.establish_partnership(monitor) f.add_errback(failure.Failure.trap, partners.DoublePartnership) return f
def get_allocation(self, allocation_id): """ Check that confirmed allocation with given id exists. Raise exception otherwise. """ try: allocation = self._read_allocations().get(allocation_id, None) if allocation is None: raise AllocationNotFound("Allocation with id=%s not found" % allocation_id) return fiber.succeed(allocation) except AllocationNotFound as e: return fiber.fail(e)
def confirm(self, state, allocation_id): """ confirms a preallocation """ allocation = state.modifications.get(allocation_id, None) if allocation == None or not isinstance(allocation, Allocation): return fiber.fail(AllocationNotFound("Expired or non-existent allocation_id=%s" % allocation_id)) self._remove_modification(allocation_id) f = fiber.Fiber() f.add_callback(self._append_allocation_to_descriptor) return f.succeed(allocation)
def start_agent_in_shard(agent, desc, shard, **kwargs): if shard is None or shard == 'lobby': return fiber.fail(ValueError( 'We cannot start agent in shard without passing a meaningful ' 'value for the shard. (%r)' % shard)) f = agent.discover_service(StartAgentManager, shard=shard, timeout=1) f.add_callback(_check_recp_not_empty, shard) f.add_callback(lambda recp: agent.initiate_protocol(StartAgentManager, recp, desc, kwargs)) f.add_callback(StartAgentManager.notify_finish) return f
def receive_notification(self, state, recp, notification_type, blackbox, sender): partner = self.find(recp) if partner is None: self.warning("Didn't find a partner matching the notification " "%r origin :%r!", notification_type, recp) return None handler_method = '_on_%s' % (notification_type, ) handler = getattr(self, handler_method, None) if not callable(handler): return fiber.fail( ValueError('No handler found for notification %r!' %\ (notification_type, ))) return handler(partner, blackbox, sender)
def substitute_partner(self, state, partners_recp, recp, alloc_id): """ Establish the partnership to recp and, when it is successfull remove partner with recipient partners_recp. Use with caution: The partner which we are removing is not notified in any way, so he still keeps link in his description. The correct usage of this method requires calling it from two agents which are divorcing. """ partner = state.partners.find(recipient.IRecipient(partners_recp)) if not partner: msg = "subsitute_partner() did not find the partner %r" % partners_recp self.error(msg) return fiber.fail(partners.FindPartnerError(msg)) return self.establish_partnership(recp, partner.allocation_id, alloc_id, substitute=partner)
def commit(self): try: self._data['args'] = self._serializer.convert( self._not_serialized['args']) self._data['kwargs'] = self._serializer.convert( self._not_serialized['kwargs']) self._data['result'] = self._serializer.freeze( self._not_serialized['result']) self._data['side_effects'] = self._serializer.convert( self._data['side_effects']) self._record.commit(**self._data) self._record = None return self except TypeError as e: self.set_result(fiber.fail(e)) self._not_serialized['args'] = None self._not_serialized['kwargs'] = None self.commit()
def initiate(self, agent): return fiber.fail(FailureOfPartner('test'))
def _fail(self, msg): self.error(msg) return fiber.fail(StartPartnerException(msg))
def _recorded_call(self, fun_id, function, args, kwargs, reentrant=True): # Starts the fiber section section = fiber.WovenSection() section.enter() fibdesc = section.descriptor # Check if we are in replay mode mode = section.state.get(RECMODE_TAG, None) if mode == JournalMode.replay: fun_id, function = self._resolve_function(fun_id, function) return self._call_fun(fun_id, function, args, kwargs) # Check if this is the first recording in the fiber section recording = section.state.get(RECORDING_TAG, None) section_first = recording is None result = None try: entry = section.state.get(JOURNAL_ENTRY_TAG, None) mode = section.state.get(RECMODE_TAG, None) fiber_first = section_first and section.descriptor.fiber_depth == 0 fun_id, function = self._resolve_function(fun_id, function) if section_first: entry = self.journal_keeper.new_entry(self.journal_id, fun_id, *args, **kwargs) entry.set_fiber_context(fibdesc.fiber_id, fibdesc.fiber_depth) section.state[RECORDING_TAG] = True section.state[RECMODE_TAG] = JournalMode.recording section.state[JOURNAL_ENTRY_TAG] = entry if not (fiber_first or reentrant): # If not reentrant and it is not the first, it's BAAAAAD. raise ReentrantCallError( "Recorded functions %s cannot be " "called from inside the recording " "section" % (fun_id,) ) result = self._call_fun(fun_id, function, args, kwargs) except failure.Failure as f: # When trapping a failure it raised itself if not section_first: raise result = fiber.fail(f.value) error.handle_failure(self, f, "Failure inside recorded " "function %s", fun_id) except Exception as e: if not section_first: raise result = fiber.fail(e) error.handle_exception(self, e, "Exception inside recorded " "function %s", fun_id) finally: if section_first: entry.set_result(result) entry.commit() result = entry.get_result() section.state[RECORDING_TAG] = None section.state[JOURNAL_ENTRY_TAG] = None section.state[RECMODE_TAG] = None return section.exit(result)
def fiber_fail(self, state, failure): return fiber.fail(failure, canceller=state.medium.get_canceller(), debug_depth=2)
def type_error_2(self): try: 1 + "" except: return fiber.fail()
def _check_recp_not_empty(recp, shard): if len(recp) == 0: return fiber.fail( NoHostFound('No hosts found in the shard %s' % (shard, ))) return recp
def got_reply(self, state, reply): assert isinstance(reply.payload, BaseResponse), reply.payload if reply.payload.success: return reply.payload else: return fiber.fail(reply.payload.failure)
def initiate(self, state): desc = state.medium.get_descriptor() for required in ['django_settings_module', 'port']: if not getattr(desc, required): return fiber.fail( error.FeatError( "Cannot start without required parameter: %r" % required)) for key, value in desc.environment.items(): self.info("Setting %s=%r environment variable.", key, value) os.environ[key] = str(value) for element in reversed(desc.python_path): self.info("Injecting %r to the python path.", element) sys.path.insert(0, element) hostname = desc.hostname or state.medium.get_hostname() stats = None if desc.elflog_path: path = desc.elflog_path if not os.path.isabs(path): path = os.path.join(configure.logdir, path) stats = webserver.ELFLog(path, desc.elflog_fields) if desc.p12_path and not os.path.isabs(desc.p12_path): p12_path = os.path.join(configure.confdir, desc.p12_path) else: p12_path = desc.p12_path security_policy = None if p12_path: if not os.path.exists(p12_path): return fiber.fail( error.FeatError( "P12 file was specified, but doesn't exist. Path: %s." % (self.p12_path, ))) fac = security.ServerContextFactory( p12_filename=p12_path, enforce_cert=desc.check_client_cert, verify_ca_from_p12=True) security_policy = security.ServerPolicy(fac) thread_stats_file = None if desc.enable_statistics: thread_stats_file = desc.statistics_db_file if (thread_stats_file != ':memory:' and not os.path.isabs(thread_stats_file)): thread_stats_file = os.path.join(configure.logdir, thread_stats_file) # enable image/png content-type and give it a higher # priority than application/json server = state.medium.agency._gateway._server server.enable_mime_type('image/png', 1) state.server = self.dependency(IServerFactory, self, desc.port, str(desc.django_settings_module), hostname, prefix=desc.prefix, interface=desc.interface, security_policy=security_policy, server_stats=stats, thread_stats_file=thread_stats_file) return fiber.wrap_defer(state.server.initiate)
def _replayed_call(self, fun_id, function, args, kwargs): try: return self._call_fun(fun_id, function, args, kwargs) except Exception as e: return fiber.fail(e)
def get_document(self, doc_id): if doc_id in self.docs: return fiber.succeed(self.docs[doc_id]) else: return fiber.fail(NotFoundError())
def allocate_ports(self, state, number): try: return state.port_allocator.reserve_ports(number) except port_allocator.PortAllocationError as e: return fiber.fail(e)