implement client-to-server read timeout PINGs

This commit is contained in:
jesopo 2020-04-26 15:07:05 +01:00
parent f33a0ad369
commit ba57d06a56
3 changed files with 22 additions and 1 deletions

View file

@ -76,6 +76,7 @@ class IServer(Server):
disconnected: bool
params: ConnectionParams
desired_caps: Set[ICapability]
last_read: float
def send_raw(self, line: str, priority=SendPriority.DEFAULT
) -> Awaitable[SentLine]:

View file

@ -2,8 +2,10 @@ import asyncio
from asyncio import Future, PriorityQueue
from typing import Awaitable, Deque, Dict, List, Optional, Set, Tuple
from collections import deque
from time import monotonic
from asyncio_throttle import Throttler
from async_timeout import timeout
from ircstates import Emit, Channel
from ircstates.numerics import *
from ircstates.server import ServerDisconnectedException
@ -23,6 +25,7 @@ from .interface import ITCPTransport, ITCPReader, ITCPWriter
THROTTLE_RATE = 4 # lines
THROTTLE_TIME = 2 # seconds
PING_TIMEOUT = 60 # seconds
class Server(IServer):
_reader: ITCPReader
@ -39,6 +42,8 @@ class Server(IServer):
rate_limit=100, period=THROTTLE_TIME)
self.sasl_state = SASLResult.NONE
self.last_read = -1.0
self._ping_sent = False
self._sent_count: int = 0
self._write_queue: PriorityQueue[SentLine] = PriorityQueue()
@ -174,7 +179,21 @@ class Server(IServer):
both = self._read_queue.popleft()
else:
while True:
data = await self._reader.read(1024)
try:
async with timeout(PING_TIMEOUT):
data = await self._reader.read(1024)
except asyncio.exceptions.TimeoutError:
if self._ping_sent:
data = b"" # empty data means the socket disconnected
else:
self._ping_sent = True
await self.send(build("PING", ["hello"]))
continue
self.last_read = monotonic()
self._ping_sent = False
try:
lines = self.recv(data)
except ServerDisconnectedException:

View file

@ -3,3 +3,4 @@ asyncio-throttle ==1.0.1
dataclasses ==0.6
ircstates ==0.9.6
async_stagger ==0.3.0
async_timeout ==3.0.1