Jobs dialog:Allow stopping of waiting jobs and add Stop all jobs button

This commit is contained in:
Kovid Goyal 2009-09-12 12:52:27 -06:00
parent b759adcee6
commit 8323e8b8b2
5 changed files with 40 additions and 12 deletions

View File

@ -14,7 +14,7 @@
<string>Active Jobs</string>
</property>
<property name="windowIcon">
<iconset resource="../../../../resources/images.qrc">
<iconset resource="../../../work/calibre/resources/images.qrc">
<normaloff>:/images/jobs.svg</normaloff>:/images/jobs.svg</iconset>
</property>
<layout class="QVBoxLayout">
@ -57,6 +57,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stop_all_jobs_button">
<property name="text">
<string>Stop &amp;all jobs</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@ -67,7 +74,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="../../../../resources/images.qrc"/>
<include location="../../../work/calibre/resources/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -193,6 +193,12 @@ class JobManager(QAbstractTableModel):
_('Job has already run')).exec_()
self.server.kill_job(job)
def kill_all_jobs(self):
for job in self.jobs:
if isinstance(job, DeviceJob) or job.duration is not None:
continue
self.server.kill_job(job)
def terminate_all_jobs(self):
self.server.killall()
@ -230,6 +236,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
self.kill_job)
self.connect(self.details_button, SIGNAL('clicked()'),
self.show_details)
self.connect(self.stop_all_jobs_button, SIGNAL('clicked()'),
self.kill_all_jobs)
self.connect(self, SIGNAL('kill_job(int, PyQt_PyObject)'),
self.jobs_view.model().kill_job)
self.pb_delegate = ProgressBarDelegate(self)
@ -247,7 +255,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
self.jobs_view.show_details(index)
return
def kill_all_jobs(self):
self.model.kill_all_jobs()
def closeEvent(self, e):
self.jobs_view.write_settings()

View File

@ -156,8 +156,6 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
dtitle = repr(mi.title)
desc = _('Convert book %d of %d (%s)') % (i + 1, total, dtitle)
desc = _('Convert book %d of %d (%s)') % (i + 1, total, repr(mi.title))
args = [in_file, out_file.name, lrecs]
temp_files.append(out_file)
jobs.append(('gui_convert', args, desc, d.output_format.upper(), book_id, temp_files))
@ -178,6 +176,7 @@ def convert_bulk_ebook(parent, db, book_ids, out_format=None):
'source format was found.') % (len(res), total),
msg).exec_()
jobs.reverse()
return jobs, changed, bad
def fetch_scheduled_recipe(recipe, script):

View File

@ -30,6 +30,7 @@ class BaseJob(object):
self.done2 = None
self.killed = False
self.failed = False
self.kill_on_start = False
self.start_time = None
self.result = None
self.duration = None

View File

@ -170,6 +170,7 @@ class Server(Thread):
except Empty:
pass
# Get notifications from worker process
for worker in self.workers:
while True:
try:
@ -179,6 +180,7 @@ class Server(Thread):
except Empty:
break
# Remove finished jobs
for worker in [w for w in self.workers if not w.is_alive]:
self.workers.remove(worker)
job = worker.job
@ -191,19 +193,27 @@ class Server(Thread):
job.duration = time.time() - job.start_time
self.changed_jobs_queue.put(job)
# Start new workers
if len(self.pool) + len(self.workers) < self.pool_size:
try:
self.pool.append(self.launch_worker())
except Exception:
pass
# Start waiting jobs
if len(self.pool) > 0 and len(self.waiting_jobs) > 0:
job = self.waiting_jobs.pop()
worker = self.pool.pop()
job.start_time = time.time()
worker.start_job(job)
self.workers.append(worker)
job.log_path = worker.log_path
if job.kill_on_start:
job.duration = 0.0
job.returncode = 1
job.killed = job.failed = True
job.result = None
else:
worker = self.pool.pop()
worker.start_job(job)
self.workers.append(worker)
job.log_path = worker.log_path
self.changed_jobs_queue.put(job)
while True:
@ -217,11 +227,13 @@ class Server(Thread):
self.kill_queue.put(job)
def killall(self):
for job in self.workers:
self.kill_queue.put(job)
for worker in self.workers:
self.kill_queue.put(worker.job)
def _kill_job(self, job):
if job.start_time is None: return
if job.start_time is None:
job.kill_on_start = True
return
for worker in self.workers:
if job is worker.job:
worker.kill()