mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-21 20:14:51 +00:00
Removed LoopingCall from torrent.py
Having a LoopingCall for each torrent is expencive with a lot of torrents. The LoopingCall in torrent.py has been moved to torrentmanager.py which runs through all the torrents and calls cleanup_prev_status.
This commit is contained in:
parent
de3740fa70
commit
feaeee0379
3 changed files with 25 additions and 30 deletions
|
@ -124,8 +124,6 @@ class Torrent(object):
|
|||
# We use this to return dicts that only contain changes from the previous
|
||||
# {session_id: status_dict, ...}
|
||||
self.prev_status = {}
|
||||
self.prev_status_cleanup_loop = LoopingCall(self._cleanup_prev_status)
|
||||
self.prev_status_cleanup_loop.start(10)
|
||||
|
||||
# Set the libtorrent handle
|
||||
self.handle = handle
|
||||
|
@ -1017,7 +1015,7 @@ class Torrent(object):
|
|||
except OSError as (errno, strerror):
|
||||
log.debug("Cannot Remove Folder: %s (ErrNo %s)", strerror, errno)
|
||||
|
||||
def _cleanup_prev_status(self):
|
||||
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.
|
||||
|
|
|
@ -199,6 +199,7 @@ class TorrentManager(component.Component):
|
|||
self.save_state_timer = LoopingCall(self.save_state)
|
||||
self.save_resume_data_timer = LoopingCall(self.save_resume_data)
|
||||
self.save_all_resume_data_timer = LoopingCall(self.save_resume_data, self.torrents.keys())
|
||||
self.prev_status_cleanup_loop = LoopingCall(self.cleanup_torrents_prev_status)
|
||||
|
||||
def start(self):
|
||||
# Check for old temp file to verify safe shutdown
|
||||
|
@ -237,6 +238,7 @@ class TorrentManager(component.Component):
|
|||
self.save_resume_data_timer.start(190, False)
|
||||
# Force update for all resume data a bit less frequently
|
||||
self.save_all_resume_data_timer.start(900, False)
|
||||
self.prev_status_cleanup_loop.start(10)
|
||||
|
||||
def stop(self):
|
||||
# Stop timers
|
||||
|
@ -249,13 +251,13 @@ class TorrentManager(component.Component):
|
|||
if self.save_all_resume_data_timer.running:
|
||||
self.save_all_resume_data_timer.stop()
|
||||
|
||||
if self.prev_status_cleanup_loop.running:
|
||||
self.prev_status_cleanup_loop.stop()
|
||||
|
||||
# Save state on shutdown
|
||||
self.save_state()
|
||||
|
||||
self.session.pause()
|
||||
for key in self.torrents:
|
||||
# Stop the status cleanup LoopingCall here
|
||||
self.torrents[key].prev_status_cleanup_loop.stop()
|
||||
|
||||
def remove_temp_file(result):
|
||||
"""Remove the temp_file to signify successfully saved state"""
|
||||
|
@ -530,8 +532,7 @@ class TorrentManager(component.Component):
|
|||
return filedump
|
||||
|
||||
def remove(self, torrent_id, remove_data=False):
|
||||
"""
|
||||
Remove a torrent from the session.
|
||||
"""Remove torrent from the session
|
||||
|
||||
:param torrent_id: the torrent to remove
|
||||
:type torrent_id: string
|
||||
|
@ -574,9 +575,6 @@ class TorrentManager(component.Component):
|
|||
except OSError as ex:
|
||||
log.warning("Unable to remove copy torrent file: %s", ex)
|
||||
|
||||
# Stop the looping call
|
||||
self.torrents[torrent_id].prev_status_cleanup_loop.stop()
|
||||
|
||||
# Remove from set if it wasn't finished
|
||||
if not self.torrents[torrent_id].is_finished:
|
||||
try:
|
||||
|
@ -726,12 +724,12 @@ class TorrentManager(component.Component):
|
|||
return True
|
||||
|
||||
def save_resume_data(self, torrent_ids=None):
|
||||
"""
|
||||
Saves resume data for list of torrent_ids or for all torrents
|
||||
"""Saves resume data for list of torrent_ids or for all torrents
|
||||
needing resume data updated if torrent_ids is None
|
||||
|
||||
:returns: A Deferred whose callback will be invoked when save is complete
|
||||
:rtype: twisted.internet.defer.Deferred
|
||||
|
||||
"""
|
||||
if torrent_ids is None:
|
||||
torrent_ids = (t[0] for t in self.torrents.iteritems() if t[1].handle.need_save_resume_data())
|
||||
|
@ -758,9 +756,11 @@ class TorrentManager(component.Component):
|
|||
return DeferredList(deferreds).addBoth(on_all_resume_data_finished)
|
||||
|
||||
def load_resume_data_file(self):
|
||||
"""Loads the resume data from file for all the torrents
|
||||
"""Load the resume data from file for all torrents
|
||||
|
||||
:returns: resume_data
|
||||
:rtype: dict
|
||||
|
||||
"""
|
||||
filename = "torrents.fastresume"
|
||||
filepath = os.path.join(self.state_dir, filename)
|
||||
|
@ -786,9 +786,7 @@ class TorrentManager(component.Component):
|
|||
return resume_data
|
||||
|
||||
def save_resume_data_file(self):
|
||||
"""
|
||||
Saves the resume data file with the contents of self.resume_data.
|
||||
"""
|
||||
"""Saves the resume data file with the contents of self.resume_data"""
|
||||
filename = "torrents.fastresume"
|
||||
filepath = os.path.join(self.state_dir, filename)
|
||||
filepath_bak = filepath + ".bak"
|
||||
|
@ -850,6 +848,11 @@ class TorrentManager(component.Component):
|
|||
self.torrents[torrent_id].handle.queue_position_bottom()
|
||||
return True
|
||||
|
||||
def cleanup_torrents_prev_status(self):
|
||||
"""Run cleanup_prev_status for each registered torrent"""
|
||||
for torrent in self.torrents.iteritems():
|
||||
torrent[1].cleanup_prev_status()
|
||||
|
||||
def on_set_max_connections_per_torrent(self, key, value):
|
||||
"""Sets the per-torrent connection limit"""
|
||||
log.debug("max_connections_per_torrent set to %s...", value)
|
||||
|
@ -863,11 +866,13 @@ class TorrentManager(component.Component):
|
|||
self.torrents[key].set_max_upload_slots(value)
|
||||
|
||||
def on_set_max_upload_speed_per_torrent(self, key, value):
|
||||
"""Sets the per-torrent upload speed limit"""
|
||||
log.debug("max_upload_speed_per_torrent set to %s...", value)
|
||||
for key in self.torrents.keys():
|
||||
self.torrents[key].set_max_upload_speed(value)
|
||||
|
||||
def on_set_max_download_speed_per_torrent(self, key, value):
|
||||
"""Sets the per-torrent download speed limit"""
|
||||
log.debug("max_download_speed_per_torrent set to %s...", value)
|
||||
for key in self.torrents.keys():
|
||||
self.torrents[key].set_max_download_speed(value)
|
||||
|
@ -1155,9 +1160,7 @@ class TorrentManager(component.Component):
|
|||
self.handle_torrents_status_callback(self.torrents_status_requests.pop())
|
||||
|
||||
def separate_keys(self, keys, torrent_ids):
|
||||
"""Separates the input keys into keys for the Torrent class
|
||||
and keys for plugins.
|
||||
"""
|
||||
"""Separates the input keys into torrent class keys and plugins keys"""
|
||||
if self.torrents:
|
||||
for torrent_id in torrent_ids:
|
||||
if torrent_id in self.torrents:
|
||||
|
@ -1168,9 +1171,7 @@ class TorrentManager(component.Component):
|
|||
return [], []
|
||||
|
||||
def handle_torrents_status_callback(self, status_request):
|
||||
"""
|
||||
Builds the status dictionary with the values from the Torrent.
|
||||
"""
|
||||
"""Build the status dictionary with torrent values"""
|
||||
d, torrent_ids, keys, diff = status_request
|
||||
status_dict = {}.fromkeys(torrent_ids)
|
||||
torrent_keys, plugin_keys = self.separate_keys(keys, torrent_ids)
|
||||
|
@ -1187,10 +1188,9 @@ class TorrentManager(component.Component):
|
|||
d.callback((status_dict, plugin_keys))
|
||||
|
||||
def torrents_status_update(self, torrent_ids, keys, diff=False):
|
||||
"""
|
||||
returns status dict for the supplied torrent_ids async
|
||||
If the torrent states were updated recently (less than 1.5 seconds ago,
|
||||
post_torrent_updates is not called. Instead the cached state is used.
|
||||
"""Returns status dict for the supplied torrent_ids async
|
||||
|
||||
If torrent states updated recently post_torrent_updates is not called, cached state is used.
|
||||
|
||||
:param torrent_ids: the torrent IDs to get the status on
|
||||
:type torrent_ids: list of str
|
||||
|
|
|
@ -51,9 +51,6 @@ class TorrentTestCase(unittest.TestCase):
|
|||
return component.start()
|
||||
|
||||
def tearDown(self):
|
||||
if self.torrent:
|
||||
self.torrent.prev_status_cleanup_loop.stop()
|
||||
|
||||
deluge.core.torrent.component = self.original_component
|
||||
|
||||
def on_shutdown(result):
|
||||
|
|
Loading…
Add table
Reference in a new issue