Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
def test_block_until_thread_is_ready():

    threadloop = ThreadLoop()

    assert not threadloop.is_ready()

    threadloop.start()

    assert threadloop.is_ready()
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
    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()
Ejemplo n.º 12
0
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)
Ejemplo n.º 14
0
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"
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    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()
Ejemplo n.º 17
0
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)
Ejemplo n.º 19
0
def test_block_until_thread_is_ready():

    threadloop = ThreadLoop()

    assert not threadloop.is_ready()

    threadloop.start()

    assert threadloop.is_ready()
Ejemplo n.º 20
0
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)
Ejemplo n.º 22
0
def threadloop():
    with ThreadLoop() as threadloop:
        yield threadloop
Ejemplo n.º 23
0
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()
Ejemplo n.º 24
0
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()
Ejemplo n.º 25
0
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