Example #1
0
File: ping.py Project: prplz/aiomc
async def minecraft_ping(host,
                         port,
                         loop: asyncio.AbstractEventLoop = None) -> PingResult:
    if loop is None:
        loop = asyncio.get_event_loop()

    conn = MinecraftProtocol(loop)
    try:
        await loop.create_connection(lambda: conn, host, port)

        conn.write_packet(packets.handshake(47, host, port))
        conn.write_packet(packets.request_status())
        await conn.drain()

        packet = MinecraftIO(await conn.read_packet())
        assert packet.read_varint() == 0
        status = packet.read_string()

        ping_id = int(time.time() * 1000)
        conn.write_packet(packets.ping(ping_id))
        await conn.drain()

        ping_send_time = loop.time()

        packet = MinecraftIO(await conn.read_packet())
        latency = int((loop.time() - ping_send_time) * 1000)
        assert packet.read_varint() == 1

        json_ = json.loads(status)

        return PingResult(json_, latency)
    finally:
        if conn.writer is not None:
            conn.writer.close()
Example #2
0
async def run(argv, hosts, loop: asyncio.AbstractEventLoop):
    started = loop.time()
    drift = i = 0
    while True:
        i += 1
        interval = argv.interval - drift
        tasks = [
            pingport(loop, host, interval, argv) for host in hosts
            if host in IP_CACHE
        ]
        await asyncio.gather(*tasks)
        drift = loop.time() - i * argv.interval - started
Example #3
0
async def pingport(loop: asyncio.AbstractEventLoop, host: str, interval: int,
                   argv):
    started = loop.time()
    elapsed = connected = 0
    if host != IP_CACHE[host]:
        hostname = f"{host}:{argv.port} ({IP_CACHE[host]})"
    else:
        hostname = f"{host}:{argv.port}"

    with async_timeout.timeout(argv.timeout + 1):
        try:
            conn = asyncio.open_connection(IP_CACHE[host],
                                           argv.port,
                                           loop=loop)
            reader, writer = await asyncio.wait_for(conn, timeout=argv.timeout)
        except KeyboardInterrupt:
            print("Ok, boss, lets call it a day.")
            sys.exit(0)
        except Exception as e:
            if argv.verbose:
                print(
                    f"Ping {hostname} failed... ({e.__class__.__name__}: {str(e)!r})"
                )
        else:
            if argv.verbose:
                print(f"Ping {hostname} OK...")
            conn.close()
            connected = argv.timeout
            elapsed = loop.time() - started

    db = host2filename(argv, host)
    # Check previous pings
    if not connected:
        last_update = rrdtool.lastupdate(db)
        if 'ds' in last_update and last_update['ds']['connect']:
            sys.stderr.write(f"{hostname} is flappy\n")
        else:
            last = rrdtool.fetch(db, "MIN", "--start", str(-argv.interval * 6))
            last_connections = [int(c) for c, t in last[2]
                                if c is not None][-5:]
            if len(last_connections) == 5 and not any(last_connections):
                sys.stderr.write(f"{hostname} is down\n")

    # Record this attempt
    rrdtool.update(
        db,
        f"N:{int(connected)}:{elapsed}",
    )
    return await asyncio.sleep(interval)
Example #4
0
def loop2timestamp(loop_time: float,
                   loop: asyncio.AbstractEventLoop = None) -> float:
    if loop is None:
        loop = asyncio.get_event_loop()
    now_loop = loop.time()
    now_timestamp = utctimestamp(datetime.utcnow())
    return now_timestamp + (loop_time - now_loop)
Example #5
0
def get_time_accelerator(
    loop: asyncio.AbstractEventLoop,
    instant_step: bool = False
) -> typing.Callable[[float], typing.Awaitable[None]]:
    """
    Returns an async advance() function

    This provides a way to advance() the BaseEventLoop.time for the scheduled TimerHandles
    made by call_later, call_at, and call_soon.
    """

    original = loop.time
    _drift = 0
    loop.time = functools.wraps(loop.time)(lambda: original() + _drift)

    async def accelerate_time(seconds: float) -> None:
        nonlocal _drift
        if seconds < 0:
            raise ValueError(f'Cannot go back in time ({seconds} seconds)')
        _drift += seconds
        await asyncio.sleep(0)

    async def accelerator(seconds: float):
        steps = seconds * 10.0 if not instant_step else 1

        for _ in range(max(int(steps), 1)):
            await accelerate_time(seconds / steps)

    return accelerator
Example #6
0
    def __init__(self, *, loop: ALoop):
        self._subscription_waiters = []  # type: List[Future]
        self._assignment_waiters = []  # type: List[Future]
        self._loop = loop  # type: ALoop

        # Fetch contexts
        self._fetch_count = 0
        self._last_fetch_ended = loop.time()
Example #7
0
    def __init__(self, *, loop: ALoop):
        self._subscription_waiters = []  # type: List[Future]
        self._assignment_waiters = []  # type: List[Future]
        self._loop = loop  # type: ALoop

        # Fetch contexts
        self._fetch_count = 0
        self._last_fetch_ended = loop.time()
Example #8
0
def call_later(
        cb: Callable[[], Any], timeout: float,
        loop: asyncio.AbstractEventLoop) -> Optional[asyncio.TimerHandle]:
    if timeout is not None and timeout > 0:
        when = loop.time() + timeout
        if timeout > 5:
            when = ceil(when)
        return loop.call_at(when, cb)
    return None
Example #9
0
    async def _monitor_lag(self, loop: AbstractEventLoop):
        log.info("Monitoring async lag started")
        while loop.is_running():
            start = loop.time()
            await sleep(self._interval)
            # The closer this gap is to our intended sleep time
            # the less load the system is under. Large gaps mean
            # the running loop is dealing with a lot of work
            time_slept = loop.time() - start
            self.lag = time_slept - self._interval
            log.debug(f"Current async lag (ms): {self.lag * 1000}")

            tasks = [task for task in Task.all_tasks(loop) if not task.done()]
            self.active_tasks = len(tasks)
            log.debug(f"Active tasks: {self.active_tasks}")

            self._warn(tasks)
        log.info("Monitoring async lag stopped")
Example #10
0
def weakref_handle(
        ob: object, name: str, timeout: float,
        loop: asyncio.AbstractEventLoop) -> Optional[asyncio.TimerHandle]:
    if timeout is not None and timeout > 0:
        when = loop.time() + timeout
        if timeout >= 5:
            when = ceil(when)

        return loop.call_at(when, _weakref_handle, (weakref.ref(ob), name))
    return None
Example #11
0
def get_time_accelerator(
    loop: asyncio.AbstractEventLoop,
    now: typing.Optional[float] = None
) -> typing.Callable[[float], typing.Awaitable[None]]:
    """
    Returns an async advance() function

    This provides a way to advance() the BaseEventLoop.time for the scheduled TimerHandles
    made by call_later, call_at, and call_soon.
    """

    _time = now or loop.time()
    loop.time = functools.wraps(loop.time)(lambda: _time)

    async def accelerate_time(seconds: float) -> None:
        nonlocal _time
        if seconds < 0:
            raise ValueError(f'Cannot go back in time ({seconds} seconds)')
        _time += seconds
        await past_events()
        await asyncio.sleep(0)

    async def past_events() -> None:
        while loop._scheduled:
            timer: asyncio.TimerHandle = loop._scheduled[0]
            if timer not in loop._ready and timer._when <= _time:
                loop._scheduled.remove(timer)
                loop._ready.append(timer)
            if timer._when > _time:
                break
            await asyncio.sleep(0)

    async def accelerator(seconds: float):
        steps = seconds * 10.0

        for _ in range(max(int(steps), 1)):
            await accelerate_time(0.1)

    return accelerator
Example #12
0
 async def _exec(
         self,
         loop: asyncio.AbstractEventLoop,
         suppress_exceptions: ExceptionsType = (),
 ) -> None:
     self._statistic.call_count += 1
     delta: float = -loop.time()
     try:
         await self.func(*self.args, **self.kwargs)
     except suppress_exceptions:
         self._statistic.fail += 1
         return
     except asyncio.CancelledError:
         raise
     except Exception:
         self._statistic.fail += 1
         log.exception("Recurring task error:")
     else:
         self._statistic.done += 1
     finally:
         delta += loop.time()
         self._statistic.sum_time += delta
Example #13
0
def get_left_time(task: asyncio.Task = None, loop: asyncio.AbstractEventLoop = None):
    if loop is None:
        loop = get_running_loop()
    if task is None:
        task = current_task()
    out_time = getattr(task, _MODULE_TIMEOUT, None)
    if not out_time:
        return sys.maxsize
    now_time = loop.time()
    left_time = out_time - now_time
    if left_time < 0:
        return 0
    return left_time
Example #14
0
def set_timeout(task: asyncio.Task, timeout: [float, int], loop: asyncio.AbstractEventLoop = None, timeout_cancel=True):
    assert isinstance(timeout, (float, int))
    if loop is None:
        loop = get_running_loop()
    now_time = loop.time()
    out_time = now_time + timeout
    if timeout_cancel:
        if timeout <= 0:
            task.cancel()
            return
        unset_timeout(task)
        handle = loop.call_at(out_time, task.cancel)
        setattr(task, _MODULE_TIMEOUT_HANDLE, handle)
    setattr(task, _MODULE_TIMEOUT, out_time)
Example #15
0
 def __init__(self, loop: AbstractEventLoop, initial_time: int):
     loop.time = self
     self._loop = loop
     self._time = initial_time
Example #16
0
 def update_screen(self, end_time, loop: asyncio.AbstractEventLoop, screen: Screen):
     screen.draw_next_frame()
     if loop.time() < end_time:
         loop.call_later(0.05, self.update_screen, end_time, loop, screen)
     else:
         loop.stop()
Example #17
0
def _timeout_to_deadline(loop: asyncio.AbstractEventLoop,
                         timeout: Optional[float]) -> Optional[float]:
    if timeout is None:
        return None
    return loop.time() + timeout