Skip to content

Instantly share code, notes, and snippets.

@diimdeep diimdeep/export.js
Last active Aug 4, 2017

Embed
What would you like to do?
// В js крутится опрашивалка статуса. при старте она получает уникальный номер задачи и каждые 5
// (или сколько там настроишь setTimeout) секунд генерит запрос состояния с этим самым номером.
// Как только поллучает сигнал о том, что все выполнено, показывает статистику и перестает генерить запросы.
// крутится 2 цикла опроса. Один запускается реже -- он ждет выполнения очередного step,
// второй чаще -- он просто опрашивает состояние и обновляет прогрессбар.
(function ($) {
$.extend($.importexport.plugins, {
cml1c: {
data: {
direction: null,
upload_time: null
},
form: null,
ajax_pull: {},
progress: false,
handler: function (element) {
$('#s-cml1c-form').find('ul.tabs a[href$="\/map\/"]').addClass('js-invalidated');
var self = this;
self.progress = true;
self.form = $(element);
var data = self.form.serialize();
self.form.find('.errormsg').text('');
self.form.find(':input').attr('disabled', true);//:not([type="hidden"])
self.form.find(':submit').hide();
self.form.find('.progressbar .progressbar-inner').css('width', '0%');
self.form.find('.progressbar').show();
self.form.find('.js-cml1c-repeat').hide();
var url = $(element).attr('action');
$.ajax({
url: url,
data: data,
dataType: 'json',
type: 'post',
success: function (response) {
if (response.error) {
self.form.find(':input:visible').attr('disabled', false);
self.form.find(':submit').show();
self.form.find('.js-progressbar-container').hide();
self.form.find('.shop-ajax-status-loading').remove();
self.progress = false;
self.form.find('.errormsg').text(response.error);
} else {
self.form.find('.progressbar').attr('title', '0.00%');
self.form.find('.progressbar-description').text('0.00%');
self.form.find('.js-progressbar-container').show();
if (response.file) {
var $link = self.form.find('.plugin-cml1c-report .value a:first');
$link.attr('href', ('' + $link.attr('href')).replace(/&file=.*$/, '') + '&file=' + response.file);
}
self.ajax_pull[response.processId] = [];
self.ajax_pull[response.processId].push(setTimeout(function () {
$.wa.errorHandler = function (xhr) {
return !((xhr.status > 400) || (xhr.status == 0));
};
self.progressHandler(url, response.processId, response);
}, 1000));
self.ajax_pull[response.processId].push(setTimeout(function () {
self.progressHandler(url, response.processId);
}, 4000));
}
},
error: function () {
self.form.find(':input:visible').attr('disabled', false);
self.form.find(':submit').show();
self.form.find('.js-progressbar-container').hide();
self.form.find('.shop-ajax-status-loading').remove();
self.form.find('.progressbar').hide();
}
});
return false;
},
/**
*
* @param url
* @param processId
* @param {cml1cProgressResponse|cml1cWarningResponse|cml1cErrorResponse} response
*/
progressHandler: function (url, processId, response) {
// display progress
// if not completed do next iteration
if (this.progress) {
var self = this;
if (response && response.ready) {
$.wa.errorHandler = null;
self.progress = false;
var timer;
while (timer = self.ajax_pull[processId].pop()) {
if (timer) {
clearTimeout(timer);
}
}
self.form.find('.progressbar .progressbar-inner').css({
'width': '100%'
});
$.shop.trace('cleanup', response.processId);
if (response.file) {
var $link = self.form.find('.plugin-cml1c-report .value a:first');
$link.attr('href', ('' + $link.attr('href')).replace(/&file=.*$/, '') + '&file=' + response.file);
}
$.ajax({
url: url,
data: {
'processId': response.processId,
'direction': self.data.direction,
'cleanup': 1
},
dataType: 'json',
type: 'post',
success: function (response) {
// show statistic
$.shop.trace('report', response);
self.form.find('.plugin-cml1c-submit').hide();
self.form.find('.progressbar').hide();
self.form.find('.plugin-cml1c-report').show();
if (response) {
if (response.report) {
var $report = self.form.find('.plugin-cml1c-report .value:first');
if (!response.report_id || ($report.data('report-id') != response.report_id)) {
if (response.report_id) {
$report.data('report-id', response.report_id);
}
$report.html(response.report);
}
}
self.showRepeat(response.configure);
}
}
});
} else if (response && response.error) {
self.form.find(':input:visible').attr('disabled', false);
self.form.find(':submit').show();
self.form.find('.js-progressbar-container').hide();
self.form.find('.shop-ajax-status-loading').remove();
self.form.find('.progressbar').hide();
self.form.find('.errormsg').text(response.error);
} else {
var $description;
if (response && (typeof(response.progress) != 'undefined')) {
var $bar = self.form.find('.progressbar .progressbar-inner');
var progress = parseFloat(('' + response.progress).replace(/,/, '.'));
$bar.animate({
'width': progress + '%'
});
self.debug.memory = Math.max(0.0, self.debug.memory, parseFloat(response.memory) || 0);
self.debug.memory_avg = Math.max(0.0, self.debug.memory_avg, parseFloat(response.memory_avg) || 0);
var title = 'Memory usage: ' + self.debug.memory_avg + '/' + self.debug.memory + 'MB';
var message = response.progress + ' ' + (1 + parseInt(response.stage_num)) + '/' + response.stage_count + ' ' + response.stage_name;
$bar.parents('.progressbar').attr('title', message);
$description = self.form.find('.progressbar-description');
$description.text(message);
$description.attr('title', title);
}
if (response && (typeof(response.warning) != 'undefined')) {
$description = self.form.find('.progressbar-description');
$description.append('<i class="icon16 exclamation"></i><p>' + response.warning + '</p>');
}
var ajax_url = url;
var id = processId;
self.ajax_pull[id].push(setTimeout(function () {
$.ajax({
url: ajax_url,
data: {
'processId': id,
'direction': self.data.direction
},
dataType: 'json',
type: 'post',
success: function (response) {
self.progressHandler(url, response ? response.processId || id : id, response);
},
error: function () {
self.progressHandler(url, id, null);
}
});
}, 1000));
}
}
}
}
});
})(jQuery);
// https://developers.webasyst.ru/cookbook/basics/classes/waLongActionController/
// Каждый запрос браузерного скрипта приводит к запуску отдельного процесса на сервере.
// Из всех процессов, порожденных контроллером, один (self::TYPE_RUNNER) выполняет полезную работу —
// либо до ее полного завершения, либо до его преждевременного прекращения из-за
// срабатывания ограничения max_execution_time, а остальные (self::TYPE_MESSENGER)
// отправляют в браузер информацию о текущем статусе выполнения операции.
finish
//Определяет, можно ли очистить связанные с выполнением операции временные данные (файлы) после ее завершения.
info
//Возвращает в браузер информацию о статусе выполнения операции.
init
//Инициализация значений, которые могут использоваться в работе контроллера.
isDone
//Определяет факт завершения операции.
step
//Логика выполнения отдельного фрагмента операции.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.