def test_main_io_loop_is_not_changed(): threadloop = ThreadLoop() threadloop.start() # The ThreadLoop's IOLoop should not be the 'current' IOLoop in the main # thread. tl_loop = threadloop.submit(ioloop.IOLoop.current).result() assert ioloop.IOLoop.current() is not tl_loop
def _create_new_thread_loop(self): """ Create a daemonized thread that will run Tornado IOLoop. :return: the IOLoop backed by the new thread. """ self._thread_loop = ThreadLoop() if not self._thread_loop.is_ready(): self._thread_loop.start() return self._thread_loop._io_loop
def test_start_must_be_called_before_submit(): threadloop = ThreadLoop() @gen.coroutine def coroutine(): raise gen.Return("Hello World") with pytest.raises(ThreadNotStartedError): threadloop.submit(coroutine)
def test_ioloop_is_not_already_running(): threadloop = ThreadLoop() threadloop.start() @gen.coroutine def f(): yield threadloop.submit(gen.sleep, 0.1) ioloop.IOLoop.current().run_sync(f)
def test_block_until_thread_is_ready(): threadloop = ThreadLoop() assert not threadloop.is_ready() threadloop.start() assert threadloop.is_ready()
class TChannelSyncClient(object): """Make synchronous TChannel requests. This client does not support incoming connections or requests- this is a uni-directional client only. The client is implemented on top of the Tornado-based implementation and starts and stops IOLoops on-demand. .. code-block:: python client = TChannelSyncClient() response = client.request( hostport='localhost:4040', service='HelloService', ).send( 'hello', None, json.dumps({"name": "World"}) ) """ def __init__(self, name, process_name=None, known_peers=None, trace=False): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ self.async_client = async.TChannel( name, hostport=glossary.EPHEMERAL_HOSTPORT, process_name=process_name, known_peers=known_peers, trace=trace ) self.threadloop = ThreadLoop() self.threadloop.start() def request(self, *args, **kwargs): """Initiate a new request to a peer. :param hostport: If specified, requests will be sent to the specific host. Otherwise, a known peer will be picked at random. :param service: Name of the service being called. Defaults to an empty string. :param service_threshold: If ``hostport`` was not specified, this specifies the score threshold at or below which peers will be ignored. :returns SyncClientOperation: An object with a ``send(arg1, arg2, arg3)`` operation. """ operation = self.async_client.request(*args, **kwargs) operation = SyncClientOperation(operation, self.threadloop) return operation
class LocalAgentSender(TBufferedTransport): """ LocalAgentSender implements everything necessary to communicate with local jaeger-agent. This class is designed to work in tornado and non-tornado environments. If in torndado, pass in the ioloop, if not then LocalAgentSender will create one for itself. NOTE: LocalAgentSender derives from TBufferedTransport. This will buffer up all written data until flush() is called. Flush gets called at the end of the batch span submission call. """ def __init__(self, host, sampling_port, reporting_port, io_loop=None, throttling_port=None): # IOLoop self._thread_loop = None self.io_loop = io_loop or self._create_new_thread_loop() # HTTP sampling self.local_agent_http = LocalAgentHTTP(host, sampling_port) # HTTP throttling if throttling_port: self.throttling_http = LocalAgentHTTP(host, throttling_port) # UDP reporting - this will only get written to after our flush() call. # We are buffering things up because we are a TBufferedTransport. udp = TUDPTransport(host, reporting_port) TBufferedTransport.__init__(self, udp) def _create_new_thread_loop(self): """ Create a daemonized thread that will run Tornado IOLoop. :return: the IOLoop backed by the new thread. """ self._thread_loop = ThreadLoop() if not self._thread_loop.is_ready(): self._thread_loop.start() return self._thread_loop._io_loop def readFrame(self): """Empty read frame that is never ready""" return Future() # Pass-through for HTTP sampling strategies request. def request_sampling_strategy(self, *args, **kwargs): return self.local_agent_http.request_sampling_strategy(*args, **kwargs) # Pass-through for HTTP throttling credit request. def request_throttling_credits(self, *args, **kwargs): return self.throttling_http.request_throttling_credits(*args, **kwargs)
def __init__(self, name, process_name=None, known_peers=None, trace=False): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ self._async_client = async .TChannel(name, process_name=process_name, known_peers=known_peers, trace=trace) self._threadloop = ThreadLoop() self._threadloop.start()
def test_use_existing_ioloop(): io_loop = ioloop.IOLoop.current() threadloop = ThreadLoop(io_loop) assert threadloop._io_loop is io_loop @gen.coroutine def coroutine(): raise gen.Return("Hello World") with threadloop: future = threadloop.submit(coroutine) assert future.result() == "Hello World"
def __init__(self, q, l): def callback(): q.wait_notempty(0.1) while True: try: val = q.get(False) l.append(val) except Empty: break ThreadLoop.__init__(self, callback)
def __init__( self, name, hostport=None, process_name=None, known_peers=None, trace=False, threadloop=None, ): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ super(TChannel, self).__init__( name, hostport=hostport, process_name=process_name, known_peers=known_peers, trace=trace, ) self._threadloop = threadloop or ThreadLoop() self.advertise = self._wrap(self.advertise) self.raw = _SyncScheme(self.raw, self._threadloop) self.thrift = _SyncScheme(self.thrift, self._threadloop) self.json = _SyncScheme(self.json, self._threadloop)
def __init__(self, name, process_name=None, known_peers=None, trace=False): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ self._async_client = async.TChannel(name, process_name=process_name, known_peers=known_peers, trace=trace) self._threadloop = ThreadLoop() self._threadloop.start()
class Sender(object): def __init__(self, host, port, io_loop=None): self.host = host self.port = port self.io_loop = io_loop or self._create_new_thread_loop() def send(self, batch): raise NotImplementedError( 'This method should be implemented by subclasses') def _create_new_thread_loop(self): """ Create a daemonized thread that will run Tornado IOLoop. :return: the IOLoop backed by the new thread. """ self._thread_loop = ThreadLoop() if not self._thread_loop.is_ready(): self._thread_loop.start() return self._thread_loop._io_loop
class LocalAgentSender(TBufferedTransport): """ LocalAgentSender implements a everything necessary to communicate with local jaeger-agent. This class is designed to work in tornado and non-tornado environments. If in torndado, pass in the ioloop, if not then LocalAgentSender will create one for itself. NOTE: LocalAgentSender derives from TBufferedTransport. This will buffer up all written data until flush() is called. Flush gets called at the end of the batch span submission call. """ def __init__(self, host, sampling_port, reporting_port, ioloop=None): # ioloop if ioloop is None: self.create_new_threadloop() else: self.io_loop = ioloop # http sampling self.local_agent_http = LocalAgentHTTP(host, sampling_port) # udp reporting - this will only get written to after our flush() call. # We are buffering things up because we are a TBufferedTransport. udp = TUDPTransport(host, reporting_port) TBufferedTransport.__init__(self, udp) def create_new_threadloop(self): self._threadloop = ThreadLoop() if not self._threadloop.is_ready(): self._threadloop.start() self.io_loop = ioloop_util.get_io_loop(self) def readFrame(self): """Empty read frame that is never ready""" return Future() # Passthroughs for the http def request_sampling_strategy(self, service_name, timeout): return self.local_agent_http.request_sampling_strategy(service_name, timeout)
class TChannelSyncClient(object): """Make synchronous TChannel requests. This client does not support incoming connections or requests- this is a uni-directional client only. The client is implemented on top of the Tornado-based implementation and starts and stops IOLoops on-demand. .. code-block:: python client = TChannelSyncClient() response = client.request( hostport='localhost:4040', service='HelloService', ).send( 'hello', None, json.dumps({"name": "World"}) ) """ def __init__(self, name, process_name=None, known_peers=None, trace=False): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ self._async_client = async .TChannel(name, process_name=process_name, known_peers=known_peers, trace=trace) self._threadloop = ThreadLoop() self._threadloop.start() def request(self, *args, **kwargs): """Initiate a new request to a peer. :param hostport: If specified, requests will be sent to the specific host. Otherwise, a known peer will be picked at random. :param service: Name of the service being called. Defaults to an empty string. :param service_threshold: If ``hostport`` was not specified, this specifies the score threshold at or below which peers will be ignored. :returns SyncClientOperation: An object with a ``send(arg1, arg2, arg3)`` operation. """ operation = self._async_client.request(*args, **kwargs) operation = SyncClientOperation(operation, self._threadloop) return operation def advertise(self, routers, name=None, timeout=None): """Advertise with Hyperbahn. :param routers: list of hyperbahn addresses to advertise to. :param name: service name to advertise with. :param timeout: backoff period for failed requests. :returns: first advertise result. :raises AdvertiseError: when unable to begin advertising. """ @gen.coroutine def make_request(): response = yield self._async_client.advertise( routers=routers, name=name, timeout=timeout, ) header = yield response.get_header() body = yield response.get_body() result = Response(header, body) raise gen.Return(result) future = self._threadloop.submit(make_request) # we're going to wait 1s longer than advertises # timeout mechanism, so it has a chance to timeout wait_until = timeout or FIRST_ADVERTISE_TIME wait_until += 1 # block for advertise's first response, # using wait_until as a fallback timeout mechanism try: result = future.result(wait_until) except TimeoutError: raise AdvertiseError("Failed to register with Hyperbahn.") return result
def create_new_threadloop(self): self._threadloop = ThreadLoop() if not self._threadloop.is_ready(): self._threadloop.start() self.io_loop = ioloop_util.get_io_loop(self)
def threadloop(): with ThreadLoop() as threadloop: yield threadloop
def test_is_not_ready_when_ready_hasnt_been_sent(): threadloop = ThreadLoop() threadloop._thread = True # fake the Thread being set assert not threadloop.is_ready()
class TChannelSyncClient(object): """Make synchronous TChannel requests. This client does not support incoming connections or requests- this is a uni-directional client only. The client is implemented on top of the Tornado-based implementation and starts and stops IOLoops on-demand. .. code-block:: python client = TChannelSyncClient() response = client.request( hostport='localhost:4040', service='HelloService', ).send( 'hello', None, json.dumps({"name": "World"}) ) """ def __init__(self, name, process_name=None, known_peers=None, trace=False): """Initialize a new TChannelClient. :param process_name: Name of the calling process. Used for logging purposes only. """ self._async_client = async.TChannel(name, process_name=process_name, known_peers=known_peers, trace=trace) self._threadloop = ThreadLoop() self._threadloop.start() def request(self, *args, **kwargs): """Initiate a new request to a peer. :param hostport: If specified, requests will be sent to the specific host. Otherwise, a known peer will be picked at random. :param service: Name of the service being called. Defaults to an empty string. :param service_threshold: If ``hostport`` was not specified, this specifies the score threshold at or below which peers will be ignored. :returns SyncClientOperation: An object with a ``send(arg1, arg2, arg3)`` operation. """ operation = self._async_client.request(*args, **kwargs) operation = SyncClientOperation(operation, self._threadloop) return operation def advertise(self, routers, name=None, timeout=None): """Advertise with Hyperbahn. :param routers: list of hyperbahn addresses to advertise to. :param name: service name to advertise with. :param timeout: backoff period for failed requests. :returns: first advertise result. :raises AdvertiseError: when unable to begin advertising. """ @gen.coroutine def make_request(): response = yield self._async_client.advertise(routers=routers, name=name, timeout=timeout) header = yield response.get_header() body = yield response.get_body() result = Response(header, body) raise gen.Return(result) future = self._threadloop.submit(make_request) # we're going to wait 1s longer than advertises # timeout mechanism, so it has a chance to timeout wait_until = timeout or FIRST_ADVERTISE_TIME wait_until += 1 # block for advertise's first response, # using wait_until as a fallback timeout mechanism try: result = future.result(wait_until) except TimeoutError: raise AdvertiseError("Failed to register with Hyperbahn.") return result