示例#1
0
async def test_fork_dead():
    """
    Try to fork a dead scope.
    """
    scope = Scope()

    async with scope:
        pass

    with pytest.raises(AssertionError):
        _ = scope.fork()
示例#2
0
async def test_nested_cancel_wait():
    """
    """
    parent = Scope()

    child = parent.fork()
    child << run10()

    await asyncio.sleep(0.1)

    child.cancel()
    parent.cancel()

    await asyncio.wait_for(asyncio.shield(parent), 1)
示例#3
0
async def test_nested_cancel_join(wait):
    """
    """
    parent = Scope()

    child = parent.fork()
    child << run10()

    await asyncio.sleep(0.1)

    child.cancel()
    parent.cancel()

    if wait:
        await parent
    else:
        await asyncio.wait_for(parent, 1)
示例#4
0
class Server:
    """Async TCP server using a scope to clean up everything"""
    def __init__(self):
        self.scope = Scope(name='TCP')
        self.scope.add_done_callback(self.stop)
        self.server = None

    def stop(self, _):
        print('scope done. closing server')
        if self.server:
            self.server.close()

    async def run(self):
        # Start TCP server
        self.server = await asyncio.start_server(self.client_connected,
                                                 '0.0.0.0', 5000)

        # Join the scope forever
        await self.scope

    async def client_connected(self, reader, writer):
        peer = writer.get_extra_info('peername')
        print(peer, 'connected')

        async with self.scope.fork(name=peer) as ctx:
            # We make one context for this connection
            # Here it's overkill, but you could have to spawn many jobs!
            try:
                while True:
                    try:
                        data = await (ctx << reader.readline())
                    except OSError as ex:
                        print(peer, 'socket error:', ex)
                        break

                    if not data:
                        # Connection closed
                        break

                    txt = data.decode().strip()
                    print(peer, 'received:', txt)

                    if txt == 'stop':
                        # Cancel the scope and exit
                        print('>>> stopping server')
                        writer.write('Closing!\n'.encode())
                        self.scope.cancel()
                        break

                    # Write reply and loop
                    writer.write('Hello {}!\n'.format(txt).encode())

                    # Just for fun, print later the received message
                    ctx << self.print_later(txt)
            finally:
                # Always say goodbye
                writer.write('Bye!\n'.encode())
                writer.close()
                print(peer, 'closed')

    @staticmethod
    async def print_later(txt):
        await asyncio.sleep(1)
        print('received earlier:', txt)