Пример #1
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()
Пример #2
0
async def main():
    context = RootContext()
    props = Props.from_func(hello_function)
    pid = context.spawn(props)

    reply = await context.request_future(pid, HelloMessage('Hello'))
    print(reply)
Пример #3
0
async def main():
    context = RootContext()
    props = Props.from_producer(HelloActor)
    pid = context.spawn(props)

    await context.send(pid, HelloMessage('Hello World!'))
    input()
Пример #4
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))
Пример #5
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()
Пример #6
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"
Пример #7
0
async def run_consistent_hash_pool_test():
    context = RootContext()
    props = Router.new_consistent_hash_pool(my_actor_props, 5)
    pid = context.spawn(props)

    for i in range(10):
        await context.send(pid, Message('%s' % (i % 4)))
Пример #8
0
async def run_broadcast_pool_test():
    context = RootContext()
    props = Router.new_broadcast_pool(my_actor_props, 5)

    for i in range(10):
        pid = context.spawn(props)
        await context.send(pid, Message('%s' % (i % 4)))
Пример #9
0
async def main():
    context = RootContext()
    provider = InMemoryProvider()

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

    input()
Пример #10
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_future(actor, PressSwitch())
    assert await context.request_future(actor, HitWithHammer()) == "Smashed!"
    assert await context.request_future(actor, PressSwitch()) == "Broken"
    assert await context.request_future(actor, Touch()) == "OW!"
Пример #11
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_future(actor, PressSwitch()) == "Turning on"
    assert await context.request_future(actor, Touch()) == "Hot!"
    assert await context.request_future(actor, PressSwitch()) == "Turning off"
    assert await context.request_future(actor, Touch()) == "Cold"
Пример #12
0
async def run_round_robin_group_test():
    context = RootContext()
    props = Router.new_round_robin_group([context.spawn(my_actor_props),
                                          context.spawn(my_actor_props),
                                          context.spawn(my_actor_props),
                                          context.spawn(my_actor_props)])

    pid = context.spawn(props)
    for i in range(10):
        await context.send(pid, Message('%s' % (i % 4)))
Пример #13
0
async def main():
    context = RootContext()
    pr = cProfile.Profile()
    while True:
        pid = context.spawn(props)
        pr.clear()
        pr.enable()
        response = await context.request_future(
            pid, Request(num=0, size=100, div=10))
        pr.disable()
        pr.print_stats(sort='time')
        print(response)
        await context.stop_future(pid)
        await asyncio.sleep(0.5)
Пример #14
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()
Пример #15
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()
Пример #16
0
    def __init__(self, number_of_iterations: int,
                 interval_between_console_updates: int, uptime: float,
                 refusal_probability: float, busy_probability: float,
                 retry_attempts: int, verbose: bool):
        self._context = RootContext()
        self._number_of_iterations = number_of_iterations
        self._interval_between_console_updates = interval_between_console_updates
        self._uptime = uptime
        self._refusal_probability = refusal_probability
        self._busy_probability = busy_probability
        self._retry_attempts = retry_attempts
        self._verbose = verbose

        self._transfers = []
        self._success_results = 0
        self._failed_and_inconsistent_results = 0
        self._failed_but_consistent_results = 0
        self._unknown_results = 0
        self._in_memory_provider = None
Пример #17
0
async def main():
    context = RootContext()
    number_of_transfers = 5
    interval_between_console_updates = 1
    uptime = 99.99
    retry_attempts = 0
    refusal_probability = 0.01
    busy_probability = 0.01
    verbose = False

    props = Props.from_producer(lambda: Runner(
        number_of_transfers, interval_between_console_updates, uptime,
        refusal_probability, busy_probability, retry_attempts, verbose
    )).with_child_supervisor_strategy(
        OneForOneStrategy(lambda pid, reason: SupervisorDirective.Restart,
                          retry_attempts, None))

    print('Spawning runner')
    context.spawn_named(props, 'runner')
    input()
Пример #18
0
async def main():
    context = RootContext()

    logging.basicConfig(
        format='%(name)s - %(levelname)s - %(message)s %(stack_info)s',
        level=logging.DEBUG,
        handlers=[logging.StreamHandler(sys.stdout)])

    props = Props.from_producer(
        lambda: ParentActor()).with_child_supervisor_strategy(
            OneForOneStrategy(Decider.decide, 1, None))
    actor = context.spawn(props)
    await context.send(actor, Hello('Alex'))
    await context.send(actor, Recoverable())
    await context.send(actor, Fatal())

    await asyncio.sleep(1)
    await context.stop(actor)

    input()
Пример #19
0
async def main():
    root_context = RootContext()
    counter = itertools.count()
    next(counter)

    async def fn(context: AbstractContext):
        msg = context.message
        if isinstance(msg, Started):
            print(f'{datetime.today().strftime("%Y-%m-%d-%H.%M.%S")} Started')
            context.set_receive_timeout(timedelta(seconds=1))
        elif isinstance(msg, ReceiveTimeout):
            print(f'{datetime.today().strftime("%Y-%m-%d-%H.%M.%S")} ReceiveTimeout: {next(counter)}')
        elif isinstance(msg, NoInfluence):
            print(f'{datetime.today().strftime("%Y-%m-%d-%H.%M.%S")} Received a no-influence message')
        elif isinstance(msg, str):
            print(f'{datetime.today().strftime("%Y-%m-%d-%H.%M.%S")} Received message: {msg}')

    props = Props.from_func(fn)
    pid = root_context.spawn(props)

    for i in range(6):
        await root_context.send(pid, 'hello')
        await asyncio.sleep(0.5)

    print('Hit [return] to send no-influence messages')
    input()

    for i in range(6):
        await root_context.send(pid, NoInfluence())
        await asyncio.sleep(0.5)

    print('Hit [return] to send a message to cancel the timeout')
    input()

    await root_context.send(pid, 'cancel')

    print('Hit [return] to finish')
    input()
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()
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()
Пример #22
0
async def start(argv):
    context = RootContext()
    Serialization().register_file_descriptor(DESCRIPTOR)
    parsed_args = parse_args(argv)

    # await Cluster.start('MyCluster', parsed_args.server_name, 12002, SingleRemoteInstanceProvider('192.168.1.72', 12000))

    await Cluster.start(
        'MyCluster', parsed_args.server_name, 12001,
        ConsulProvider(
            ConsulClientConfiguration(
                f'http://{parsed_args.consul_url}:8500/')))

    pid, sc = await Cluster.get_async("TheName", "HelloKind")
    while sc != ResponseStatusCode.OK:
        await asyncio.sleep(0.5)
        pid, sc = await Cluster.get_async("TheName", "HelloKind")

    res = await context.request_future(pid, HelloRequest())
    print(res.message)
    await asyncio.sleep(timedelta(days=180).total_seconds())
    print('Shutting Down...')
    await Cluster.shutdown()
Пример #23
0
async def main():
    context = RootContext()
    Serialization().register_file_descriptor(DESCRIPTOR)
    Remote().start("192.168.1.77", 12000)
    context.spawn_named(Props.from_producer(lambda: EchoActor()), 'remote')
    input()
Пример #24
0
 def __init__(self, context: AbstractSenderContext = RootContext()):
     self._context = context
Пример #25
0
async def main():
    headers = MessageHeader({'TraceID': str(uuid.uuid4()),
                             'SpanID': str(uuid.uuid4())})

    def get_middleware(next_middleware):
        async def process(context, target, envelope):
            new_envelope = envelope \
                .with_header(key='TraceID', value=context.headers.get('TraceID')) \
                .with_header(key='SpanID', value=str(uuid.uuid4())) \
                .with_header(key='ParentSpanID', value=context.headers.get('SpanID'))

            print(' 1 Enter RootContext SenderMiddleware')
            print(' 1 TraceID: ' + new_envelope.header.get('TraceID'))
            print(' 1 SpanID: ' + new_envelope.header.get('SpanID'))
            print(' 1 ParentSpanID: ' + new_envelope.header.get('ParentSpanID'))
            await next_middleware(context, target, new_envelope)
            print(' 1 Exit RootContext SenderMiddleware - Send is async, this is out of order by design')

        return process

    root = RootContext(headers, [get_middleware])

    async def actor_logic(context):
        if isinstance(context.message, str):
            print('   3 Enter Actor')
            print('   3 TraceID = ' + context.headers.get('TraceID'))
            print('   3 SpanID = ' + context.headers.get('SpanID'))
            print('   3 ParentSpanID = ' + context.headers.get('ParentSpanID'))
            print('   3 actor got = %s:%s' % (str(type(context.message)), context.message))
            await context.respond("World !")
            print('   3 Exit Actor')

    def get_receive_middleware(next_middleware):
        async def process(context, envelope):
            if isinstance(envelope.message, str):
                new_envelope = envelope \
                    .with_header(key='TraceID', value=envelope.header.get('TraceID')) \
                    .with_header(key='SpanID', value=str(uuid.uuid4())) \
                    .with_header(key='ParentSpanID', value=envelope.header.get('SpanID'))

                print('  2 Enter Actor ReceiverMiddleware')
                print('  2 TraceID: ' + new_envelope.header.get('TraceID'))
                print('  2 SpanID: ' + new_envelope.header.get('SpanID'))
                print('  2 ParentSpanID: ' + new_envelope.header.get('ParentSpanID'))
                await next_middleware(context, new_envelope)
                print('  2 Exit Actor ReceiverMiddleware')
            else:
                await next_middleware(context, envelope)

        return process

    def get_sender_middleware(next_middleware):
        async def process(context, target, envelope):
            new_envelope = envelope \
                .with_header(key='TraceID', value=context.headers.get('TraceID')) \
                .with_header(key='SpanID', value=str(uuid.uuid4())) \
                .with_header(key='ParentSpanID', value=context.headers.get('SpanID'))

            print('    4 Enter Actor SenderMiddleware')
            print('    4 TraceID: ' + new_envelope.header.get('TraceID'))
            print('    4 SpanID: ' + new_envelope.header.get('SpanID'))
            print('    4 ParentSpanID: ' + new_envelope.header.get('ParentSpanID'))
            await next_middleware(context, target, envelope)
            print('    4 Exit Actor SenderMiddleware')

        return process

    actor = Props.from_func(actor_logic)\
            .with_receive_middleware([get_receive_middleware])\
            .with_sender_middleware([get_sender_middleware])

    pid = root.spawn(actor)

    print('0 TraceID: ' + root.headers.get('TraceID'))
    print('0 SpanID: ' + root.headers.get('SpanID'))
    print('0 ParentSpanID: ' + root.headers.get('ParentSpanID', ''))

    res = await root.request_future(pid, "hello")
    print('Got result ' + res)

    await asyncio.sleep(0.5)
import asyncio
import logging
import threading
from datetime import timedelta

import pytest

from protoactor.actor.actor import Actor
from protoactor.actor.actor_context import RootContext, AbstractContext
from protoactor.actor.props import Props
from protoactor.router.messages import RemoveRoutee, GetRoutees, AddRoutee, BroadcastMessage
from protoactor.router.router import Router

context = RootContext()
timeout = timedelta(milliseconds=1000)
my_actor_props = Props.from_producer(lambda: MyTestActor())


@pytest.mark.asyncio
async def test_broadcast_group_router_all_routees_receive_messages():
    router, routee1, routee2, routee3 = create_broadcast_group_router_with3_routees(
    )

    await context.send(router, 'hello')

    assert await context.request_future(routee1, 'received?',
                                        timeout) == 'hello'
    assert await context.request_future(routee2, 'received?',
                                        timeout) == 'hello'
    assert await context.request_future(routee3, 'received?',
                                        timeout) == 'hello'
Пример #27
0
async def main():
    context = RootContext()
    props = Props.from_producer(ScheduleActor)
    pid = context.spawn(props)

    input()
Пример #28
0
class Runner(Actor):
    def __init__(self, number_of_iterations: int,
                 interval_between_console_updates: int, uptime: float,
                 refusal_probability: float, busy_probability: float,
                 retry_attempts: int, verbose: bool):
        self._context = RootContext()
        self._number_of_iterations = number_of_iterations
        self._interval_between_console_updates = interval_between_console_updates
        self._uptime = uptime
        self._refusal_probability = refusal_probability
        self._busy_probability = busy_probability
        self._retry_attempts = retry_attempts
        self._verbose = verbose

        self._transfers = []
        self._success_results = 0
        self._failed_and_inconsistent_results = 0
        self._failed_but_consistent_results = 0
        self._unknown_results = 0
        self._in_memory_provider = None

    def __create_account(self, name: str) -> PID:
        account_props = Props.from_producer(
            lambda: Account(name, self._uptime, self._refusal_probability, self
                            ._busy_probability))
        return self._context.spawn_named(account_props, name)

    async def receive(self, context: AbstractContext) -> None:
        msg = context.message
        if isinstance(msg, SuccessResult):
            self._success_results += 1
            await self.__check_for_completion(msg.pid)
        elif isinstance(msg, UnknownResult):
            self._unknown_results += 1
            await self.__check_for_completion(msg.pid)
        elif isinstance(msg, FailedAndInconsistent):
            self._failed_and_inconsistent_results += 1
            await self.__check_for_completion(msg.pid)
        elif isinstance(msg, FailedButConsistentResult):
            self._failed_but_consistent_results += 1
            await self.__check_for_completion(msg.pid)
        elif isinstance(msg, Started):
            self._in_memory_provider = InMemoryProvider()

            def every_nth_action(i: int):
                print(f'Started {i}/{self._number_of_iterations} processes')

            def every_action(i: int, nth: bool):
                j = i
                from_account = self.__create_account(f'FromAccount{j}')
                to_account = self.__create_account(f'ToAccount{j}')
                actor_name = f'Transfer Process {j}'
                persistance_id = f'Transfer Process {j}'
                factory = TransferFactory(context, self._in_memory_provider,
                                          self._uptime, self._retry_attempts)
                transfer = factory.create_transfer(actor_name, from_account,
                                                   to_account, 10,
                                                   persistance_id)
                self._transfers.append(transfer)
                if i == self._number_of_iterations and not nth:
                    print(f'Started {j}/{self._number_of_iterations} proesses')

            ForWithProgress(self._number_of_iterations,
                            self._interval_between_console_updates, True,
                            False).every_nth(every_nth_action, every_action)

    async def __check_for_completion(self, pid: PID):
        self._transfers.remove(pid)
        remaining = len(self._transfers)
        if self._number_of_iterations >= self._interval_between_console_updates:
            print('.')
            if remaining % (self._number_of_iterations /
                            self._interval_between_console_updates) == 0:
                print()
                print(f'{remaining} processes remaining')
            else:
                print(f'{remaining} processes remaining')
            if remaining == 0:
                await asyncio.sleep(0.25)
                print()
                print(
                    f'RESULTS for {self._uptime}% uptime, {self._refusal_probability}% chance of refusal, '
                    f'{self._busy_probability}% of being busy and {self._retry_attempts} retry attempts:'
                )

                print(
                    f'{self.__as_percentage(self._number_of_iterations, self._success_results)}% '
                    f'({self._success_results}/{self._number_of_iterations}) successful transfers'
                )

                print(
                    f'{self.__as_percentage(self._number_of_iterations, self._failed_but_consistent_results)}% '
                    f'({self._failed_but_consistent_results}/{self._number_of_iterations}) '
                    f'failures leaving a consistent system')

                print(
                    f'{self.__as_percentage(self._number_of_iterations, self._failed_and_inconsistent_results)}% '
                    f'({self._failed_and_inconsistent_results}/{self._number_of_iterations}) '
                    f'failures leaving an inconsistent system')

                print(
                    f'{self.__as_percentage(self._number_of_iterations, self._unknown_results)}% '
                    f'({self._unknown_results}/{self._number_of_iterations}) unknown results'
                )

                if self._verbose:
                    for stream in self._in_memory_provider.events:
                        print()
                        print(f'Event log for {stream.key}')
                        for event in stream.value:
                            print(event.value)

    def __as_percentage(self, number_of_iterations: float, results: float):
        return (results / number_of_iterations) * 100
import threading
import uuid

import pytest

from protoactor.actor.actor import Actor
from protoactor.actor.actor_context import AbstractContext, RootContext
from protoactor.actor.props import Props
from protoactor.persistence.persistence import Persistence
from protoactor.persistence.snapshot_strategies.interval_strategy import IntervalStrategy
from protoactor.persistence.providers.in_memory_provider import InMemoryProvider
from tests.persistence.test_example_persistent_actor import Multiplied, Multiply
from tests.test_fixtures.mock_mailbox import MockMailbox

root_context = RootContext()


@pytest.mark.asyncio
async def test_given_an_interval_strategy_should_save_snapshot_accordingly():
    threading_events, pid, _, actor_id, provider_state = create_test_actor(IntervalStrategy(1))

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

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

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