fix: load less messages on startup/gap fill

gap filler was called on MUC joins, therefore loading 999 messages
instead of the 2 times the screen height
This commit is contained in:
mathieui 2021-06-26 18:49:42 +02:00
parent e5b4f7ab0d
commit ae3b747e94
2 changed files with 34 additions and 12 deletions

View file

@ -19,7 +19,7 @@ from __future__ import annotations
import asyncio import asyncio
import logging import logging
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from typing import List from typing import List, Optional
from poezio import tabs from poezio import tabs
from poezio.logger import ( from poezio.logger import (
build_log_message, build_log_message,
@ -88,9 +88,9 @@ class LogLoader:
messages = [] messages = []
if gap is not None: if gap is not None:
if self.mam_only: if self.mam_only:
messages = await self.mam_fill_gap(gap) messages = await self.mam_fill_gap(gap, amount)
else: else:
messages = await self.local_fill_gap(gap) messages = await self.local_fill_gap(gap, amount)
else: else:
if self.mam_only: if self.mam_only:
messages = await self.mam_tab_open(amount) messages = await self.mam_tab_open(amount)
@ -126,6 +126,10 @@ class LogLoader:
finally: finally:
tab.query_status = False tab.query_status = False
def _get_time_limit(self) -> datetime:
"""Get the date 10 weeks ago from now."""
return datetime.now() - timedelta(weeks=10)
async def local_tab_open(self, nb: int) -> List[BaseMessage]: async def local_tab_open(self, nb: int) -> List[BaseMessage]:
"""Fetch messages locally when opening a new tab. """Fetch messages locally when opening a new tab.
@ -133,11 +137,14 @@ class LogLoader:
:returns: list of ui messages to add :returns: list of ui messages to add
""" """
await self.wait_mam() await self.wait_mam()
limit = self._get_time_limit()
results: List[BaseMessage] = [] results: List[BaseMessage] = []
filepath = self.logger.get_file_path(self.tab.jid) filepath = self.logger.get_file_path(self.tab.jid)
count = 0 count = 0
for msg in iterate_messages_reverse(filepath): for msg in iterate_messages_reverse(filepath):
typ_ = msg.pop('type') typ_ = msg.pop('type')
if msg['time'] < limit:
break
if typ_ == 'message': if typ_ == 'message':
results.append(make_line_local(self.tab, msg)) results.append(make_line_local(self.tab, msg))
if len(results) >= nb: if len(results) >= nb:
@ -147,13 +154,15 @@ class LogLoader:
await asyncio.sleep(0) await asyncio.sleep(0)
return results[::-1] return results[::-1]
async def mam_fill_gap(self, gap: HistoryGap) -> List[BaseMessage]: async def mam_fill_gap(self, gap: HistoryGap, amount: Optional[int] = None) -> List[BaseMessage]:
"""Fill a message gap in an existing tab using MAM. """Fill a message gap in an existing tab using MAM.
:param gap: Object describing the history gap :param gap: Object describing the history gap
:returns: list of ui messages to add :returns: list of ui messages to add
""" """
tab = self.tab tab = self.tab
if amount is None:
amount = HARD_LIMIT
start = gap.last_timestamp_before_leave start = gap.last_timestamp_before_leave
end = gap.first_timestamp_after_join end = gap.first_timestamp_after_join
@ -166,21 +175,24 @@ class LogLoader:
tab, tab,
start=start, start=start,
end=end, end=end,
amount=HARD_LIMIT amount=amount,
) )
except (NoMAMSupportException, MAMQueryException, DiscoInfoException): except (NoMAMSupportException, MAMQueryException, DiscoInfoException):
return [] return []
finally: finally:
tab.query_status = False tab.query_status = False
async def local_fill_gap(self, gap: HistoryGap) -> List[BaseMessage]: async def local_fill_gap(self, gap: HistoryGap, amount: Optional[int] = None) -> List[BaseMessage]:
"""Fill a message gap in an existing tab using the local logs. """Fill a message gap in an existing tab using the local logs.
Mostly useless when not used with the MAMFiller. Mostly useless when not used with the MAMFiller.
:param gap: Object describing the history gap :param gap: Object describing the history gap
:returns: list of ui messages to add :returns: list of ui messages to add
""" """
if amount is None:
amount = HARD_LIMIT
await self.wait_mam() await self.wait_mam()
limit = self._get_time_limit()
start = gap.last_timestamp_before_leave start = gap.last_timestamp_before_leave
end = gap.first_timestamp_after_join end = gap.first_timestamp_after_join
count = 0 count = 0
@ -189,11 +201,13 @@ class LogLoader:
filepath = self.logger.get_file_path(self.tab.jid) filepath = self.logger.get_file_path(self.tab.jid)
for msg in iterate_messages_reverse(filepath): for msg in iterate_messages_reverse(filepath):
typ_ = msg.pop('type') typ_ = msg.pop('type')
if msg['time'] < limit:
break
if start and msg['time'] < start: if start and msg['time'] < start:
break break
if typ_ == 'message' and (not end or msg['time'] < end): if typ_ == 'message' and (not end or msg['time'] < end):
results.append(make_line_local(self.tab, msg)) results.append(make_line_local(self.tab, msg))
if len(results) >= HARD_LIMIT: if len(results) >= amount:
break break
count += 1 count += 1
if count % 20 == 0: if count % 20 == 0:
@ -234,16 +248,17 @@ class LogLoader:
await self.wait_mam() await self.wait_mam()
tab = self.tab tab = self.tab
count = 0 count = 0
last_message_time = None
if tab._text_buffer.messages: first_message = tab._text_buffer.find_first_message()
last_message_time = to_utc(tab._text_buffer.messages[0].time) first_message_time = None
last_message_time -= timedelta(microseconds=1) if first_message:
first_message_time = first_message.time - timedelta(microseconds=1)
results: List[BaseMessage] = [] results: List[BaseMessage] = []
filepath = self.logger.get_file_path(self.tab.jid) filepath = self.logger.get_file_path(self.tab.jid)
for msg in iterate_messages_reverse(filepath): for msg in iterate_messages_reverse(filepath):
typ_ = msg.pop('type') typ_ = msg.pop('type')
if last_message_time is None or msg['time'] < last_message_time: if first_message_time is None or msg['time'] < first_message_time:
if typ_ == 'message': if typ_ == 'message':
results.append(make_line_local(self.tab, msg)) results.append(make_line_local(self.tab, msg))
if len(results) >= nb: if len(results) >= nb:

View file

@ -315,6 +315,13 @@ class TextBuffer:
return message return message
return None return None
def find_first_message(self) -> Optional[Message]:
"""Find the first real message received in this buffer"""
for message in self.messages:
if isinstance(message, Message):
return message
return None
def __del__(self): def __del__(self):
size = len(self.messages) size = len(self.messages)
log.debug('** Deleting %s messages from textbuffer', size) log.debug('** Deleting %s messages from textbuffer', size)