コード例 #1
0
ファイル: test_messaging.py プロジェクト: pombredanne/nameko
def test_consume_from_rabbit(rabbit_manager, rabbit_config):

    vhost = rabbit_config['vhost']

    container = Mock(spec=ServiceContainer)
    container.worker_ctx_cls = CustomWorkerContext
    container.service_name = "service"
    container.config = rabbit_config
    container.max_workers = 10

    def spawn_thread(method, protected):
        return eventlet.spawn(method)

    container.spawn_managed_thread = spawn_thread

    worker_ctx = CustomWorkerContext(container, None, None)

    factory = DependencyFactory(
        ConsumeProvider, queue=foobar_queue, requeue_on_error=False)
    consumer = factory.create_and_bind_instance("injection_name", container)

    # prepare and start dependencies
    consumer.prepare()
    consumer.queue_consumer.prepare()
    consumer.start()
    consumer.queue_consumer.start()

    # test queue, exchange and binding created in rabbit
    exchanges = rabbit_manager.get_exchanges(vhost)
    queues = rabbit_manager.get_queues(vhost)
    bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name)

    assert "foobar_ex" in [exchange['name'] for exchange in exchanges]
    assert "foobar_queue" in [queue['name'] for queue in queues]
    assert "foobar_ex" in [binding['source'] for binding in bindings]

    # test message consumed from queue
    container.spawn_worker.return_value = worker_ctx

    headers = {'nameko.language': 'en', 'nameko.customheader': 'customvalue'}
    rabbit_manager.publish(
        vhost, foobar_ex.name, '', 'msg', properties=dict(headers=headers))

    ctx_data = {
        'language': 'en',
        'customheader': 'customvalue',
    }
    with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method:
        method.assert_called_once_with(
            consumer, ('msg', ), {},
            context_data=ctx_data,
            handle_result=ANY_PARTIAL)
        handle_result = method.call_args[1]['handle_result']

    # ack message
    handle_result(worker_ctx, 'result')

    # stop will hang if the consumer hasn't acked or requeued messages
    with eventlet.timeout.Timeout(CONSUME_TIMEOUT):
        consumer.stop()
コード例 #2
0
def test_nested_dependencies(rabbit_config):

    container = Mock()
    container.config = rabbit_config

    bar_factory = DependencyFactory(BarProvider)
    bar = bar_factory.create_and_bind_instance("bar", container)

    dependencies = list(bar.nested_dependencies)
    assert len(dependencies) == 2
    assert dependencies[0].container == dependencies[1].container == container
    assert set([type(dep) for dep in dependencies]) == set([SharedProvider, NestedProvider])
コード例 #3
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
def test_nested_dependencies(rabbit_config):

    container = Mock()
    container.config = rabbit_config

    bar_factory = DependencyFactory(BarProvider)
    bar = bar_factory.create_and_bind_instance("bar", container)

    dependencies = list(bar.nested_dependencies)
    assert len(dependencies) == 2
    assert dependencies[0].container == dependencies[1].container == container
    assert set([type(dep) for dep in dependencies]) == set([SharedProvider,
                                                           NestedProvider])
コード例 #4
0
def consume(queue, requeue_on_error=False):
    """
    Decorates a method as a message consumer.

    Messages from the queue will be deserialized depending on their content
    type and passed to the the decorated method.
    When the consumer method returns without raising any exceptions,
    the message will automatically be acknowledged.
    If any exceptions are raised during the consumption and
    `requeue_on_error` is True, the message will be requeued.

    Example::

        @consume(...)
        def handle_message(self, body):

            if not self.spam(body):
                raise Exception('message will be requeued')

            self.shrub(body)

    Args:
        queue: The queue to consume from.
    """
    return DependencyFactory(ConsumeProvider, queue, requeue_on_error)
コード例 #5
0
ファイル: rpc.py プロジェクト: jason790/nameko
def rpc(expected_exceptions=()):
    """ Mark a method to be exposed over rpc

    :Parameters:
        expected_exceptions : exception class or tuple of exception classes
            Stashed on the provider instance for later inspection by other
            dependencies in the worker lifecycle. Use for exceptions caused
            by the caller (e.g. bad arguments).
    """
    return DependencyFactory(RpcProvider, expected_exceptions)
コード例 #6
0
def file_logger(path=None):
    """ User docs for file logger
    """
    if path is not None:
        check_path = path
        if not os.path.exists(check_path):
            check_path = os.path.dirname(path)
        if not os.access(check_path, os.W_OK):
            raise InvalidPath("File or dir not writable: {}".format(path))

    return DependencyFactory(LogFile, path)
コード例 #7
0
ファイル: timer.py プロジェクト: topiaruss/nameko
def timer(interval=None, config_key=None):
    '''
    Decorates a method as a timer, which will be called every `interval` sec.

    Either the `interval` or the `config_key` have to be provided or both.
    If the `config_key` is given the value for that key in the config will be
    used as the interval otherwise the `interval` provided will be used.

    Example::

        class Foobar(object):

            @timer(interval=5, config_key='foobar_interval')
            def handle_timer(self):
                self.shrub(body)
    '''
    return DependencyFactory(TimerProvider, interval, config_key)
コード例 #8
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
 def injection_provider():
     return DependencyFactory(ExampleProvider)
コード例 #9
0
def shopping_basket():
    """ A shopping basket tied to the current user.
    """
    return DependencyFactory(ShoppingBasket)
コード例 #10
0
ファイル: test_contextdata.py プロジェクト: jason790/nameko
def custom_value():
    return DependencyFactory(ContextDataProvider, CUSTOM_CONTEXT_KEY)
コード例 #11
0
ファイル: stdout.py プロジェクト: topiaruss/nameko-chat
def stdout():
    return DependencyFactory(StdoutProvider)
コード例 #12
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
def foobar(*args, **kwargs):
    """foobar-doc"""
    return DependencyFactory(FooProvider, *args, **kwargs)
コード例 #13
0
def foobar():
    return DependencyFactory(CallCollectingEntrypointProvider)
コード例 #14
0
ファイル: contextdata.py プロジェクト: jason790/nameko
def auth_token():
    return DependencyFactory(ContextDataProvider, AUTH_TOKEN_CONTEXT_KEY)
コード例 #15
0
def context_reader():
    return DependencyFactory(ContextReader)
コード例 #16
0
ファイル: contextdata.py プロジェクト: jason790/nameko
def user_id():
    return DependencyFactory(ContextDataProvider, USER_ID_CONTEXT_KEY)
コード例 #17
0
ファイル: contextdata.py プロジェクト: jason790/nameko
def user_agent():
    return DependencyFactory(ContextDataProvider, USER_AGENT_CONTEXT_KEY)
コード例 #18
0
ファイル: contextdata.py プロジェクト: jason790/nameko
def language():
    return DependencyFactory(ContextDataProvider, LANGUAGE_CONTEXT_KEY)
コード例 #19
0
ファイル: dependencies.py プロジェクト: topiaruss/nameko
def rpc():
    return DependencyFactory(NovaRpcProvider)
コード例 #20
0
ファイル: dependencies.py プロジェクト: topiaruss/nameko
def nova_rpc_consumer():
    return DependencyFactory(NovaRpcConsumer)
コード例 #21
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
def shared_provider(*args, **kwargs):
    return DependencyFactory(SharedProvider, *args, **kwargs)
コード例 #22
0
ファイル: test_rpc.py プロジェクト: jason790/nameko
def translator():
    return DependencyFactory(Translator)
コード例 #23
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
def nested_provider(*args, **kwargs):
    return DependencyFactory(NestedProvider, *args, **kwargs)
コード例 #24
0
def test_consume_from_rabbit(rabbit_manager, rabbit_config):

    vhost = rabbit_config['vhost']

    container = Mock(spec=ServiceContainer)
    container.worker_ctx_cls = CustomWorkerContext
    container.service_name = "service"
    container.config = rabbit_config
    container.max_workers = 10

    def spawn_thread(method, protected):
        return eventlet.spawn(method)

    container.spawn_managed_thread = spawn_thread

    worker_ctx = CustomWorkerContext(container, None, DummyProvider())

    factory = DependencyFactory(ConsumeProvider,
                                queue=foobar_queue,
                                requeue_on_error=False)
    consumer = factory.create_and_bind_instance("injection_name", container)

    # prepare and start dependencies
    consumer.prepare()
    consumer.queue_consumer.prepare()
    consumer.start()
    consumer.queue_consumer.start()

    # test queue, exchange and binding created in rabbit
    exchanges = rabbit_manager.get_exchanges(vhost)
    queues = rabbit_manager.get_queues(vhost)
    bindings = rabbit_manager.get_queue_bindings(vhost, foobar_queue.name)

    assert "foobar_ex" in [exchange['name'] for exchange in exchanges]
    assert "foobar_queue" in [queue['name'] for queue in queues]
    assert "foobar_ex" in [binding['source'] for binding in bindings]

    # test message consumed from queue
    container.spawn_worker.return_value = worker_ctx

    headers = {'nameko.language': 'en', 'nameko.customheader': 'customvalue'}
    rabbit_manager.publish(vhost,
                           foobar_ex.name,
                           '',
                           'msg',
                           properties=dict(headers=headers))

    ctx_data = {
        'language': 'en',
        'customheader': 'customvalue',
    }
    with wait_for_call(CONSUME_TIMEOUT, container.spawn_worker) as method:
        method.assert_called_once_with(consumer, ('msg', ), {},
                                       context_data=ctx_data,
                                       handle_result=ANY_PARTIAL)
        handle_result = method.call_args[1]['handle_result']

    # ack message
    handle_result(worker_ctx, 'result')

    # stop will hang if the consumer hasn't acked or requeued messages
    with eventlet.timeout.Timeout(CONSUME_TIMEOUT):
        consumer.stop()

    consumer.queue_consumer.kill()
コード例 #25
0
ファイル: test_dependencies.py プロジェクト: topiaruss/nameko
def barfoo(*args, **kwargs):
    return DependencyFactory(BarProvider, *args, **kwargs)
コード例 #26
0
def event_dispatcher():
    return DependencyFactory(EventDispatcher)
コード例 #27
0
def call_collector():
    return DependencyFactory(CallCollectingInjectionProvider)
コード例 #28
0
def event_handler(service_name, event_type, handler_type=SERVICE_POOL,
                  reliable_delivery=True, requeue_on_error=False,
                  event_handler_cls=EventHandler):
    r"""
    Decorate a method as a handler of ``event_type`` events on the service
    called ``service_name``. ``event_type`` must be either a subclass of
    :class:`~.Event` with a class attribute ``type`` or a string matching the
    value of this attribute.
    ``handler_type`` determines the behaviour of the handler:

        - ``events.SERVICE_POOL``:

            Event handlers will be pooled by service type and handler-method
            and one from each pool will receive the event. ::

                           .-[queue]- (service X handler-method-1)
                          /
                exchange o --[queue]- (service X handler-method-2)
                          \
                           \          (service Y(instance 1) hanlder-method)
                            \       /
                             [queue]
                                    \
                                      (service Y(instance 2) handler-method)


        - ``events.SINGLETON``:

            Events will be received by only one registered handler.
            If requeued on error, they may be given to a different
            handler. ::

                                       (service X handler-method)
                                     /
                exchange o -- [queue]
                                     \
                                       (service Y handler-method)

        - ``events.BROADCAST``:
            Events will be received by every handler. This  will broadcast
            to every service instance, not just every service type
            - use wisely! ::

                            [queue]- (service X(instance 1) handler-method)
                          /
                exchange o - [queue]- (service X(instance 2) handler-method)
                          \
                            [queue]- (service Y handler-method)

    If ``requeue_on_error``, handlers will return the event to the queue if an
    error occurs while handling it. Defaults to False.

    If ``reliable_delivery``, events will be kept in the queue until there is
    a handler to consume them. Defaults to ``True``.

    ``event_handler_cls`` may be specified to use a different EventHandler
        (sub)class for custom behaviour.

    Raises an ``EventHandlerConfigurationError`` if the ``handler_type``
    is set to ``BROADCAST`` and ``reliable_delivery`` is set to ``True``.
    """

    if reliable_delivery and handler_type is BROADCAST:
        raise EventHandlerConfigurationError(
            "Broadcast event handlers cannot be configured with reliable "
            "delivery.")

    if isinstance(event_type, type) and issubclass(event_type, Event):
        event_type = event_type.type
    elif not isinstance(event_type, basestring):
        raise TypeError(
            'event_type must be either a nameko.events.Event subclass or a '
            'string a string matching the Event.type value. '
            'Got {}'.format(type(event_type).__name__))

    return DependencyFactory(event_handler_cls, service_name, event_type,
                             handler_type, reliable_delivery, requeue_on_error)
コード例 #29
0
ファイル: services.py プロジェクト: jason790/nameko
def dummy():
    return DependencyFactory(DummyEntrypoint)
コード例 #30
0
def once(*args, **kwargs):
    """ Fire the decorated entrypoint once, immediately.
    """
    return DependencyFactory(OnceProvider, args, kwargs)
コード例 #31
0
ファイル: test_rpc.py プロジェクト: jason790/nameko
def worker_logger():
    return DependencyFactory(WorkerErrorLogger)
コード例 #32
0
def stdin():
    """ Receive messages from `sys.stdin`
    """
    return DependencyFactory(StdinProvider)