Refactor progress bars somewhat to allow file-based sessions
hoping this solves issue of Apache restart at end of upgrade
This commit is contained in:
parent
f203f2c377
commit
f46e20c119
|
@ -1,4 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8; -*-
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
|
@ -26,15 +26,21 @@ Progress Indicator
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from beaker.session import Session
|
from beaker.session import Session
|
||||||
|
|
||||||
|
|
||||||
def get_progress_session(request, key):
|
def get_progress_session(request, key, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create/get a Beaker session object, to be used for progress.
|
Create/get a Beaker session object, to be used for progress.
|
||||||
"""
|
"""
|
||||||
id = '{0}.progress.{1}'.format(request.session.id, key)
|
id = '{}.progress.{}'.format(request.session.id, key)
|
||||||
return Session(request, id, use_cookies=False)
|
kwargs['use_cookies'] = False
|
||||||
|
if kwargs.get('type') == 'file':
|
||||||
|
kwargs['data_dir'] = os.path.join(request.rattail_config.appdir(), 'sessions')
|
||||||
|
session = Session(request, id, **kwargs)
|
||||||
|
return session
|
||||||
|
|
||||||
|
|
||||||
class SessionProgress(object):
|
class SessionProgress(object):
|
||||||
|
@ -46,8 +52,9 @@ class SessionProgress(object):
|
||||||
for display to the user.
|
for display to the user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, request, key):
|
def __init__(self, request, key, session_type=None):
|
||||||
self.session = get_progress_session(request, key)
|
self.key = key
|
||||||
|
self.session = get_progress_session(request, key, type=session_type)
|
||||||
self.canceled = False
|
self.canceled = False
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## -*- coding: utf-8 -*-
|
## -*- coding: utf-8; -*-
|
||||||
<%namespace file="tailbone:templates/base.mako" import="core_javascript" />
|
<%namespace file="tailbone:templates/base.mako" import="core_javascript" />
|
||||||
<%namespace file="/base.mako" import="jquery_theme" />
|
<%namespace file="/base.mako" import="jquery_theme" />
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
|
|
||||||
function update_progress() {
|
function update_progress() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '${url('progress', key=key)}',
|
url: '${url('progress', key=progress.key)}?sessiontype=${progress.session.type}',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
location.href = '${cancel_url}';
|
location.href = '${cancel_url}';
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
clearInterval(updater);
|
clearInterval(updater);
|
||||||
$(this).button('disable').button('option', 'label', "Canceling, please wait...");
|
$(this).button('disable').button('option', 'label', "Canceling, please wait...");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '${url('progress.cancel', key=key)}',
|
url: '${url('progress', key=progress.key)}?sessiontype=${progress.session.type}',
|
||||||
data: {
|
data: {
|
||||||
'cancel_msg': '${cancel_msg}',
|
'cancel_msg': '${cancel_msg}',
|
||||||
},
|
},
|
||||||
|
|
|
@ -506,14 +506,13 @@ class BatchMasterView(MasterView):
|
||||||
permission_prefix = self.get_permission_prefix()
|
permission_prefix = self.get_permission_prefix()
|
||||||
|
|
||||||
# showing progress requires a separate thread; start that first
|
# showing progress requires a separate thread; start that first
|
||||||
progress_key = '{}.prefill'.format(route_prefix)
|
key = '{}.prefill'.format(route_prefix)
|
||||||
progress = SessionProgress(self.request, progress_key)
|
progress = SessionProgress(self.request, key)
|
||||||
thread = Thread(target=self.prefill_thread, args=(batch.uuid, progress))
|
thread = Thread(target=self.prefill_thread, args=(batch.uuid, progress))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
# Send user to progress page.
|
# Send user to progress page.
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'key': progress_key,
|
|
||||||
'cancel_url': self.get_action_url('view', batch),
|
'cancel_url': self.get_action_url('view', batch),
|
||||||
'cancel_msg': "Batch prefill was canceled.",
|
'cancel_msg': "Batch prefill was canceled.",
|
||||||
}
|
}
|
||||||
|
@ -522,7 +521,7 @@ class BatchMasterView(MasterView):
|
||||||
if not self.request.has_perm('{}.view'.format(permission_prefix)):
|
if not self.request.has_perm('{}.view'.format(permission_prefix)):
|
||||||
kwargs['cancel_url'] = self.request.route_url('{}.create'.format(route_prefix))
|
kwargs['cancel_url'] = self.request.route_url('{}.create'.format(route_prefix))
|
||||||
|
|
||||||
return self.render_progress(kwargs)
|
return self.render_progress(progress, kwargs)
|
||||||
|
|
||||||
def prefill_thread(self, batch_uuid, progress):
|
def prefill_thread(self, batch_uuid, progress):
|
||||||
"""
|
"""
|
||||||
|
@ -601,7 +600,6 @@ class BatchMasterView(MasterView):
|
||||||
|
|
||||||
# Send user to progress page.
|
# Send user to progress page.
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'key': key,
|
|
||||||
'cancel_url': self.get_action_url('view', batch),
|
'cancel_url': self.get_action_url('view', batch),
|
||||||
'cancel_msg': "Batch refresh was canceled.",
|
'cancel_msg': "Batch refresh was canceled.",
|
||||||
}
|
}
|
||||||
|
@ -610,7 +608,7 @@ class BatchMasterView(MasterView):
|
||||||
if not self.request.has_perm('{}.view'.format(permission_prefix)):
|
if not self.request.has_perm('{}.view'.format(permission_prefix)):
|
||||||
kwargs['cancel_url'] = self.request.route_url('{}.create'.format(route_prefix))
|
kwargs['cancel_url'] = self.request.route_url('{}.create'.format(route_prefix))
|
||||||
|
|
||||||
return self.render_progress(kwargs)
|
return self.render_progress(progress, kwargs)
|
||||||
|
|
||||||
def refresh_data(self, session, batch, cognizer=None, progress=None):
|
def refresh_data(self, session, batch, cognizer=None, progress=None):
|
||||||
"""
|
"""
|
||||||
|
@ -764,12 +762,12 @@ class BatchMasterView(MasterView):
|
||||||
self.request.session['batch.{}.execute_option.{}'.format(batch.batch_key, key)] = unicode(value)
|
self.request.session['batch.{}.execute_option.{}'.format(batch.batch_key, key)] = unicode(value)
|
||||||
|
|
||||||
key = '{}.execute'.format(self.model_class.__tablename__)
|
key = '{}.execute'.format(self.model_class.__tablename__)
|
||||||
kwargs['progress'] = SessionProgress(self.request, key)
|
progress = SessionProgress(self.request, key)
|
||||||
|
kwargs['progress'] = progress
|
||||||
thread = Thread(target=self.execute_thread, args=(batch.uuid, self.request.user.uuid), kwargs=kwargs)
|
thread = Thread(target=self.execute_thread, args=(batch.uuid, self.request.user.uuid), kwargs=kwargs)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
return self.render_progress({
|
return self.render_progress(progress, {
|
||||||
'key': key,
|
|
||||||
'cancel_url': self.get_action_url('view', batch),
|
'cancel_url': self.get_action_url('view', batch),
|
||||||
'cancel_msg': "Batch execution was canceled.",
|
'cancel_msg': "Batch execution was canceled.",
|
||||||
})
|
})
|
||||||
|
@ -850,12 +848,12 @@ class BatchMasterView(MasterView):
|
||||||
|
|
||||||
key = '{}.execute_results'.format(self.model_class.__tablename__)
|
key = '{}.execute_results'.format(self.model_class.__tablename__)
|
||||||
batches = self.get_effective_data()
|
batches = self.get_effective_data()
|
||||||
kwargs['progress'] = SessionProgress(self.request, key)
|
progress = SessionProgress(self.request, key)
|
||||||
|
kwargs['progress'] = progress
|
||||||
thread = Thread(target=self.execute_results_thread, args=(batches, self.request.user.uuid), kwargs=kwargs)
|
thread = Thread(target=self.execute_results_thread, args=(batches, self.request.user.uuid), kwargs=kwargs)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
return self.render_progress({
|
return self.render_progress(progress, {
|
||||||
'key': key,
|
|
||||||
'cancel_url': self.get_index_url(),
|
'cancel_url': self.get_index_url(),
|
||||||
'cancel_msg': "Batch execution was canceled",
|
'cancel_msg': "Batch execution was canceled",
|
||||||
})
|
})
|
||||||
|
|
|
@ -90,10 +90,11 @@ class View(object):
|
||||||
def progress_loop(self, func, items, factory, *args, **kwargs):
|
def progress_loop(self, func, items, factory, *args, **kwargs):
|
||||||
return progress_loop(func, items, factory, *args, **kwargs)
|
return progress_loop(func, items, factory, *args, **kwargs)
|
||||||
|
|
||||||
def render_progress(self, kwargs):
|
def render_progress(self, progress, kwargs):
|
||||||
"""
|
"""
|
||||||
Render the progress page, with given kwargs as context.
|
Render the progress page, with given kwargs as context.
|
||||||
"""
|
"""
|
||||||
|
kwargs['progress'] = progress
|
||||||
return render_to_response('/progress.mako', kwargs, request=self.request)
|
return render_to_response('/progress.mako', kwargs, request=self.request)
|
||||||
|
|
||||||
def file_response(self, path):
|
def file_response(self, path):
|
||||||
|
|
|
@ -741,13 +741,12 @@ class MasterView(View):
|
||||||
Delete all records matching the current grid query
|
Delete all records matching the current grid query
|
||||||
"""
|
"""
|
||||||
if self.request.method == 'POST':
|
if self.request.method == 'POST':
|
||||||
key = '{}.bulk_delete'.format(self.model_class.__tablename__)
|
|
||||||
objects = self.get_effective_data()
|
objects = self.get_effective_data()
|
||||||
|
key = '{}.bulk_delete'.format(self.model_class.__tablename__)
|
||||||
progress = SessionProgress(self.request, key)
|
progress = SessionProgress(self.request, key)
|
||||||
thread = Thread(target=self.bulk_delete_thread, args=(objects, progress))
|
thread = Thread(target=self.bulk_delete_thread, args=(objects, progress))
|
||||||
thread.start()
|
thread.start()
|
||||||
return self.render_progress({
|
return self.render_progress(progress, {
|
||||||
'key': key,
|
|
||||||
'cancel_url': self.get_index_url(),
|
'cancel_url': self.get_index_url(),
|
||||||
'cancel_msg': "Bulk deletion was canceled",
|
'cancel_msg': "Bulk deletion was canceled",
|
||||||
})
|
})
|
||||||
|
@ -804,13 +803,12 @@ class MasterView(View):
|
||||||
model_title = self.get_model_title()
|
model_title = self.get_model_title()
|
||||||
if self.request.method == 'POST':
|
if self.request.method == 'POST':
|
||||||
|
|
||||||
key = '{}.execute'.format(self.get_grid_key())
|
progress = self.make_execute_progress()
|
||||||
kwargs = {'progress': SessionProgress(self.request, key)}
|
kwargs = {'progress': progress}
|
||||||
thread = Thread(target=self.execute_thread, args=(obj.uuid, self.request.user.uuid), kwargs=kwargs)
|
thread = Thread(target=self.execute_thread, args=(obj.uuid, self.request.user.uuid), kwargs=kwargs)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
return self.render_progress({
|
return self.render_progress(progress, {
|
||||||
'key': key,
|
|
||||||
'cancel_url': self.get_action_url('view', obj),
|
'cancel_url': self.get_action_url('view', obj),
|
||||||
'cancel_msg': "{} execution was canceled".format(model_title),
|
'cancel_msg': "{} execution was canceled".format(model_title),
|
||||||
})
|
})
|
||||||
|
@ -818,6 +816,10 @@ class MasterView(View):
|
||||||
self.request.session.flash("Sorry, you must POST to execute a {}.".format(model_title), 'error')
|
self.request.session.flash("Sorry, you must POST to execute a {}.".format(model_title), 'error')
|
||||||
return self.redirect(self.get_action_url('view', obj))
|
return self.redirect(self.get_action_url('view', obj))
|
||||||
|
|
||||||
|
def make_execute_progress(self):
|
||||||
|
key = '{}.execute'.format(self.get_grid_key())
|
||||||
|
return SessionProgress(self.request, key)
|
||||||
|
|
||||||
def execute_thread(self, uuid, user_uuid, progress=None, **kwargs):
|
def execute_thread(self, uuid, user_uuid, progress=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Thread target for executing an object.
|
Thread target for executing an object.
|
||||||
|
|
|
@ -489,13 +489,11 @@ class ProductsView(MasterView):
|
||||||
handler = get_batch_handler(self.rattail_config, batch_key,
|
handler = get_batch_handler(self.rattail_config, batch_key,
|
||||||
default=supported[batch_key].spec)
|
default=supported[batch_key].spec)
|
||||||
products = self.get_effective_data()
|
products = self.get_effective_data()
|
||||||
progress_key = 'products.batch'
|
progress = SessionProgress(self.request, 'products.batch')
|
||||||
progress = SessionProgress(self.request, progress_key)
|
|
||||||
thread = Thread(target=self.make_batch_thread,
|
thread = Thread(target=self.make_batch_thread,
|
||||||
args=(handler, self.request.user.uuid, products, params, progress))
|
args=(handler, self.request.user.uuid, products, params, progress))
|
||||||
thread.start()
|
thread.start()
|
||||||
return self.render_progress({
|
return self.render_progress(progress, {
|
||||||
'key': progress_key,
|
|
||||||
'cancel_url': self.get_index_url(),
|
'cancel_url': self.get_index_url(),
|
||||||
'cancel_msg': "Batch creation was canceled.",
|
'cancel_msg': "Batch creation was canceled.",
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,17 +20,18 @@
|
||||||
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
# Rattail. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Progress Views
|
Progress Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ..progress import get_progress_session
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
|
from tailbone.progress import get_progress_session
|
||||||
|
|
||||||
|
|
||||||
def progress(request):
|
def progress(request):
|
||||||
key = request.matchdict['key']
|
key = request.matchdict['key']
|
||||||
session = get_progress_session(request, key)
|
session = get_progress_session(request, key, type=request.GET.get('sessiontype'))
|
||||||
if session.get('complete'):
|
if session.get('complete'):
|
||||||
msg = session.get('success_msg')
|
msg = session.get('success_msg')
|
||||||
if msg:
|
if msg:
|
||||||
|
|
|
@ -183,6 +183,10 @@ class UpgradeView(MasterView):
|
||||||
def before_create_flush(self, upgrade):
|
def before_create_flush(self, upgrade):
|
||||||
upgrade.created_by = self.request.user
|
upgrade.created_by = self.request.user
|
||||||
|
|
||||||
|
def make_execute_progress(self):
|
||||||
|
key = '{}.execute'.format(self.get_grid_key())
|
||||||
|
return SessionProgress(self.request, key, session_type='file')
|
||||||
|
|
||||||
def execute_instance(self, upgrade, user, **kwargs):
|
def execute_instance(self, upgrade, user, **kwargs):
|
||||||
session = orm.object_session(upgrade)
|
session = orm.object_session(upgrade)
|
||||||
upgrade.executing = True
|
upgrade.executing = True
|
||||||
|
|
Loading…
Reference in a new issue