def __init__(self, uuid, exchange, topics, transition_timeout=pr.REQUEST_TIMEOUT, url=None, transport=None, transport_options=None, retry_options=None, worker_expiry=pr.EXPIRES_AFTER): self._uuid = uuid self._ongoing_requests = {} self._ongoing_requests_lock = threading.RLock() self._transition_timeout = transition_timeout self._proxy = proxy.Proxy(uuid, exchange, on_wait=self._on_wait, url=url, transport=transport, transport_options=transport_options, retry_options=retry_options) # NOTE(harlowja): This is the most simplest finder impl. that # doesn't have external dependencies (outside of what this engine # already requires); it though does create periodic 'polling' traffic # to workers to 'learn' of the tasks they can perform (and requires # pre-existing knowledge of the topics those workers are on to gather # and update this information). self._finder = wt.ProxyWorkerFinder(uuid, self._proxy, topics, worker_expiry=worker_expiry) self._proxy.dispatcher.type_handlers.update({ pr.RESPONSE: dispatcher.Handler(self._process_response, validator=pr.Response.validate), pr.NOTIFY: dispatcher.Handler( self._finder.process_response, validator=functools.partial(pr.Notify.validate, response=True)), }) # Thread that will run the message dispatching (and periodically # call the on_wait callback to do various things) loop... self._helper = None self._messages_processed = { 'finder': self._finder.messages_processed, }
def test_single_topic_worker(self): finder = worker_types.ProxyWorkerFinder('me', mock.MagicMock(), []) w, emit = finder._add('dummy-topic', [utils.DummyTask]) self.assertIsNotNone(w) self.assertTrue(emit) self.assertEqual(1, finder._total_workers()) w2 = finder.get_worker_for_task(utils.DummyTask) self.assertEqual(w.identity, w2.identity)
def test_expiry(self, mock_now): finder = worker_types.ProxyWorkerFinder('me', mock.MagicMock(), [], worker_expiry=60) w, emit = finder._add('dummy-topic', [utils.DummyTask]) w.last_seen = 0 mock_now.side_effect = [120] gone = finder.clean() self.assertEqual(0, finder.total_workers) self.assertEqual(1, gone)
def test_multi_same_topic_workers(self): finder = worker_types.ProxyWorkerFinder('me', mock.MagicMock(), []) w, emit = finder._add('dummy-topic', [utils.DummyTask]) self.assertIsNotNone(w) self.assertTrue(emit) w2, emit = finder._add('dummy-topic-2', [utils.DummyTask]) self.assertIsNotNone(w2) self.assertTrue(emit) w3 = finder.get_worker_for_task( reflection.get_class_name(utils.DummyTask)) self.assertIn(w3.identity, [w.identity, w2.identity])
def test_multi_different_topic_workers(self): finder = worker_types.ProxyWorkerFinder('me', mock.MagicMock(), []) added = [] added.append(finder._add('dummy-topic', [utils.DummyTask])) added.append(finder._add('dummy-topic-2', [utils.DummyTask])) added.append(finder._add('dummy-topic-3', [utils.NastyTask])) self.assertEqual(3, finder._total_workers()) w = finder.get_worker_for_task(utils.NastyTask) self.assertEqual(added[-1][0].identity, w.identity) w = finder.get_worker_for_task(utils.DummyTask) self.assertIn(w.identity, [w_a[0].identity for w_a in added[0:2]])
def __init__(self, uuid, exchange, topics, transition_timeout=pr.REQUEST_TIMEOUT, url=None, transport=None, transport_options=None, retry_options=None): self._uuid = uuid self._requests_cache = wt.RequestsCache() self._transition_timeout = transition_timeout type_handlers = { pr.RESPONSE: dispatcher.Handler(self._process_response, validator=pr.Response.validate), } self._proxy = proxy.Proxy(uuid, exchange, type_handlers=type_handlers, on_wait=self._on_wait, url=url, transport=transport, transport_options=transport_options, retry_options=retry_options) # NOTE(harlowja): This is the most simplest finder impl. that # doesn't have external dependencies (outside of what this engine # already requires); it though does create periodic 'polling' traffic # to workers to 'learn' of the tasks they can perform (and requires # pre-existing knowledge of the topics those workers are on to gather # and update this information). self._finder = wt.ProxyWorkerFinder(uuid, self._proxy, topics) self._finder.notifier.register(wt.WorkerFinder.WORKER_ARRIVED, self._on_worker) self._helpers = tu.ThreadBundle() self._helpers.bind(lambda: tu.daemon_thread(self._proxy.start), after_start=lambda t: self._proxy.wait(), before_join=lambda t: self._proxy.stop()) p_worker = periodics.PeriodicWorker.create([self._finder]) if p_worker: self._helpers.bind(lambda: tu.daemon_thread(p_worker.start), before_join=lambda t: p_worker.stop(), after_join=lambda t: p_worker.reset(), before_start=lambda t: p_worker.reset())