예제 #1
0
async def main():
    context = RootContext()
    props = Props.from_func(hello_function)
    pid = context.spawn(props)

    reply = await context.request_async(pid, HelloMessage('Hello'))
    print(reply)
예제 #2
0
async def test_reenter_after_can_do_action_for_task():
    queue = Queue()

    async def actor(ctx):
        if ctx.message == 'hello1':

            async def target():
                await asyncio.sleep(0.1)
                queue.put('bar')
                return 'hey1'

            async def action(result):
                queue.put('baz')
                await ctx.respond(result)

            ctx.reenter_after(target, action)
        elif ctx.message == 'hello2':
            queue.put('foo')
            await ctx.respond('hey2')

    props = Props.from_func(actor)
    pid = context.spawn(props)

    task1 = asyncio.ensure_future(context.request_async(pid, "hello1"))
    task2 = asyncio.ensure_future(context.request_async(pid, "hello2"))

    reply1 = await task1
    reply2 = await task2

    assert reply1 == 'hey1'
    assert reply2 == 'hey2'

    assert 'foo' == queue.get()
    assert 'bar' == queue.get()
    assert 'baz' == queue.get()
async def test_can_use_separate_stores():
    threading_events = {
        'process_started': threading.Event(),
        'process_get_state': threading.Event(),
        'process_get_index': threading.Event(),
        'process_request_snapshot': threading.Event(),
        'process_multiply': threading.Event()
    }

    actor_id = str(uuid.uuid4())
    event_store = InMemoryProvider()
    snapshot_store = InMemoryProvider()
    props = Props.from_producer(lambda: ExamplePersistentActor(
        threading_events, event_store, snapshot_store, actor_id)).with_mailbox(
            MockMailbox)
    pid = root_context.spawn(props)

    await root_context.send(pid, Multiply(2))
    threading_events['process_multiply'].wait()
    threading_events['process_multiply'].clear()

    event_store_messages = []
    await event_store.get_events(actor_id, 0, 1,
                                 lambda msg: event_store_messages.append(msg))
    assert len(event_store_messages) == 1

    snapshot_store_messages = []
    await snapshot_store.get_events(
        actor_id, 0, 1, lambda msg: snapshot_store_messages.append(msg))
    assert len(snapshot_store_messages) == 0
예제 #4
0
    async def setup(self) -> None:
        props = Props.from_producer(lambda: PidCacheWatcher()) \
            .with_guardian_supervisor_strategy(Supervision.always_restart_strategy)

        self._watcher = GlobalRootContext.spawn_named(props, 'PidCacheWatcher')
        self._cluster_topology_evn_sub = GlobalEventStream.subscribe(
            self.process_member_status_event, type(AbstractMemberStatusEvent))
예제 #5
0
async def main():
    context = RootContext()
    props = Props.from_producer(HelloActor)
    pid = context.spawn(props)

    await context.send(pid, HelloMessage('Hello World!'))
    input()
예제 #6
0
 async def __process_start_loop_actor_message(self, context, message):
     if self._timer_started:
         return
     self._timer_started = True
     print('MyPersistenceActor - StartLoopActor')
     props = Props.from_producer(lambda: LoopActor())
     self._loop_actor = context.spawn(props)
예제 #7
0
async def main():
    tracer = init_jaeger_tracer()
    opentracing.set_global_tracer(tracer)

    context = RootContext()

    Serialization().register_file_descriptor(DESCRIPTOR)
    Remote().start("127.0.0.1", 8000)
    clients = []

    async def process_message(ctx: AbstractContext):
        msg = ctx.message
        if isinstance(msg, Connect):
            print(f'Client {msg.sender} connected')
            clients.append(msg.sender)
            await ctx.send(msg.sender, Connected(message='Welcome!'))
        elif isinstance(msg, SayRequest):
            for client in clients:
                await ctx.send(client, SayResponse(user_name=msg.user_name, message=msg.message))
        elif isinstance(msg, NickRequest):
            for client in clients:
                await ctx.send(client, NickResponse(old_user_name=msg.old_user_name, new_user_name=msg.new_user_name))

    props = OpenTracingFactory.get_props_with_open_tracing(Props.from_func(process_message), span_setup, span_setup)
    context.spawn_named(props, 'chatserver')

    input()
예제 #8
0
async def test_pop_behavior_should_restore_pushed_behavior():
    behavior = Behavior()

    async def func_1(ctx):
        if isinstance(ctx.message, str):

            async def func_2(ctx2):
                await ctx2.respond(42)
                behavior.unbecome_stacked()

            behavior.become_stacked(func_2)
            await ctx.respond(ctx.message)

    behavior.become(func_1)

    props = Props.from_func(behavior.receive_async)
    context = RootContext()
    pid = context.spawn(props)

    reply = await context.request_future(pid, "number")
    reply_after_push = await context.request_future(pid, None)
    reply_after_pop = await context.request_future(
        pid, "answertolifetheuniverseandeverything")

    assert reply + str(
        reply_after_push
    ) + reply_after_pop == "number42answertolifetheuniverseandeverything"
예제 #9
0
async def main():
    context = RootContext()
    Serialization().register_file_descriptor(DESCRIPTOR)
    Remote().start("192.168.1.129", 12001)

    wg = asyncio.Event()
    message_count = 10000

    props = Props.from_producer(lambda: LocalClient(0, message_count, wg, asyncio.get_event_loop()))

    pid = context.spawn(props)
    remote = PID(address="192.168.1.77:12000", id="remote")

    await context.request_future(remote, StartRemote(Sender=pid))

    start = datetime.datetime.now()
    print('Starting to send')
    for i in range(message_count):
        await context.send(remote, Ping())
    await wg.wait()

    elapsed = datetime.datetime.now() - start
    print(f'Elapsed {elapsed}')

    t = message_count * 2.0 / elapsed.total_seconds()
    print(f'Throughput {t} msg / sec')

    input()
예제 #10
0
async def test_request_actor_async_should_not_raise_timeout_exception_when_result_is_first(
):
    props = Props.from_func(hello_function)
    pid = context.spawn(props)
    reply = await context.request_async(pid, "hello", timedelta(seconds=1))

    assert reply == "hey"
예제 #11
0
async def start(argv):
    tracer = init_jaeger_tracer()
    opentracing.set_global_tracer(tracer)

    middleware = open_tracing_middleware.open_tracing_sender_middleware(tracer)

    Serialization().register_file_descriptor(DESCRIPTOR)
    Remote().start("127.0.0.1", 12001)
    server = PID(address='127.0.0.1:8000', id='chatserver')
    context = RootContext(MessageHeader(), [middleware])

    props = OpenTracingFactory.get_props_with_open_tracing(Props.from_func(process_message), span_setup, span_setup,
                                                           tracer)

    client = context.spawn(props)
    await context.send(server, Connect(sender=client))

    nick = 'Alex'
    while True:
        text = input()
        if text == '/exit':
            return
        elif text.startswith('/nick '):
            new_nick = text.split(' ')[1]
            await context.send(server, NickRequest(old_user_name=nick, new_user_name=new_nick))
            nick = new_nick
        else:
            await context.send(server, SayRequest(user_name=nick, message=text))
예제 #12
0
    def get_props_with_open_tracing(props: Props, send_span_setup: Callable[[Span, any], None] = None,
                                    receive_span_setup: Callable[[Span, any], None] = None,
                                    tracer: Tracer = None) -> Props:
        def fn(ctx):
            return OpenTracingFactory.get_context_with_open_tracing(ctx, send_span_setup, receive_span_setup)

        new_props = props.with_context_decorator([fn])
        return OpenTracingFactory.get_props_with_open_tracing_sender(new_props, tracer)
예제 #13
0
async def test_request_actor_async_should_raise_timeout_exception_when_timeout_is_reached(
):
    with pytest.raises(TimeoutError) as excinfo:
        props = Props.from_func(empty_receive)
        pid = context.spawn(props)
        await context.request_async(pid, "", timedelta(seconds=1))

    assert 'TimeoutError' in str(excinfo)
예제 #14
0
async def main():
    context = RootContext()
    provider = InMemoryProvider()

    props = Props.from_producer(lambda: MyPersistenceActor(provider))
    pid = context.spawn(props)

    input()
예제 #15
0
async def test_can_use_global_behaviour():
    context = RootContext()
    test_actor_props = Props.from_producer(LightBulb)
    actor = context.spawn(test_actor_props)
    _ = await context.request_async(actor, PressSwitch())
    assert await context.request_async(actor, HitWithHammer()) == "Smashed!"
    assert await context.request_async(actor, PressSwitch()) == "Broken"
    assert await context.request_async(actor, Touch()) == "OW!"
예제 #16
0
async def run_test(mailbox: Callable[..., AbstractMailbox]):
    props = Props.from_func(process_message) \
                 .with_mailbox(mailbox)

    pid = GlobalRootContext.spawn(props)
    for i in range(10000):
        await GlobalRootContext.send(pid, i)
    await GlobalRootContext.request_future(pid, 'stop')
예제 #17
0
async def test_can_change_states():
    test_actor_props = Props.from_producer(LightBulb)
    context = RootContext()
    actor = context.spawn(test_actor_props)
    assert await context.request_async(actor, PressSwitch()) == "Turning on"
    assert await context.request_async(actor, Touch())== "Hot!"
    assert await context.request_async(actor, PressSwitch()) == "Turning off"
    assert await context.request_async(actor, Touch()) == "Cold"
예제 #18
0
    def start(self) -> None:
        # self.__logger.log_debug('Started EndpointManager')
        props = Props().from_producer(EndpointSupervisor)\
            .with_guardian_supervisor_strategy(Supervision().always_restart_strategy)

        self._endpoint_supervisor = GlobalRootContext().instance.spawn_named(props, 'EndpointSupervisor')
        self._endpoint_conn_evn_sub = GlobalEventStream().instance.subscribe(self.__on_endpoint_connected,
                                                                             EndpointConnectedEvent)
        self._endpoint_term_evn_sub = GlobalEventStream().instance.subscribe(self.__on_endpoint_terminated,
                                                                             EndpointTerminatedEvent)
예제 #19
0
def test_props_default_init():
    props = Props()

    assert props.producer is None
    # TODO: change these value with concrete default instances
    #assert props.mailbox_producer is None
    #assert props.supervisor_strategy is None
    assert props.dispatcher is None
    assert props.middleware == []
    assert props.middleware_chain is None
예제 #20
0
 def create_transfer(self, actor_name: str, from_account: PID,
                     to_account: PID, amount: float,
                     persistence_id: str) -> PID:
     transfer_props = Props.from_producer(lambda: TransferProcess(
         from_account, to_account, amount, self._provider, persistence_id,
         self._availability)).with_child_supervisor_strategy(
             OneForOneStrategy(
                 lambda pid, reason: SupervisorDirective.Restart,
                 self._retry_attempts, None))
     transfer = self._context.spawn_named(transfer_props, actor_name)
     return transfer
예제 #21
0
    def __spawn_writer(self, address: str, context: AbstractContext) -> PID:
        writer_props = Props.from_producer(lambda: EndpointWriter(address,
                                                                  Remote().remote_config.channel_options,
                                                                  Remote().remote_config.call_options,
                                                                  Remote().remote_config.channel_credentials))

        writer_props = writer_props.with_mailbox(lambda: EndpointWriterMailbox(Remote()
                                                                               .remote_config
                                                                               .endpoint_writer_batch_size))
        writer = context.spawn(writer_props)
        return writer
예제 #22
0
        def spawn_router_process(name: str, props: Props, parent: PID) -> PID:
            wg = threading.Event()
            router_state = self.create_router_state()
            p = props.with_producer(lambda: RouterActor(self, router_state, wg))

            ctx = ActorContext(p, parent)
            mailbox = props.mailbox_producer()
            dispatcher = props.dispatcher
            process = RouterProcess(router_state, mailbox, wg)
            pid, absent = ProcessRegistry().try_add(name, process)
            if not absent:
                raise ProcessNameExistException(name, pid)

            ctx.my_self = pid
            mailbox.register_handlers(ctx, dispatcher)
            mailbox.post_system_message(Started())
            mailbox.start()
            wg.wait()

            return pid
예제 #23
0
    async def receive(self, context: AbstractContext):
        if context.children is None or len(context.children) == 0:
            props = Props.from_producer(lambda: ChildActor())
            child = context.spawn(props)
        else:
            child = context.children[0]

        msg = context.message
        if isinstance(msg, Hello) or \
           isinstance(msg, Recoverable) or \
           isinstance(msg, Fatal):
            await context.forward(child)
        elif isinstance(msg, Terminated):
            print(f'Watched actor was Terminated, {msg.who}')
async def main():
    async def child_fn(context: AbstractContext):
        print(f'{context.my_self.id}: MSG: {type(context.message)}')
        if isinstance(context.message, Started):
            raise Exception('child failure')

    child_props = Props.from_func(child_fn)

    async def root_fn(context: AbstractContext):
        print(f'{context.my_self.id}: MSG: {type(context.message)}')
        if isinstance(context.message, Started):
            context.spawn_named(child_props, 'child')
        elif isinstance(context.message, Terminated):
            print(f'Terminated {context.message.who}')

    root_props = Props.from_func(root_fn).with_child_supervisor_strategy(
        OneForOneStrategy(lambda pid, reason: SupervisorDirective.Escalate, 0,
                          None))

    root_context = RootContext()
    root_context.spawn_named(root_props, 'root')

    input()
예제 #25
0
def test_props_with(field, method, value):
    props = Props()

    with_method = getattr(props, method)
    new_props = with_method(value)

    results = [('producer', None), ('dispatcher', None),
               ('mailbox_producer', None), ('supervisor_strategy', None)]

    for r in results:
        field_name = r[0]
        prop_value = getattr(new_props, field_name)
        if field_name == field:
            assert prop_value == value
        else:
            assert prop_value == r[1]
예제 #26
0
async def main():
    tracer = init_jaeger_tracer()
    opentracing.set_global_tracer(tracer)
    GlobalEventStream.subscribe(process_dead_letter_event, DeadLetterEvent)

    context = RootContext(middleware=[open_tracing_sender_middleware()])

    props = Props.from_producer(lambda: ChildActor())
    props = OpenTracingFactory.get_props_with_open_tracing(props)

    actor = context.spawn(props)
    await context.send(actor, Hello(who="Alex"))

    await asyncio.sleep(1)
    await GlobalRootContext.stop_future(actor)

    input()
def create_test_actor(strategy):
    events = {'process_started': threading.Event(),
              'process_get_state': threading.Event(),
              'process_get_index': threading.Event(),
              'process_request_snapshot': threading.Event(),
              'process_multiply': threading.Event()}

    actor_id = str(uuid.uuid4())
    in_memory_provider = InMemoryProvider()
    props = Props.from_producer(lambda: ExamplePersistentActor(events,
                                                               in_memory_provider,
                                                               in_memory_provider,
                                                               actor_id,
                                                               strategy)).with_mailbox(MockMailbox)
    pid = root_context.spawn(props)

    return events, pid, props, actor_id, in_memory_provider
async def main():
    context = LoggingRootDecorator(RootContext())

    async def fn(context: AbstractContext):
        message = context.message
        if isinstance(message, str):
            print(f'Inside Actor: {message}')
            await context.respond("Yo!")

    props = Props.from_func(fn).with_context_decorator([
        lambda c: LoggingDecorator(c, 'logger1'),
        lambda c: LoggingDecorator(c, 'logger2')
    ])
    pid = context.spawn(props)

    res = await context.request_future(pid, 'Hello')
    print(f'Got result {res}')
    input()
예제 #29
0
async def start(argv):
    host = None
    port = None
    opts, args = getopt.getopt(argv, "hp", ["host=", "port="])
    for opt, arg in opts:
        if opt == '--host':
            host = arg
        elif opt == '--port':
            port = arg

    Serialization().register_file_descriptor(DESCRIPTOR)

    context = RootContext()
    Remote().start(host, port)
    props = Props().from_producer(lambda: EchoActor(host, port))
    Remote().register_known_kind('EchoActor', props)
    context.spawn_named(props, "EchoActorInstance")

    input()
예제 #30
0
 async def receive(self, context: AbstractContext):
     msg = context.message
     if isinstance(msg, Started):
         pid = context.spawn(Props.from_producer(ScheduleGreetActor))
         await self._scheduler.schedule_tell_once(
             timedelta(milliseconds=100), context.my_self,
             SimpleMessage('test 1'))
         await self._scheduler.schedule_tell_once(
             timedelta(milliseconds=200), context.my_self,
             SimpleMessage('test 2'))
         await self._scheduler.schedule_tell_once(
             timedelta(milliseconds=300), context.my_self,
             SimpleMessage('test 3'))
         await self._scheduler.schedule_tell_once(
             timedelta(milliseconds=400), context.my_self,
             SimpleMessage('test 4'))
         await self._scheduler.schedule_tell_once(
             timedelta(milliseconds=500), context.my_self,
             SimpleMessage('test 5'))
         await self._scheduler.schedule_request_once(
             timedelta(seconds=1), context.my_self, pid, Greet('Daniel'))
         await self._scheduler.schedule_tell_once(timedelta(seconds=5),
                                                  context.my_self, Hello())
     elif isinstance(msg, Hello):
         print(
             "Hello Once, let's give you a hickup every 0.5 second starting in 3 seconds!"
         )
         await self._scheduler.schedule_tell_repeatedly(
             timedelta(seconds=3), timedelta(milliseconds=500),
             context.my_self, HickUp(), self._timer)
     elif isinstance(msg, HickUp):
         self._counter += 1
         print('Hello!')
         if self._counter == 5:
             self._timer.trigger()
             await context.send(context.my_self, AbortHickUp())
     elif isinstance(msg, AbortHickUp):
         print(f'Aborted hickup after {self._counter} times')
         print('All this was scheduled calls, have fun!')
     elif isinstance(msg, Greet):
         print(f'Thanks {msg.who()}')
     elif isinstance(msg, SimpleMessage):
         print(msg.msg())