Example #1
0
async def test_join_cleanup_external2():
    """
    Ensure that when the scope is done,
    all tasks have been cleaned properly.
    """
    done = False
    scope = Scope()

    async def job():
        nonlocal done
        try:
            await asyncio.sleep(10)
        finally:
            done = True

    async def runner(scope):
        async with scope:
            scope << job()

    task = asyncio.ensure_future(runner(scope))

    # Wait a bit so that everyone is started and blocked
    await asyncio.sleep(0.2)

    # Now: scope should be joining, pending on job
    assert not done

    # Cancel the scope and await the scope
    scope.cancel()
    await scope

    # As soon as scope is done, we should have cleaned up job
    assert done

    await task
Example #2
0
async def test_join_cleanup():
    """
    Ensure that when the scope is done,
    all tasks have been cleaned properly.
    """
    done = False

    async def job():
        nonlocal done
        try:
            await asyncio.sleep(10)
        finally:
            done = True

    scope = Scope()

    # will run 0.2 seconds
    scope << job()

    await asyncio.sleep(0.1)

    scope.cancel()
    await scope

    assert done
Example #3
0
async def test_join_cancel(wait):
    """

    """
    parent = Scope()

    await asyncio.sleep(0.1)
    parent.cancel()

    if wait:
        await parent
    else:
        await asyncio.wait_for(parent, 1)
Example #4
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)
Example #5
0
async def test_cancel_finally_cancel():
    """
    Cancelled internally, twice
    """
    async def cleaner():
        await asyncio.sleep(0.2)
        raise ValueError('boom')

    scope = Scope()

    with pytest.raises(ValueError):
        try:
            async with scope:
                scope << cleaner()
        finally:
            scope.cancel()
Example #6
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)
Example #7
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)