Stricter requirements to consider a client healthy

A healthy client must not only have a sync task running, but also have
finished its initial sync and have been succesful in its last sync
attempt.

The previous weak requirement caused this issue:
Have two clients, one on a failing server, and try to fetch a media,
thumbnail or profile: since these functions don't need auth, any
healthy client is picked to do the request, but the previous
requirement made it possible to pick the failing client.
This commit is contained in:
miruka 2020-07-20 16:03:46 -04:00
parent b803c34338
commit e62d99c3cc
4 changed files with 21 additions and 7 deletions

View File

@ -258,7 +258,8 @@ class Backend:
while True:
for client in self.clients.values():
if client.syncing:
if client.healthy:
print( client, client.first_sync_done)
return client
if failures and failures % 300 == 0:

View File

@ -189,8 +189,9 @@ class MatrixClient(nio.AsyncClient):
self.upload_tasks: Dict[UUID, asyncio.Task] = {}
self.send_message_tasks: Dict[UUID, asyncio.Task] = {}
self.first_sync_done: asyncio.Event = asyncio.Event()
self.first_sync_date: Optional[datetime] = None
self.first_sync_done: asyncio.Event = asyncio.Event()
self.first_sync_date: Optional[datetime] = None
self.last_sync_error: Optional[Exception] = None
self.past_tokens: Dict[str, str] = {} # {room_id: token}
self.fully_loaded_rooms: Set[str] = set() # {room_id}
@ -324,13 +325,15 @@ class MatrixClient(nio.AsyncClient):
await self.close()
@property
def syncing(self) -> bool:
"""Return whether this client is currently syncing with the server."""
def healthy(self) -> bool:
"""Return whether we're syncing and last sync was successful."""
if not self.sync_task:
task = self.sync_task
if not task or not self.first_sync_date or self.last_sync_error:
return False
return not self.sync_task.done()
return not task.done()
async def _start(self) -> None:
@ -395,6 +398,8 @@ class MatrixClient(nio.AsyncClient):
await self.sync_task
break # task cancelled
except Exception as err:
self.last_sync_error = err
trace = traceback.format_exc().rstrip()
if isinstance(err, MatrixError) and err.http_code >= 500:
@ -405,6 +410,8 @@ class MatrixClient(nio.AsyncClient):
)
else:
LoopException(str(err), err, trace)
else:
self.last_sync_error = None
await asyncio.sleep(5)

View File

@ -0,0 +1,3 @@
<svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg">
<path d="m1664 896q0 156-61 298t-164 245-245 164-298 61q-172 0-327-72.5t-264-204.5q-7-10-6.5-22.5t8.5-20.5l137-138q10-9 25-9 16 2 23 12 73 95 179 147t225 52q104 0 198.5-40.5t163.5-109.5 109.5-163.5 40.5-198.5-40.5-198.5-109.5-163.5-163.5-109.5-198.5-40.5q-98 0-188 35.5t-160 101.5l137 138q31 30 14 69-17 40-59 40h-448q-26 0-45-19t-19-45v-448q0-42 40-59 39-17 69 14l130 129q107-101 244.5-156.5t284.5-55.5q156 0 298 61t245 164 164 245 61 298z"/>
</svg>

After

Width:  |  Height:  |  Size: 547 B

View File

@ -0,0 +1,3 @@
<svg height="1792" viewBox="0 0 1792 1792" width="1792" xmlns="http://www.w3.org/2000/svg">
<path d="m1664 256v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l138-138q-148-137-349-137-104 0-198.5 40.5t-163.5 109.5-109.5 163.5-40.5 198.5 40.5 198.5 109.5 163.5 163.5 109.5 198.5 40.5q119 0 225-52t179-147q7-10 23-12 14 0 25 9l137 138q9 8 9.5 20.5t-7.5 22.5q-109 132-264 204.5t-327 72.5q-156 0-298-61t-245-164-164-245-61-298 61-298 164-245 245-164 298-61q147 0 284.5 55.5t244.5 156.5l130-129q29-31 70-14 39 17 39 59z"/>
</svg>

After

Width:  |  Height:  |  Size: 532 B