Exemple #1
0
    async def request(self, action: str, data: Any = None, **kw):
        """
        Send a request to the client, await+return the reply
        """
        if processing.get():
            raise RuntimeError("You cannot call this from within the receiver",
                               processing.get())

        self._n += 1
        n = self._n
        self._req[n] = evt = trio.Event()

        if kw:
            if data:
                data.update(kw)
            else:
                data = kw
        try:
            await super().send(["req", [action, n, data]])
            await evt.wait()
        except BaseException:
            self._req.pop(n)
            raise
        else:
            res = self._req.pop(n)
            if isinstance(res, Exception):
                raise res
            return res
Exemple #2
0
    def __init__(self, queue_len=None):
        if queue_len is None:
            queue_len = 1000

        # Processing queue
        self._q = trio.Queue(queue_len)

        # which files to close?
        self._close_files = set()

        # set up
        super().__init__(_TrioSelector())

        # replaced internal data
        self._ready = _Clear()
        self._scheduled = _Clear()
        self._default_executor = TrioExecutor()

        self._orig_signals = {}

        # we do our own timeout handling
        self._timers = []

        # Marker whether the loop is actually running
        self._stopped = trio.Event()
        self._stopped.set()
Exemple #3
0
async def test_trio_manager_stats_does_not_count_main_run_method():
    ready = trio.Event()

    class StatsTest(Service):
        async def run(self):
            self.manager.run_task(trio.sleep_forever)
            ready.set()

    async with background_trio_service(StatsTest()) as manager:
        with trio.fail_after(1):
            await ready.wait()

        # we need to yield to the event loop a few times to allow the various
        # tasks to schedule themselves and get running.
        for _ in range(10):
            await trio.hazmat.checkpoint()

        assert manager.stats.tasks.total_count == 1
        assert manager.stats.tasks.finished_count == 0
        assert manager.stats.tasks.pending_count == 1

    # now check after exiting
    assert manager.stats.tasks.total_count == 1
    assert manager.stats.tasks.finished_count == 1
    assert manager.stats.tasks.pending_count == 0
Exemple #4
0
    async def _main_loop(self, task_status=trio.TASK_STATUS_IGNORED):
        """Run the loop by processing its event queue.

        This is the core of trio-asyncio's replacement
        of the asyncio main loop.

        Do not call this method directly.
        """

        self._stopped = trio.Event()
        task_status.started()
        sniffio.current_async_library_cvar.set("asyncio")

        try:
            # The shield here ensures that if the context surrounding
            # the loop is cancelled, we keep processing callbacks
            # until we reach the callback inserted by stop().
            # That's important to maintain the asyncio invariant
            # that everything you schedule before stop() will run
            # before the loop stops. In order to be safe against
            # deadlocks, it's important that the surrounding
            # context ensure that stop() gets called upon a
            # cancellation. (open_loop() does this indirectly
            # by calling _main_loop_exit().)
            with trio.CancelScope(shield=True):
                while not self._stopped.is_set():
                    await self._main_loop_one()
        except StopAsyncIteration:
            # raised by .stop_me() to interrupt the loop
            pass
        finally:
            # Signal that the loop is no longer running
            self._stopped.set()
Exemple #5
0
async def wait_signal(signal: SignalInstance) -> typing.Tuple[typing.Any, ...]:
    """Block for the next emission of `signal` and return the emitted arguments.

    Warning:
        In many cases this can result in a race condition since you are unable to
        first connect the signal and then wait for it.

    Args:
        signal: The signal instance to wait for emission of.
    """
    event = trio.Event()
    result: typing.Tuple[typing.Any, ...] = ()

    def slot(*args):
        """Receive and store the emitted arguments and set the event so we can continue.

        Args:
            args: The arguments emitted from the signal.
        """
        nonlocal result
        result = args
        event.set()

    with qtrio._qt.connection(signal, slot):
        await event.wait()

    return result
async def test_eventual_values(predicate, held_for, consume_duration,
                               publish_durations, expected_values, nursery,
                               autojump_clock):
    assert held_for == 0 or predicate is not None
    expected_values = expected_values[:]
    x = AsyncValue(0)  # publisher uses sequence [0, 1, 2, ...]
    done_event = trio.Event()

    @nursery.start_soon
    async def _consumer():
        iterator = x.eventual_values() if predicate is None \
                else x.eventual_values(predicate, held_for=held_for)
        async for val in iterator:
            assert expected_values, f'unexpected additional value: {val}'
            assert val == expected_values.pop(0)
            if consume_duration is not None:
                await trio.sleep(consume_duration)
            if not expected_values:
                done_event.set()

    await wait_all_tasks_blocked()
    for duration in publish_durations:
        if duration is not None:
            await trio.sleep(duration)
        x.value += 1
    await done_event.wait()
Exemple #7
0
async def test_subscribe_and_publish():
    async with PubsubFactory.create_batch_with_floodsub(1) as pubsubs_fsub:
        pubsub = pubsubs_fsub[0]

        list_data = [b"d0", b"d1"]
        event_receive_data_started = trio.Event()

        async def publish_data(topic):
            await event_receive_data_started.wait()
            for data in list_data:
                await pubsub.publish(topic, data)

        async def receive_data(topic):
            i = 0
            event_receive_data_started.set()
            assert topic not in pubsub.topic_ids
            subscription = await pubsub.subscribe(topic)
            async with subscription:
                assert topic in pubsub.topic_ids
                async for msg in subscription:
                    assert msg.data == list_data[i]
                    i += 1
                    if i == len(list_data):
                        break
            assert topic not in pubsub.topic_ids

        async with trio.open_nursery() as nursery:
            nursery.start_soon(receive_data, TESTING_TOPIC)
            nursery.start_soon(publish_data, TESTING_TOPIC)
Exemple #8
0
 def __init__(self, hostname: str, port: int, use_ssl: bool,
              entry_point: Callable):
     self.hostname = hostname
     self.port = port
     self.use_ssl = use_ssl
     self.entry_point = entry_point
     self._on_offline = trio.Event()
Exemple #9
0
async def test_read_messages_after_remote_close(nursery):
    '''
    When the remote endpoint closes, the local endpoint can still read all
    of the messages sent prior to closing. Any attempt to read beyond that will
    raise ConnectionClosed.

    This test also exercises the configuration of the queue size.
    '''
    server_closed = trio.Event()

    async def handler(request):
        server = await request.accept()
        async with server:
            await server.send_message('1')
            await server.send_message('2')
        server_closed.set()

    server = await nursery.start(
        partial(serve_websocket, handler, HOST, 0, ssl_context=None))

    # The client needs a message queue of size 2 so that it can buffer both
    # incoming messages without blocking the reader task.
    async with open_websocket(HOST, server.port, '/', use_ssl=False,
            message_queue_size=2) as client:
        await server_closed.wait()
        assert await client.get_message() == '1'
        assert await client.get_message() == '2'
        with pytest.raises(ConnectionClosed):
            await client.get_message()
Exemple #10
0
def running_backend_port_known(request, unused_tcp_port):
    # Useful to synchronize other fixtures that need to connect to
    # the backend if it is available
    # This is also needed to create backend addr with a valid port
    event = trio.Event()
    backend_port = None

    # Called by `running_backend`` fixture once port is known
    def _set_running_backend_port_known(port: int) -> None:
        nonlocal backend_port
        assert not event.is_set()
        event.set()
        backend_port = port

    async def _wait_running_backend_port_known() -> int:
        nonlocal backend_port
        await event.wait()
        assert backend_port is not None
        return backend_port

    # Nothing to wait if current test doesn't use `running_backend` fixture
    if "running_backend" not in request.fixturenames:
        _set_running_backend_port_known(unused_tcp_port)

    # Only accessed by `running_backend` fixture
    _wait_running_backend_port_known._set_running_backend_port_known = (
        _set_running_backend_port_known)

    return _wait_running_backend_port_known
Exemple #11
0
    async def test_return_from_publish(self, channel):
        called = trio.Event()

        async def logger(task_status=trio.TASK_STATUS_IGNORED):
            task_status.started()
            async for a,b,c in channel:
                called.set()

        async def sender(task_status=trio.TASK_STATUS_IGNORED):
            task_status.started()

            # declare
            await channel.exchange_declare("e", "topic")

            # publish
            await channel.publish("coucou", "e", routing_key="not.found",
                                  mandatory=True)

        async def run_test():
            async with trio.open_nursery() as n:
                await n.start(logger)
                await n.start(sender)
                await called.wait()
                n.cancel_scope.cancel()

        with trio.fail_after(1):
            await run_test()
Exemple #12
0
    def stop(self, waiter=None):
        """Halt the main loop.

        (Or rather, tell it to halt itself soon(ish).)

        :param waiter: an Event that is set when the loop is stopped.
        :type waiter: :class:`trio.Event`
        :return: Either the Event instance that was passed in,
                 or a newly-allocated one.

        """
        if waiter is None:
            waiter = trio.Event()
        else:
            waiter.clear()

        def stop_me():
            waiter.set()
            raise StopAsyncIteration

        if self._stopped.is_set():
            waiter.set()
        else:
            self._queue_handle(
                Handle(stop_me, (), self, context=None, is_sync=True))
        return waiter
Exemple #13
0
async def AsyncShowDialog(dialog):
    """Shows a non-modal wx Dialog asyncronously"""
    closed = trio.Event()

    def end_dialog(return_code):
        dialog.SetReturnCode(return_code)
        dialog.Hide()
        closed.set()

    def on_button(event):
        # Logic copied from src/common/dlgcmn.cpp:
        # wxDialogBase::OnButton, EndDialog, and AcceptAndClose
        event_id = event.GetId()
        if event_id == dialog.GetAffirmativeId():
            if dialog.Validate() and dialog.TransferDataFromWindow():
                end_dialog(event_id)
        elif event_id == wx.ID_APPLY:
            if dialog.Validate():
                dialog.TransferDataFromWindow()
        elif event_id == dialog.GetEscapeId() or (event_id == wx.ID_CANCEL
                                                  and dialog.GetEscapeId()
                                                  == wx.ID_ANY):
            end_dialog(wx.ID_CANCEL)
        else:
            event.Skip()

    def on_close(event):
        closed.set()
        dialog.Hide()

    dialog.Bind(wx.EVT_CLOSE, on_close)
    dialog.Bind(wx.EVT_BUTTON, on_button)
    dialog.Show()
    await closed.wait()
    return dialog.GetReturnCode()
Exemple #14
0
    def __init__(
        self,
        addr: BackendOrganizationAddr,
        device_id: DeviceID,
        signing_key: SigningKey,
        event_bus: EventBus,
        max_cooldown: int = 30,
        max_pool: int = 4,
        keepalive: Optional[int] = None,
    ):
        if max_pool < 2:
            raise ValueError(
                "max_pool must be at least 2 (for event listener + query sender)"
            )

        self._started = False
        self._transport_pool = _transport_pool_factory(addr, device_id,
                                                       signing_key, max_pool,
                                                       keepalive)
        self._status = BackendConnStatus.LOST
        self._status_exc = None
        self._cmds = BackendAuthenticatedCmds(addr, self._acquire_transport)
        self._manager_connect_cancel_scope = None
        self._monitors_cbs: List[Callable[..., None]] = []
        self._monitors_idle_event = trio.Event()
        self._monitors_idle_event.set()  # No monitors
        self._backend_connection_failures = 0
        self.event_bus = event_bus
        self.max_cooldown = max_cooldown
Exemple #15
0
    async def execute(self, cmd: typing.Generator[dict,T,typing.Any]) -> T:
        '''
        Execute a command on the server and wait for the result.

        :param cmd: any CDP command
        :returns: a CDP result
        '''
        cmd_id = next(self.id_iter)
        cmd_event = trio.Event()
        self.inflight_cmd[cmd_id] = cmd, cmd_event
        request = next(cmd)
        request['id'] = cmd_id
        if self.session_id:
            request['sessionId'] = self.session_id
        logger.debug('Sending command %r', request)
        request_str = json.dumps(request)
        try:
            await self.ws.send_message(request_str)
        except WsConnectionClosed as wcc:
            raise CdpConnectionClosed(wcc.reason) from None
        await cmd_event.wait()
        response = self.inflight_result.pop(cmd_id)
        if isinstance(response, Exception):
            raise response
        return response
Exemple #16
0
 def __init__(self, redis_cli, redis_topic):
     self.event_buffer = {}
     if redis_cli is None:
         redis_cli = redis.Redis(host=REDIS_HOSTNAME, port=REDIS_PORT)
     self.redis_cli = redis_cli
     self.redis_topic = redis_topic
     self.exit_daemon_flag = trio.Event()
    async def set_pin_level(self, pin_watcher):
        """Set an output pin to a level based on the state of another pin that is being watched.
        Waits for initialization from pin_watcher. 

        Based on the state (True|False) of the pin being watched, sets the output of another pin to 0 or 1.

        Arguments::
            pin_watcher: an instance of the PinWatcher class, which represents the state of the pin being watched.
        """
        with pin_watcher.cancel_on_shutdown():
            # Trio checkpoint to facilitate checking on shutdown signals
            await trio.sleep(0)
            with gpio.Chip(label=self._chip_id) as chip:
                pin_in = chip.line(self._pin)
                with pin_in.open(
                        direction=gpio.DIRECTION_OUTPUT) as current_pin:
                    await pin_watcher.initialized.wait()
                    logger.info(
                        f'pin_watcher has been initialized, {self._name} monitoring on and off events'
                    )
                    logger.debug(
                        f'pin_watcher initial state in {self._name} is {pin_watcher.state}'
                    )
                    while True:
                        if pin_watcher.state:
                            current_pin.value = self._out_true
                            logger.debug(
                                f'in {self._name}, pin {self._pin} set to {self._out_true}'
                            )
                            pin_watcher.off_notify = event_to_watch = trio.Event(
                            )
                            await event_to_watch.wait()
                            if pin_watcher.shutting_down:
                                break
                        else:
                            current_pin.value = self._out_false
                            logger.debug(
                                f'in {self._name}, pin {self._pin} set to {self._out_false}'
                            )
                            pin_watcher.on_notify = event_to_watch = trio.Event(
                            )
                            await event_to_watch.wait()
                            if pin_watcher.shutting_down:
                                break
        logger.info(f'method set_pin_level in {self._name} has shutdown')
        if pin_watcher.shutting_down:
            return
Exemple #18
0
async def test_user_claim_ok(monkeypatch, backend, anonymous_backend_sock,
                             coolorg, alice, mallory_invitation):
    user_invitation_retreived = trio.Event()

    vanilla_claim_user_invitation = backend.user.claim_user_invitation

    async def _mocked_claim_user_invitation(*args, **kwargs):
        ret = await vanilla_claim_user_invitation(*args, **kwargs)
        user_invitation_retreived.set()
        return ret

    monkeypatch.setattr(backend.user, "claim_user_invitation",
                        _mocked_claim_user_invitation)

    with freeze_time(mallory_invitation.created_on):
        async with user_claim(
                anonymous_backend_sock,
                invited_user_id=mallory_invitation.user_id,
                encrypted_claim=b"<foo>",
        ) as prep:

            # `backend.user.create_user` will destroy the user invitation,
            # so make sure we retreived it before
            await user_invitation_retreived.wait()

            # No the user we are waiting for
            await backend.user.create_user(
                alice.organization_id,
                User(
                    user_id=UserID("dummy"),
                    user_certificate=b"<user certif>",
                    user_certifier=alice.device_id,
                ),
                Device(
                    device_id=DeviceID("dummy@pc1"),
                    device_certificate=b"<device certif>",
                    device_certifier=alice.device_id,
                ),
            )

            await backend.user.create_user(
                alice.organization_id,
                User(
                    user_id=mallory_invitation.user_id,
                    user_certificate=b"<user certif>",
                    user_certifier=alice.device_id,
                ),
                Device(
                    device_id=DeviceID(f"{mallory_invitation.user_id}@pc1"),
                    device_certificate=b"<device certif>",
                    device_certifier=alice.device_id,
                ),
            )

    assert prep[0] == {
        "status": "ok",
        "user_certificate": b"<user certif>",
        "device_certificate": b"<device certif>",
    }
Exemple #19
0
    def __init__(self, client):
        self.client = client
        self.sock = None
        self._event_large_write = trio.Event()

        self.client.on_socket_open = self.on_socket_open
        self.client.on_socket_register_write = self.on_socket_register_write
        self.client.on_socket_unregister_write = self.on_socket_unregister_write
Exemple #20
0
 async def cancel_trio(seen):
     started = trio.Event()
     async with trio.open_nursery() as nursery:
         nursery.start_soon(partial(self.call_t_a_depr, loop=loop),
                            in_asyncio, started, seen)
         await started.wait()
         nursery.cancel_scope.cancel()
     seen.flag |= 8
Exemple #21
0
 async def basic_consume_ok(self, frame):
     ctag = frame.payload_decoder.read_shortstr()
     results = {
         'consumer_tag': ctag,
     }
     future = self._get_waiter('basic_consume')
     future.set_result(results)
     self._ctag_events[ctag] = trio.Event()
Exemple #22
0
    def pause_reading(self):
        """Protocols can call this to tell us to stop reading data, if we are
        reading too much and too fast.

        We use an event and a flag to tell the background task to stop reading.
        """
        self._reading_paused = True
        self._reading_resumed_event = trio.Event()
Exemple #23
0
 async def get_wait(self, key: KT) -> VT:
     """Return value of given key, blocking until populated."""
     if key in self._store:
         return self._store[key]
     if key not in self._pending:
         self._pending[key] = trio.Event()
     await self._pending[key].wait()
     return self._store[key]
async def func_off_trigger(pin_watcher):
    """An example of a function that is is waiting on the state of a pin to be false.
    """
    pin_watcher.off_notify = event_to_watch = trio.Event()
    await pin_watcher.initialized.wait()
    logger.info(
        f'pin_watcher has been initialized, func_off_trigger has started')
    while True:
        with pin_watcher.cancel_on_shutdown():
            await event_to_watch.wait()
            if not pin_watcher.shutting_down:
                logger.debug(f'func_off_trigger has executed')
                # Code to execute when the pin is false goes here.
                pin_watcher.off_notify = event_to_watch = trio.Event()
        if pin_watcher.shutting_down:
            break
    logger.info(f'func_off_trigger has shutdown')
Exemple #25
0
 def __init__(self, all_insts: BaseInstrumentGroup):
     self.steps = []
     self.measurements = []
     self._insts = all_insts
     self._send_channels = []
     self.stop_signal = trio.Event()
     self.running = False
     self.write_file = None
Exemple #26
0
 def __init__(self, port: int) -> None:
     """
     :param port: The port that a server wants to bind to on this machine, and
     make publicly accessible.
     """
     self.port = port
     self._has_ip_addresses = trio.Event()
     self._ip_changed = trio.Condition()
Exemple #27
0
 def put_nowait(self, item: Any) -> None:
     logger.debug('trying to add %s to queue', item)
     self._send_channel.send_nowait(item)
     self._tasks_in_progress += 1
     logger.debug('number of tasks in progress is now: %s',
                  self._tasks_in_progress)
     if self._finished.is_set():
         self._finished = trio.Event()
async def test_device_claim_ok(monkeypatch, backend,
                               apiv1_anonymous_backend_sock, alice,
                               alice_nd_invitation):
    device_invitation_retrieved = trio.Event()

    vanilla_claim_device_invitation = backend.user.claim_device_invitation

    async def _mocked_claim_device_invitation(*args, **kwargs):
        ret = await vanilla_claim_device_invitation(*args, **kwargs)
        device_invitation_retrieved.set()
        return ret

    monkeypatch.setattr(backend.user, "claim_device_invitation",
                        _mocked_claim_device_invitation)

    with freeze_time(alice_nd_invitation.created_on):
        async with device_claim(
                apiv1_anonymous_backend_sock,
                invited_device_id=alice_nd_invitation.device_id,
                encrypted_claim=b"<foo>",
        ) as prep:

            # `backend.user.create_device` will destroy the device invitation,
            # so make sure we retrieved it before
            await device_invitation_retrieved.wait()

            # No the device we are waiting for
            await backend.user.create_device(
                alice.organization_id,
                Device(
                    device_id=alice.user_id.to_device_id("dummy"),
                    device_label=None,
                    device_certificate=b"<alice@dummy certificate>",
                    redacted_device_certificate=
                    b"<redacted alice@dummy certificate>",
                    device_certifier=alice.device_id,
                ),
                encrypted_answer=b"<alice@dummy answer>",
            )

            await backend.user.create_device(
                alice.organization_id,
                Device(
                    device_id=alice_nd_invitation.device_id,
                    device_label=None,
                    device_certificate=b"<alice@new_device certificate>",
                    redacted_device_certificate=
                    b"<redacted alice@new_device certificate>",
                    device_certifier=alice.device_id,
                ),
                encrypted_answer=b"<alice@new_device answer>",
            )

    assert prep[0] == {
        "status": "ok",
        "encrypted_answer": b"<alice@new_device answer>",
        "device_certificate": b"<alice@new_device certificate>",
    }
Exemple #29
0
    def __init__(self, nursery):
        super().__init__()

        self.log = logging.getLogger("ServerInterfaceAllStatements")

        # Lean environment
        self.lean_env: LeanEnvironment = LeanEnvironment(inst)
        # Lean attributes
        self.lean_file_content: str = ""
        self.lean_server: LeanServer = LeanServer(nursery, self.lean_env)
        self.nursery: trio.Nursery = nursery

        # Set server callbacks
        self.lean_server.on_message_callback = self.__on_lean_message
        self.lean_server.running_monitor.on_state_change_callback = \
            self.__on_lean_state_change

        # Course data
        self.course = None
        self.statement_from_hypo_line = dict()
        self.statement_from_targets_line = dict()
        self.statements = []
        self.hypo_analysis = None
        self.targets_analysis = None
        self.pf_counter = 0
        # Current proof state + Events
        self.file_invalidated = trio.Event()
        # self.__proof_state_valid       = trio.Event()

        # __proof_receive_done is set when enough information have been
        # received, i.e. either we have context and target and all effective
        # codes, OR an error message.
        self.__proof_receive_done = trio.Event()
        # self.__proof_receive_error     = trio.Event()  # Set if request
        # failed

        # When some CodeForLean iss sent to the __update method, it will be
        # duplicated and stored in __tmp_effective_code. This attribute will
        # be progressively modified into an effective code which is devoid
        # of or_else combinator, according to the "EFFECTIVE CODE" messages
        # sent by Lean.

        # Errors memory channels
        self.error_send, self.error_recv = \
            trio.open_memory_channel(max_buffer_size=1024)
    async def full_sync(self, filename, content=None) -> None:
        """Fully compile a Lean file before returning."""
        # Waiting for the response is not enough, so we prepare another event
        response = await self.send(SyncRequest(filename, content))
        assert isinstance(response, SyncResponse)

        if response.message == "file invalidated":
            self.is_fully_ready = trio.Event()
            await self.is_fully_ready.wait()