import asyncio


async def cancel_task(task, name, log):
    """
    Cancels and cleans up `task`, with logging as `name`.
    """
    log.info(f"canceling {name} task")
    if task.cancelled():
        log.info(f"{name} task already cancelled")
    else:
        task.cancel()

    try:
        return await task
    except asyncio.CancelledError:
        log.info(f"{name} task cancelled")
    except Exception:
        log.error(f"{name} task raised", exc_info=True)