[fixes] wiring exections for async requests

This commit is contained in:
Rushabh Mehta 2015-07-27 18:22:29 +05:30
parent 5b84651a54
commit 3932cecf85
7 changed files with 117 additions and 97 deletions

View file

@ -83,3 +83,5 @@ frappe.patches.v5_0.modify_session
frappe.patches.v5_0.expire_old_scheduler_logs
execute:frappe.permissions.reset_perms("DocType")
execute:frappe.db.sql("delete from `tabProperty Setter` where `property` = 'idx'")
frappe.patches.v6_0.make_task_log_folder

View file

View file

@ -0,0 +1,6 @@
import frappe.utils, os
def execute():
path = frappe.utils.get_site_path('task-logs')
if not os.path.exists(path):
os.makedirs(path)

View file

@ -1,111 +1,114 @@
frappe.socket = {
open_tasks: {},
open_tasks: {},
init: function() {
if (frappe.boot.no_async) {
return;
}
var socketio_server = frappe.boot.dev_server? '//' + document.domain + ':3000' : '//' + document.domain + ':' + window.location.port;
frappe.socket.socket = io.connect(socketio_server);
frappe.socket.socket.on('msgprint', function(message) {
frappe.msgprint(message)
});
var socketio_server = frappe.boot.dev_server? '//' + document.domain + ':3000' : '//' + document.domain + ':' + window.location.port;
frappe.socket.socket = io.connect(socketio_server);
frappe.socket.socket.on('msgprint', function(message) {
frappe.msgprint(message)
});
frappe.socket.setup_listeners();
frappe.socket.setup_reconnect();
$(document).on('form-load', function(e, frm) {
frappe.socket.doc_subscribe(frm.doctype, frm.docname);
});
frappe.socket.setup_listeners();
frappe.socket.setup_reconnect();
$(document).on('form-load', function(e, frm) {
frappe.socket.doc_subscribe(frm.doctype, frm.docname);
});
$(document).on('form-unload', function(e, frm) {
frappe.socket.doc_unsubscribe(frm.doctype, frm.docname);
});
},
subscribe: function(task_id, opts) {
frappe.socket.socket.emit('task_subscribe', task_id);
frappe.socket.socket.emit('progress_subscribe', task_id);
$(document).on('form-unload', function(e, frm) {
frappe.socket.doc_unsubscribe(frm.doctype, frm.docname);
});
},
subscribe: function(task_id, opts) {
frappe.socket.socket.emit('task_subscribe', task_id);
frappe.socket.socket.emit('progress_subscribe', task_id);
frappe.socket.open_tasks[task_id] = opts;
},
frappe.socket.open_tasks[task_id] = opts;
},
doc_subscribe: function(doctype, docname) {
frappe.socket.socket.emit('doc_subscribe', doctype, docname);
frappe.socket.open_doc = {doctype: doctype, docname: docname};
},
},
doc_unsubscribe: function(doctype, docname) {
frappe.socket.socket.emit('doc_unsubscribe', doctype, docname);
frappe.socket.open_doc = null;
},
setup_listeners: function() {
frappe.socket.socket.on('task_status_change', function(data) {
if(data.status==="Running") {
frappe.socket.process_response(data, "running");
} else {
// failed or finished
frappe.socket.process_response(data, "callback");
// delete frappe.socket.open_tasks[data.task_id];
}
});
frappe.socket.socket.on('task_progress', function(data) {
frappe.socket.process_response(data, "progress");
});
frappe.socket.socket.on('new_comment', function(comment) {
if (frappe.model.docinfo[comment.comment_doctype] && frappe.model.docinfo[comment.comment_doctype][comment.comment_docname]) {
var comments = frappe.model.docinfo[comment.comment_doctype][comment.comment_docname].comments
var comment_exists = !!$.map(comments, function(x) { return x.name == comment.name? true : undefined}).length
if (!comment_exists) {
frappe.model.docinfo[comment.comment_doctype][comment.comment_docname].comments = comments.concat([comment]);
}
}
if (cur_frm.doctype === comment.comment_doctype && cur_frm.docname === comment.comment_docname) {
cur_frm.comments.refresh();
}
});
frappe.socket.socket.on('new_message', function(comment) {
frappe.utils.notify(__("Message from {0}", [comment.comment_by_fullname]), comment.comment);
if ($(cur_page.page).data('page-route') === 'messages') {
var current_contact = $(cur_page.page).find('[data-contact]').data('contact');
var on_broadcast_page = current_contact === user;
if (current_contact == comment.owner || (on_broadcast_page && comment.broadcast)) {
var $row = $('<div class="list-row"/>');
frappe.desk.pages.messages.list.data.unshift(comment);
frappe.desk.pages.messages.list.render_row($row, comment);
frappe.desk.pages.messages.list.parent.prepend($row);
}
}
else {
}
});
},
setup_listeners: function() {
frappe.socket.socket.on('task_status_change', function(data) {
if(data.status==="Running") {
frappe.socket.process_response(data, "running");
} else {
// failed or finished
frappe.socket.process_response(data, "callback");
// delete frappe.socket.open_tasks[data.task_id];
}
});
frappe.socket.socket.on('task_progress', function(data) {
frappe.socket.process_response(data, "progress");
});
frappe.socket.socket.on('new_comment', function(comment) {
if (frappe.model.docinfo[comment.comment_doctype] && frappe.model.docinfo[comment.comment_doctype][comment.comment_docname]) {
var comments = frappe.model.docinfo[comment.comment_doctype][comment.comment_docname].comments
var comment_exists = !!$.map(comments, function(x) { return x.name == comment.name? true : undefined}).length
if (!comment_exists) {
frappe.model.docinfo[comment.comment_doctype][comment.comment_docname].comments = comments.concat([comment]);
}
}
if (cur_frm.doctype === comment.comment_doctype && cur_frm.docname === comment.comment_docname) {
cur_frm.comments.refresh();
}
});
frappe.socket.socket.on('new_message', function(comment) {
frappe.utils.notify(__("Message from {0}", [comment.comment_by_fullname]), comment.comment);
if ($(cur_page.page).data('page-route') === 'messages') {
var current_contact = $(cur_page.page).find('[data-contact]').data('contact');
var on_broadcast_page = current_contact === user;
if (current_contact == comment.owner || (on_broadcast_page && comment.broadcast)) {
var $row = $('<div class="list-row"/>');
frappe.desk.pages.messages.list.data.unshift(comment);
frappe.desk.pages.messages.list.render_row($row, comment);
frappe.desk.pages.messages.list.parent.prepend($row);
}
}
else {
}
});
},
setup_reconnect: function() {
// subscribe again to open_tasks
frappe.socket.socket.on("connect", function() {
$.each(frappe.socket.open_tasks, function(task_id, opts) {
frappe.socket.subscribe(task_id, opts);
});
});
},
setup_reconnect: function() {
// subscribe again to open_tasks
frappe.socket.socket.on("connect", function() {
$.each(frappe.socket.open_tasks, function(task_id, opts) {
frappe.socket.subscribe(task_id, opts);
});
});
if(frappe.socket.open_doc) {
frappe.socket.doc_subscribe(frappe.socket.open_doc.doctype, frappe.socket.open_doc.docname);
}
},
process_response: function(data, method) {
if(!data) {
return;
}
if(frappe.socket.open_doc) {
frappe.socket.doc_subscribe(frappe.socket.open_doc.doctype, frappe.socket.open_doc.docname);
}
},
process_response: function(data, method) {
if(!data) {
return;
}
if(data) {
var opts = frappe.socket.open_tasks[data.task_id];
if(opts[method]) opts[method](data);
}
if(opts.always) {
opts.always(data);
}
if(data.status_code && status_code > 400 && opts.error) {
opts.error(data);
return;
}
// success
if(data) {
var opts = frappe.socket.open_tasks[data.task_id];
if(opts[method]) opts[method](data);
}
}
// always
frappe.request.cleanup(opts, data);
if(opts.always) {
opts.always(data);
}
// error
if(data.status_code && data.status_code > 400 && opts.error) {
opts.error(data);
}
}
}
$(frappe.socket.init);

View file

@ -93,6 +93,11 @@ frappe.upload = {
opts.callback(attachment, r);
$(document).trigger("upload_complete", attachment);
},
error: function(r) {
// if no onerror, assume callback will handle errors
opts.onerror ? opts.onerror(r) : opts.callback(null, null, r);
return;
},
btn: opts.btn
});
}

View file

@ -154,14 +154,15 @@ def run_async_task(self, site, user, cmd, form_dict):
ret = frappe.local.response
except Exception, e:
frappe.db.rollback()
set_task_status(self.request.id, "Failed")
if not frappe.flags.in_test:
frappe.db.commit()
ret = frappe.local.response
http_status_code = getattr(e, "http_status_code", 500)
ret['status_code'] = http_status_code
ret['exc'] = frappe.get_traceback()
frappe.errprint(frappe.get_traceback())
frappe.utils.response.make_logs()
set_task_status(self.request.id, "Failed", response=ret)
task_logger.error('Exception in running {}: {}'.format(cmd, ret['exc']))
else:
set_task_status(self.request.id, "Finished", response=ret)

View file

@ -64,18 +64,21 @@ def as_json():
response.data = json.dumps(frappe.local.response, default=json_handler, separators=(',',':'))
return response
def make_logs():
def make_logs(response = None):
"""make strings for msgprint and errprint"""
if not response:
response = frappe.local.response
if frappe.error_log:
# frappe.response['exc'] = json.dumps("\n".join([cstr(d) for d in frappe.error_log]))
frappe.response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log])
response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log])
if frappe.local.message_log:
frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for
response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for
d in frappe.local.message_log])
if frappe.debug_log and frappe.conf.get("logging") or False:
frappe.response['_debug_messages'] = json.dumps(frappe.local.debug_log)
response['_debug_messages'] = json.dumps(frappe.local.debug_log)
def json_handler(obj):
"""serialize non-serializable data for json"""