#1117, #1137: fix re-introduced race queuing tasks

This commit is contained in:
blushingpenguin 2021-08-31 14:37:36 +01:00
parent 68195acc00
commit 8760b6d315
4 changed files with 34 additions and 21 deletions

View File

@ -539,9 +539,9 @@ class DownloadTask(object):
The same thing works for failed downloads ("notify_as_failed()").
"""
# Possible states this download task can be in
STATUS_MESSAGE = (_('Queued'), _('Downloading'),
STATUS_MESSAGE = (_('Queued'), _('Queued'), _('Downloading'),
_('Finished'), _('Failed'), _('Cancelling'), _('Cancelled'), _('Pausing'), _('Paused'))
(QUEUED, DOWNLOADING, DONE, FAILED, CANCELLING, CANCELLED, PAUSING, PAUSED) = list(range(8))
(NEW, QUEUED, DOWNLOADING, DONE, FAILED, CANCELLING, CANCELLED, PAUSING, PAUSED) = list(range(9))
# Wheter this task represents a file download or a device sync operation
ACTIVITY_DOWNLOAD, ACTIVITY_SYNCHRONIZE = list(range(2))
@ -621,7 +621,7 @@ class DownloadTask(object):
def __init__(self, episode, config, downloader=None):
assert episode.download_task is None
self.__lock = threading.RLock()
self.__status = DownloadTask.QUEUED
self.__status = DownloadTask.NEW
self.__activity = DownloadTask.ACTIVITY_DOWNLOAD
self.__status_changed = True
self.__episode = episode
@ -765,15 +765,20 @@ class DownloadTask(object):
self.__start_time = 0
self.__start_blocks = 0
# If the download has already been cancelled, skip it
# If the download has already been cancelled/paused, skip it
with self:
if self.status == DownloadTask.CANCELLING:
self.status = DownloadTask.CANCELLED
util.delete_file(self.tempname)
self.progress = 0.0
self.speed = 0.0
self.recycle()
return False
if self.status == DownloadTask.PAUSING:
self.status = DownloadTask.PAUSED
return False
# We only start this download if its status is queued
if self.status != DownloadTask.QUEUED:
return False

View File

@ -163,13 +163,14 @@ class DownloadStatusModel:
self.request_update(iter, task)
def register_task(self, task):
self.work_queue.add_task(task)
# self.work_queue.add_task(task)
util.idle_add(self.__add_new_task, task)
def queue_task(self, task):
with task:
task.status = download.DownloadTask.QUEUED
self.work_queue.add_task(task)
if task.status in (task.NEW, task.FAILED, task.CANCELLED, task.PAUSED):
task.status = task.QUEUED
self.work_queue.add_task(task)
def tell_all_tasks_to_quit(self):
for row in self.list:

View File

@ -3062,14 +3062,15 @@ class gPodder(BuilderWidget, dbus.service.Object):
def download_episode_list(self, episodes, add_paused=False, force_start=False, downloader=None):
def queue_tasks(tasks, queued_existing_task):
for task in tasks:
if add_paused:
task.status = task.PAUSED
else:
self.mygpo_client.on_download([task.episode])
if force_start:
self.download_queue_manager.force_start_task(task)
with task:
if add_paused:
task.status = task.PAUSED
else:
self.download_queue_manager.queue_task(task)
self.mygpo_client.on_download([task.episode])
if force_start:
self.download_queue_manager.force_start_task(task)
else:
self.download_queue_manager.queue_task(task)
if tasks or queued_existing_task:
self.set_download_list_state(gPodderSyncUI.DL_ONEOFF)
# Flush updated episode status
@ -3128,7 +3129,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
for task in tasks:
with task:
if task.status in (task.QUEUED, task.DOWNLOADING):
if task.status in (task.NEW, task.QUEUED, task.DOWNLOADING):
task.status = task.CANCELLING
elif task.status == task.PAUSED:
task.status = task.CANCELLED

View File

@ -27,6 +27,7 @@ import calendar
import glob
import logging
import os.path
from re import S
import threading
import time
from urllib.parse import urlparse
@ -230,7 +231,7 @@ class Device(services.ObservableService):
# XXX: need to check if track is added properly?
sync_task = SyncTask(track)
sync_task.status = sync_task.QUEUED
sync_task.status = sync_task.NEW
sync_task.device = self
# New Task, we must wait on the GTK Loop
self.download_status_model.register_task(sync_task)
@ -697,9 +698,9 @@ class SyncTask(download.DownloadTask):
# An object representing the synchronization task of an episode
# Possible states this sync task can be in
STATUS_MESSAGE = (_('Queued'), _('Downloading'),
STATUS_MESSAGE = (_('Queued'), _('Queued'), _('Downloading'),
_('Finished'), _('Failed'), _('Cancelling'), _('Cancelled'), _('Pausing'), _('Paused'))
(QUEUED, DOWNLOADING, DONE, FAILED, CANCELLING, CANCELLED, PAUSING, PAUSED) = list(range(8))
(NEW, QUEUED, DOWNLOADING, DONE, FAILED, CANCELLING, CANCELLED, PAUSING, PAUSED) = list(range(9))
def __str__(self):
return self.__episode.title
@ -761,7 +762,7 @@ class SyncTask(download.DownloadTask):
def __init__(self, episode):
self.__lock = threading.RLock()
self.__status = SyncTask.QUEUED
self.__status = SyncTask.NEW
self.__activity = SyncTask.ACTIVITY_SYNCHRONIZE
self.__status_changed = True
self.__episode = episode
@ -840,11 +841,16 @@ class SyncTask(download.DownloadTask):
self.__start_time = 0
self.__start_blocks = 0
# If the download has already been cancelled, skip it
if self.status == SyncTask.CANCELLED:
# If the download has already been cancelled/paused, skip it
if self.status == SyncTask.CANCELLING:
util.delete_file(self.tempname)
self.progress = 0.0
self.speed = 0.0
self.status = SyncTask.CANCELLED
return False
if self.status == SyncTask.PAUSING:
self.status = SyncTask.PAUSED
return False
with self: