Use torrent status diffs in the TorrentView to reduce the amount of rpc

traffic from the core->gtkui
This commit is contained in:
Andrew Resch 2010-01-25 00:15:12 +00:00
parent c202f7727f
commit 25afa04ba3
5 changed files with 63 additions and 10 deletions

View File

@ -385,9 +385,9 @@ class Core(component.Component):
self.torrentmanager[torrent_id].resume() self.torrentmanager[torrent_id].resume()
@export @export
def get_torrent_status(self, torrent_id, keys): def get_torrent_status(self, torrent_id, keys, diff=False):
# Build the status dictionary # Build the status dictionary
status = self.torrentmanager[torrent_id].get_status(keys) status = self.torrentmanager[torrent_id].get_status(keys, diff)
# Get the leftover fields and ask the plugin manager to fill them # Get the leftover fields and ask the plugin manager to fill them
leftover_fields = list(set(keys) - set(status.keys())) leftover_fields = list(set(keys) - set(status.keys()))
@ -396,7 +396,7 @@ class Core(component.Component):
return status return status
@export @export
def get_torrents_status(self, filter_dict, keys): def get_torrents_status(self, filter_dict, keys, diff=False):
""" """
returns all torrents , optionally filtered by filter_dict. returns all torrents , optionally filtered by filter_dict.
""" """
@ -405,7 +405,7 @@ class Core(component.Component):
# Get the torrent status for each torrent_id # Get the torrent status for each torrent_id
for torrent_id in torrent_ids: for torrent_id in torrent_ids:
status_dict[torrent_id] = self.get_torrent_status(torrent_id, keys) status_dict[torrent_id] = self.get_torrent_status(torrent_id, keys, diff)
return status_dict return status_dict

View File

@ -96,8 +96,7 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase,
try: try:
status[field] = self.status_fields[field](torrent_id) status[field] = self.status_fields[field](torrent_id)
except KeyError: except KeyError:
log.warning("Status field %s is not registered with the\ pass
PluginManager.", field)
return status return status
def register_status_field(self, field, function): def register_status_field(self, field, function):

View File

@ -72,7 +72,7 @@ class TorrentOptions(dict):
self["file_priorities"] = [] self["file_priorities"] = []
self["mapped_files"] = {} self["mapped_files"] = {}
class Torrent: class Torrent(object):
"""Torrent holds information about torrents added to the libtorrent session. """Torrent holds information about torrents added to the libtorrent session.
""" """
def __init__(self, handle, options, state=None, filename=None, magnet=None): def __init__(self, handle, options, state=None, filename=None, magnet=None):
@ -80,6 +80,16 @@ class Torrent:
# Get the core config # Get the core config
self.config = ConfigManager("core.conf") self.config = ConfigManager("core.conf")
self.rpcserver = component.get("RPCServer")
# This dict holds previous status dicts returned for this torrent
# We use this to return dicts that only contain changes from the previous
# {session_id: status_dict, ...}
self.prev_status = {}
from twisted.internet.task import LoopingCall
self.prev_status_cleanup_loop = LoopingCall(self.cleanup_prev_status)
self.prev_status_cleanup_loop.start(10)
# Set the libtorrent handle # Set the libtorrent handle
self.handle = handle self.handle = handle
# Set the torrent_id for this torrent # Set the torrent_id for this torrent
@ -525,8 +535,21 @@ class Torrent:
return host return host
return "" return ""
def get_status(self, keys): def get_status(self, keys, diff=False):
"""Returns the status of the torrent based on the keys provided""" """
Returns the status of the torrent based on the keys provided
:param keys: the keys to get the status on
:type keys: list of str
:param diff: if True, will return a diff of the changes since the last
call to get_status based on the session_id
:type diff: bool
:returns: a dictionary of the status keys and their values
:rtype: dict
"""
# Create the full dictionary # Create the full dictionary
self.status = self.handle.status() self.status = self.handle.status()
if self.handle.has_metadata(): if self.handle.has_metadata():
@ -656,6 +679,24 @@ class Torrent:
status_dict[key] = full_status[key] status_dict[key] = full_status[key]
elif key in fns: elif key in fns:
status_dict[key] = fns[key]() status_dict[key] = fns[key]()
session_id = self.rpcserver.get_session_id()
if diff:
if session_id in self.prev_status:
# We have a previous status dict, so lets make a diff
status_diff = {}
for key, value in status_dict.items():
if key in self.prev_status[session_id]:
if value != self.prev_status[session_id][key]:
status_diff[key] = value
else:
status_diff[key] = value
self.prev_status[session_id] = status_dict
return status_diff
self.prev_status[session_id] = status_dict
return status_dict
return status_dict return status_dict
@ -828,3 +869,14 @@ class Torrent:
wait_on_folder[2].append(f["index"]) wait_on_folder[2].append(f["index"])
self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8")) self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8"))
self.waiting_on_folder_rename.append(wait_on_folder) self.waiting_on_folder_rename.append(wait_on_folder)
def cleanup_prev_status(self):
"""
This method gets called to check the validity of the keys in the prev_status
dict. If the key is no longer valid, the dict will be deleted.
"""
for key in self.prev_status.keys():
if not self.rpcserver.is_session_valid(key):
del self.prev_status[key]

View File

@ -387,6 +387,8 @@ class TorrentManager(component.Component):
if options["mapped_files"]: if options["mapped_files"]:
for index, name in options["mapped_files"].items(): for index, name in options["mapped_files"].items():
log.debug("renaming file index %s to %s", index, name) log.debug("renaming file index %s to %s", index, name)
import code
code.interact(local=locals())
torrent_info.rename_file(index, name.encode("utf-8")) torrent_info.rename_file(index, name.encode("utf-8"))
add_torrent_params["ti"] = torrent_info add_torrent_params["ti"] = torrent_info

View File

@ -325,7 +325,7 @@ class TorrentView(listview.ListView, component.Component):
# Request the statuses for all these torrent_ids, this is async so we # Request the statuses for all these torrent_ids, this is async so we
# will deal with the return in a signal callback. # will deal with the return in a signal callback.
client.core.get_torrents_status( client.core.get_torrents_status(
self.filter, status_keys).addCallback(self._on_get_torrents_status) self.filter, status_keys, True).addCallback(self._on_get_torrents_status)
def update(self): def update(self):
# Send a status request # Send a status request