Add progress indicator to batch execution.

Also disable Execute button immediately when clicked.
This commit is contained in:
Lance Edgar 2015-08-19 18:49:09 -05:00
parent e01e323d3e
commit 6c5eec7981
2 changed files with 80 additions and 5 deletions

View file

@ -1,3 +1,27 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8 -*-
<%inherit file="/batch/crud.mako" /> <%inherit file="/batch/crud.mako" />
<%def name="head_tags()">
${parent.head_tags()}
<script type="text/javascript">
$(function() {
$('#execute-batch').click(function() {
$(this).button('option', 'label', "Executing, please wait...").button('disable');
location.href = '${url('{0}.execute'.format(route_prefix), uuid=batch.uuid)}';
});
});
</script>
</%def>
<%def name="buttons()">
<div class="buttons">
% if not form.readonly and batch.refreshable:
${h.submit('save-refresh', "Save & Refresh Data")}
% endif
% if not batch.executed and request.has_perm('{0}.execute'.format(permission_prefix)):
<button type="button" id="execute-batch"${'' if execute_enabled else ' disabled="disabled"'}>${execute_title}</button>
% endif
</div>
</%def>
${parent.body()} ${parent.body()}

View file

@ -647,12 +647,63 @@ class BatchCrud(BaseCrud):
return self.request.route_url('{0}.refresh'.format(self.route_prefix), uuid=uuid) return self.request.route_url('{0}.refresh'.format(self.route_prefix), uuid=uuid)
def execute(self): def execute(self):
"""
Execute a batch. Starts a separate thread for the execution, and
displays a progress indicator page.
"""
batch = self.current_batch() batch = self.current_batch()
if self.handler.execute(batch):
batch.executed = datetime.datetime.utcnow() key = '{0}.execute'.format(self.batch_class.__tablename__)
batch.executed_by = self.request.user progress = SessionProgress(self.request, key)
self.request.session.flash("Batch was executed successfully.") thread = Thread(target=self.execute_thread, args=(batch.uuid, progress))
return HTTPFound(location=self.view_url(batch.uuid)) thread.start()
kwargs = {
'key': key,
'cancel_url': self.view_url(batch.uuid),
'cancel_msg': "Batch execution was canceled.",
}
return render_to_response('/progress.mako', kwargs, request=self.request)
def execute_thread(self, batch_uuid, progress=None):
"""
Thread target for executing a batch with progress indicator.
"""
# Execute the batch, with progress. Note that we must use the rattail
# session here; can't use tailbone because it has web request
# transaction binding etc.
session = RatSession()
batch = session.query(self.batch_class).get(batch_uuid)
try:
result = self.handler.execute(batch, progress=progress)
# If anything goes wrong, rollback and log the error etc.
except Exception as error:
session.rollback()
log.exception("execution failed for batch: {0}".format(batch))
session.close()
if progress:
progress.session.load()
progress.session['error'] = True
progress.session['error_msg'] = "Batch execution failed: {0}".format(error)
progress.session.save()
# If no error, check result flag (false means user canceled).
else:
if result:
batch.executed = datetime.datetime.utcnow()
batch.executed_by = self.request.user
session.commit()
else:
session.rollback()
session.refresh(batch)
session.close()
if progress:
progress.session.load()
progress.session['complete'] = True
progress.session['success_url'] = self.view_url(batch.uuid)
progress.session.save()
class FileBatchCrud(BatchCrud): class FileBatchCrud(BatchCrud):