async def test_pub_sub_with_all_topics(server):
    """
    Check client gets event when subscribing via ALL_TOPICS
    """
    # finish trigger
    finish = asyncio.Event()
    # Create a client and subscribe to topics
    async with PubSubClient() as client:

        async def on_event(data, topic):
            assert data == DATA
            finish.set()

        # subscribe for the event
        client.subscribe(ALL_TOPICS, on_event)
        # start listentining
        client.start_client(uri)
        # wait for the client to be ready to receive events
        await client.wait_until_ready()
        # publish events (with sync=False toa void deadlocks waiting on the publish to ourselves)
        published = await client.publish(
            [EVENT_TOPIC], data=DATA, sync=False, notifier_id=gen_uid()
        )
        assert published.result
        # wait for finish trigger
        await asyncio.wait_for(finish.wait(), 5)
    def __init__(self,
                 broadcast_url: str,
                 notifier: EventNotifier,
                 channel="EventNotifier",
                 broadcast_type=None,
                 is_publish_only=False) -> None:
        """

        Args:
            broadcast_url (str): the URL of the broadcasting service
            notifier (EventNotifier): the event notifier managing our internal events - which will be bridge via the broadcaster
            channel (str, optional): Channel name. Defaults to "EventNotifier".
            broadcast_type (Broadcast, optional): Broadcast class to use. None - Defaults to Broadcast.
            is_publish_only (bool, optional): [For default context] Should the broadcaster only transmit events and not listen to any. Defaults to False
        """
        # Broadcast init params
        self._broadcast_url = broadcast_url
        self._broadcast_type = broadcast_type or Broadcast
        # Publish broadcast (initialized within async with statement)
        self._sharing_broadcast_channel = None
        # channel to operate on
        self._channel = channel
        # Async-io task for reading broadcasts (initialized within async with statement)
        self._subscription_task = None
        # Uniqueue instance id (used to avoid reading own notifications sent in broadcast)
        self._id = gen_uid()
        # The internal events notifier
        self._notifier = notifier
        self._is_publish_only = is_publish_only
        self._publish_lock = None
        # used to track creation / removal of resources needed per type (reader task->listen, and subscription to internal events->share)
        self._listen_count: int = 0
        self._share_count: int = 0
        # If we opt to manage the context directly (i.e. call async with on the event broadcaster itself)
        self._context_manager = None
async def test_immediate_server_disconnect(server):
    """
    Test reconnecting when a server hangups on connect
    """
    # finish trigger
    finish = asyncio.Event()
    # Create a client and subscribe to topics
    async with PubSubClient() as client:

        async def on_event(data, topic):
            assert data == DATA
            finish.set()

        # subscribe for the event
        client.subscribe(EVENT_TOPIC, on_event)
        # start listentining
        client.start_client(uri)
        # wait for the client to be ready to receive events
        await client.wait_until_ready()
        # publish events (with sync=False toa void deadlocks waiting on the publish to ourselves)
        published = await client.publish([EVENT_TOPIC],
                                         data=DATA,
                                         sync=False,
                                         notifier_id=gen_uid())
        assert published.result == True
        # wait for finish trigger
        await asyncio.wait_for(finish.wait(), 5)
Exemplo n.º 4
0
    def __init__(self,
                 broadcast_url: str,
                 notifier: EventNotifier,
                 channel="EventNotifier",
                 broadcast_type=None,
                 is_publish_only=False) -> None:
        """

        Args:
            broadcast_url (str): the URL of the broadcasting service
            notifier (EventNotifier): the event notifier managing our internal events - which will be bridge via the broadcaster
            channel (str, optional): Channel name. Defaults to "EventNotifier".
            broadcast_type (Broadcast, optional): Broadcast class to use. None - Defaults to Broadcast.
            is_publish_only (bool, optional): Should the broadcaster only transmit events and not listen to any. Defaults to False
        """
        # Broadcast init params
        self._broadcast_url = broadcast_url
        self._broadcast_type = broadcast_type or Broadcast
        # Publish broadcast (initialized within async with statement)
        self._broadcast = None
        # channel to operate on
        self._channel = channel
        # Async-io task for reading broadcasts (initialized within async with statement)
        self._subscription_task = None
        # Uniqueue instance id (used to avoid reading own notifications sent in broadcast)
        self._id = gen_uid()
        # The internal events notifier
        self._notifier = notifier
        self._is_publish_only = is_publish_only
        self._lock = asyncio.Lock()
        self._publish_lock = asyncio.Lock()
        self._num_connections = 0
async def test_pub_sub_with_all_topics_with_remote_id_on(server):
    """
    same as the basic_test::test_pub_sub_with_all_topics, but this time makes sure that
    the rpc_channel_get_remote_id doesn't break anything.
    """
    # finish trigger
    finish = asyncio.Event()
    # Create a client and subscribe to topics
    async with PubSubClient() as client:

        async def on_event(data, topic):
            assert data == DATA
            finish.set()

        # subscribe for the event
        client.subscribe(ALL_TOPICS, on_event)
        # start listentining
        client.start_client(uri)
        # wait for the client to be ready to receive events
        await client.wait_until_ready()
        # publish events (with sync=False toa void deadlocks waiting on the publish to ourselves)
        published = await client.publish([EVENT_TOPIC],
                                         data=DATA,
                                         sync=False,
                                         notifier_id=gen_uid())
        assert published.result
        # wait for finish trigger
        await asyncio.wait_for(finish.wait(), 5)
 async def on_connect(client, channel):
     try:
         print("Connected")
         # publish events (with sync=False to avoid deadlocks waiting on the publish to ourselves)
         published = await client.publish([EVENT_TOPIC],
                                          data=DATA,
                                          sync=False,
                                          notifier_id=gen_uid())
         assert published.result == True
     except RpcChannelClosedException:
         # expected
         pass
async def test_disconnect_callback_without_context(delayed_death_server):
    """
    Test reconnecting when a server hangups AFTER connect and that the disconnect callback work
    """
    # finish trigger
    finish = asyncio.Event()
    disconnected = asyncio.Event()

    async def on_disconnect(channel):
        disconnected.set()

    async def on_connect(client, channel):
        try:
            print("Connected")
            # publish events (with sync=False to avoid deadlocks waiting on the publish to ourselves)
            published = await client.publish([EVENT_TOPIC],
                                             data=DATA,
                                             sync=False,
                                             notifier_id=gen_uid())
            assert published.result == True
        except RpcChannelClosedException:
            # expected
            pass

    # Create a client and subscribe to topics
    client = PubSubClient(on_disconnect=[on_disconnect],
                          on_connect=[on_connect])

    async def on_event(data, topic):
        assert data == DATA
        finish.set()

    # subscribe for the event
    client.subscribe(EVENT_TOPIC, on_event)
    # start listentining
    client.start_client(uri)
    # wait for the client to be ready to receive events
    await client.wait_until_ready()
    # publish events (with sync=False toa void deadlocks waiting on the publish to ourselves)
    published = await client.publish([EVENT_TOPIC],
                                     data=DATA,
                                     sync=False,
                                     notifier_id=gen_uid())
    assert published.result == True
    # wait for finish trigger
    await asyncio.wait_for(finish.wait(), 5)
    await client.disconnect()
    await asyncio.wait_for(disconnected.wait(), 1)
    assert disconnected.is_set()
Exemplo n.º 8
0
from fastapi import (APIRouter, FastAPI, WebSocket)
import uvicorn
import pytest
from multiprocessing import Process
import asyncio
import os
import sys

# Add parent path to use local src as package for tests
sys.path.append(
    os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))

# Configurable
PORT = int(os.environ.get("PORT") or "9000")
# Random ID
CLIENT_ID = gen_uid()
uri = f"ws://localhost:{PORT}/ws/{CLIENT_ID}"


class RpcCalculator(RpcMethodsBase):
    async def add(self, a: float, b: float) -> float:
        return a + b

    async def multiply(self, a: float, b: float) -> float:
        return a * b


def setup_calc_server():
    app = FastAPI()
    router = APIRouter()
    # expose calculator methods
 def gen_subscription_id(self):
     return gen_uid()
 def gen_subscriber_id(self):
     return gen_uid()