From 3e550f4ae7ef13496fcc2e19ae406f324a2ee8e2 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 14 Feb 2011 14:37:36 +0100 Subject: [PATCH 1/2] Properly remove the info_win from the list of the global information_buffer to make it Garbage Collected when we close the tab --- src/tabs.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/tabs.py b/src/tabs.py index 3c91fc14..aa5ccab3 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -259,6 +259,16 @@ class ChatTab(Tab): def command_say(self, line): raise NotImplementedError +class TabWithInfoWin(Tab): + def __init__(self): + self.info_win = windows.TextWin() + self.core.information_buffer.add_window(self.info_win) + + def __del__(self): + self.core.information_buffer.del_window(self.info_win) + del self.info_win + Tab.__del__(self) + class InfoTab(ChatTab): """ The information tab, used to display global informations @@ -267,8 +277,6 @@ class InfoTab(ChatTab): def __init__(self, core): Tab.__init__(self, core) self.tab_win = windows.GlobalInfoBar() - self.info_win = windows.TextWin() - self.core.information_buffer.add_window(self.info_win) self.input = windows.Input() self.name = "Info" self.color_state = theme.COLOR_TAB_NORMAL @@ -338,21 +346,20 @@ class InfoTab(ChatTab): def on_close(self): return -class MucTab(ChatTab): +class MucTab(ChatTab, TabWithInfoWin): """ The tab containing a multi-user-chat room. It contains an userlist, an input, a topic, an information and a chat zone """ def __init__(self, core, room): ChatTab.__init__(self, core, room) + TabWithInfoWin.__init__(self) self.topic_win = windows.Topic() self.text_win = windows.TextWin() room.add_window(self.text_win) self.v_separator = windows.VerticalSeparator() self.user_win = windows.UserList() self.info_header = windows.MucInfoWin() - self.info_win = windows.TextWin() - self.core.information_buffer.add_window(self.info_win) self.tab_win = windows.GlobalInfoBar() self.input = windows.MessageInput() self.ignores = [] # set of Users @@ -662,17 +669,16 @@ class MucTab(ChatTab): def on_close(self): return -class PrivateTab(ChatTab): +class PrivateTab(ChatTab, TabWithInfoWin): """ The tab containg a private conversation (someone from a MUC) """ def __init__(self, core, room): ChatTab.__init__(self, core, room) + TabWithInfoWin.__init__(self) self.text_win = windows.TextWin() room.add_window(self.text_win) self.info_header = windows.PrivateInfoWin() - self.info_win = windows.TextWin() - self.core.information_buffer.add_window(self.info_win) self.tab_win = windows.GlobalInfoBar() self.input = windows.MessageInput() # keys @@ -1043,21 +1049,20 @@ class RosterInfoTab(Tab): def on_close(self): return -class ConversationTab(ChatTab): +class ConversationTab(ChatTab, TabWithInfoWin): """ The tab containg a normal conversation (not from a MUC) """ def __init__(self, core, jid): txt_buff = text_buffer.TextBuffer() ChatTab.__init__(self, core, txt_buff) + TabWithInfoWin.__init__(self) self.color_state = theme.COLOR_TAB_NORMAL self._name = jid # a conversation tab is linked to one specific full jid OR bare jid self.text_win = windows.TextWin() txt_buff.add_window(self.text_win) self.upper_bar = windows.ConversationStatusMessageWin() self.info_header = windows.ConversationInfoWin() - self.info_win = windows.TextWin() - self.core.information_buffer.add_window(self.info_win) self.tab_win = windows.GlobalInfoBar() self.input = windows.MessageInput() # keys From 4b31e5acf142664c2f2ebd2e0cfa26e700d947d7 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 14 Feb 2011 14:54:26 +0100 Subject: [PATCH 2/2] Make the number of lines and messages kept in memory configurable and lower (a lot) the number of lines kept in the info_win buffers This lower the memory usage. --- data/default_config.cfg | 6 ++++++ src/room.py | 8 ++++---- src/tabs.py | 2 +- src/text_buffer.py | 8 ++++---- src/windows.py | 5 +++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index 662fb44e..02103571 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -141,6 +141,12 @@ send_os_info = true # Set to false if you don't want people to know that information send_time = true +# Configure the number of maximum lines and messages (for each tab) that +# can be kept in memory. If poezio consumes too much memory, lower these +# values +max_messages_in_memory = 2048 +max_lines_in_memory = 2048 + [var] # You should not edit this section, it is just used by poezio # to save various data across restarts diff --git a/src/room.py b/src/room.py index 29986142..df97c638 100644 --- a/src/room.py +++ b/src/room.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with Poezio. If not, see . -from text_buffer import TextBuffer, MESSAGE_NB_LIMIT +from text_buffer import TextBuffer from datetime import datetime from random import randrange from config import config @@ -29,8 +29,8 @@ import logging log = logging.getLogger(__name__) class Room(TextBuffer): - def __init__(self, name, nick): - TextBuffer.__init__(self) + def __init__(self, name, nick, messages_nb_limit=config.get('max_messages_in_memory', 2048)): + TextBuffer.__init__(self, messages_nb_limit) self.name = name self.own_nick = nick self.color_state = theme.COLOR_TAB_NORMAL # color used in RoomInfo @@ -115,7 +115,7 @@ class Room(TextBuffer): time = time if time is not None else datetime.now() nick_color = nick_color or user.color if user else None message = Message(txt, time, nickname, nick_color, color, colorized, user=user) - while len(self.messages) > MESSAGE_NB_LIMIT: + while len(self.messages) > self.messages_nb_limit: self.messages.pop(0) self.messages.append(message) for window in self.windows: # make the associated windows diff --git a/src/tabs.py b/src/tabs.py index aa5ccab3..3b25095d 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -261,7 +261,7 @@ class ChatTab(Tab): class TabWithInfoWin(Tab): def __init__(self): - self.info_win = windows.TextWin() + self.info_win = windows.TextWin(20) self.core.information_buffer.add_window(self.info_win) def __del__(self): diff --git a/src/text_buffer.py b/src/text_buffer.py index 9285a433..3b2ddd1a 100644 --- a/src/text_buffer.py +++ b/src/text_buffer.py @@ -24,15 +24,15 @@ log = logging.getLogger(__name__) from message import Message from datetime import datetime import theme - -MESSAGE_NB_LIMIT = 8192 +from config import config class TextBuffer(object): """ This class just keep trace of messages, in a list with various informations and attributes. """ - def __init__(self): + def __init__(self, messages_nb_limit=config.get('max_messages_in_memory', 2048)): + self.messages_nb_limit = messages_nb_limit self.messages = [] # Message objects self.windows = [] # we keep track of one or more windows # so we can pass the new messages to them, as they are added, so @@ -47,7 +47,7 @@ class TextBuffer(object): time = time or datetime.now() msg = Message(txt, time, nickname, nick_color, color, colorized) self.messages.append(msg) - while len(self.messages) > MESSAGE_NB_LIMIT: + while len(self.messages) > self.messages_nb_limit: self.messages.pop(0) for window in self.windows: # make the associated windows # build the lines from the new message diff --git a/src/windows.py b/src/windows.py index c46b60e3..1ec5de8a 100644 --- a/src/windows.py +++ b/src/windows.py @@ -432,8 +432,9 @@ class MucInfoWin(InfoWin): self.addstr(txt, curses.color_pair(theme.COLOR_INFORMATION_BAR)) class TextWin(Win): - def __init__(self): + def __init__(self, lines_nb_limit=config.get('max_lines_in_memory', 2048)): Win.__init__(self) + self.lines_nb_limit = lines_nb_limit self.pos = 0 self.built_lines = [] # Each new message is built and kept here. # on resize, we rebuild all the messages @@ -525,7 +526,7 @@ class TextWin(Win): if txt.startswith('\n'): txt = txt[1:] first = False - while len(self.built_lines) > LINES_NB_LIMIT: + while len(self.built_lines) > self.lines_nb_limit: self.built_lines.pop(0) return nb