feat: implemented pull trigger in follower nodes
This commit is contained in:
parent
3f415094e9
commit
739b033489
8 changed files with 97 additions and 47 deletions
|
|
@ -119,11 +119,12 @@ def executed(patchmodule):
|
|||
# print "Patch %s already executed in %s" % (patchmodule, frappe.db.cur_db_name)
|
||||
return done
|
||||
|
||||
def block_user(block):
|
||||
def block_user(block, msg = None):
|
||||
"""stop/start execution till patch is run"""
|
||||
frappe.local.flags.in_patch = block
|
||||
frappe.db.begin()
|
||||
msg = "Patches are being executed in the system. Please try again in a few moments."
|
||||
if not msg:
|
||||
msg = "Patches are being executed in the system. Please try again in a few moments."
|
||||
frappe.db.set_global('__session_status', block and 'stop' or None)
|
||||
frappe.db.set_global('__session_status_message', block and msg or None)
|
||||
frappe.db.commit()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
{
|
||||
"_comments": "[]",
|
||||
"_liked_by": "[]",
|
||||
"autoname": "field:host_name",
|
||||
"creation": "2019-07-30 15:10:47.993692",
|
||||
"doctype": "DocType",
|
||||
|
|
@ -9,6 +7,7 @@
|
|||
"host_name",
|
||||
"api_key",
|
||||
"api_secret",
|
||||
"user",
|
||||
"allow_auto_changes",
|
||||
"last_updated"
|
||||
],
|
||||
|
|
@ -16,7 +15,9 @@
|
|||
{
|
||||
"fieldname": "host_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Hostname (URL)",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
|
|
@ -43,11 +44,18 @@
|
|||
"fieldname": "last_updated",
|
||||
"fieldtype": "Link",
|
||||
"label": "Last Updated",
|
||||
"options": "Update Log",
|
||||
"read_only": 1
|
||||
"options": "Update Log"
|
||||
},
|
||||
{
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Node User",
|
||||
"options": "User",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"modified": "2019-08-09 14:54:07.173962",
|
||||
"modified": "2019-08-14 10:19:30.049821",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Offline",
|
||||
"name": "Node",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.frappeclient import FrappeClient
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Node(Document):
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
frappe.ui.form.on('Node Configuration', {
|
||||
// refresh: function(frm) {
|
||||
//
|
||||
|
||||
// }
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,60 +8,86 @@ from frappe import _
|
|||
import json
|
||||
from frappe.model.document import Document
|
||||
from frappe.frappeclient import FrappeClient
|
||||
from frappe.model.document import check_doctype_has_followers
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||
|
||||
class NodeConfiguration(Document):
|
||||
def before_insert(self):
|
||||
config_exists = frappe.db.get_all(
|
||||
doctype = 'Node Configuration',
|
||||
filters = [
|
||||
['master_node', '=', self.master_node],
|
||||
['follower_node', '=', self.follower_node]
|
||||
]
|
||||
doctype = 'Node Configuration',
|
||||
filters = {
|
||||
'master_node': self.master_node,
|
||||
'follower_node': self.follower_node
|
||||
}
|
||||
)
|
||||
if config_exists:
|
||||
frappe.throw(_('Node Configuration already exists'))
|
||||
frappe.throw(_('Node configuration already exists'))
|
||||
|
||||
def on_update(self):
|
||||
''' create custom field to store remote docname of master node'''
|
||||
df = {
|
||||
'label': 'Remote Docname',
|
||||
'fieldname': 'remote_docname',
|
||||
'fieldtype': 'Data',
|
||||
'hidden': 1,
|
||||
'read_only': 1,
|
||||
'unique': 1,
|
||||
'no_copy': 1
|
||||
}
|
||||
for doc in self.following_doctypes:
|
||||
print(doc)
|
||||
create_custom_field(doc.ref_doctype, df)
|
||||
|
||||
@frappe.whitelist()
|
||||
def sync_master_data():
|
||||
'''Sync master data to all follower nodes, triggered when update log is created'''
|
||||
def pull_master_data():
|
||||
'''Fetch data from remote master node.'''
|
||||
current_node = frappe.utils.get_url()
|
||||
port = frappe.conf.http_port or frappe.conf.webserver_port
|
||||
current_node = current_node + ':' + str(port)
|
||||
|
||||
node_configurations = frappe.get_all(
|
||||
doctype = 'Node Configuration',
|
||||
filters = {'master_node': current_node},
|
||||
group_by = 'follower_node'
|
||||
filters = {'follower_node': current_node}
|
||||
)
|
||||
|
||||
for node_config in node_configurations:
|
||||
config = frappe.get_doc('Node Configuration', node_config.name)
|
||||
client = FrappeClient(config.master_node, 'Administrator', 'root')
|
||||
remote_node = client.get_doc('Node', filters = {'host_name': current_node}, fields = ['name', 'last_updated'])
|
||||
last_update_synced = client.get_value('Update Log', 'creation', filters = {'name': remote_node[0].get('last_updated')})
|
||||
|
||||
last_updated = frappe.db.get_value('Node', config.follower_node, 'last_updated')
|
||||
last_update_synced = frappe.db.get_value('Update Log', last_updated, 'creation')
|
||||
|
||||
doctypes = []
|
||||
for entry in config.following_doctypes:
|
||||
doctypes.append(entry.ref_doctype)
|
||||
|
||||
updates_to_be_synced = frappe.get_all(
|
||||
updates_to_be_synced = client.get_list(
|
||||
doctype = 'Update Log',
|
||||
filters = [['creation', '>', last_update_synced], ['ref_doctype', 'in', doctypes]],
|
||||
fields = ['update_type', 'ref_doctype', 'docname', 'data', 'name'],
|
||||
order_by = 'creation'
|
||||
)
|
||||
|
||||
if updates_to_be_synced != []:
|
||||
client = FrappeClient(config.follower_node, 'Administrator', 'root')
|
||||
|
||||
for doc in updates_to_be_synced:
|
||||
if doc.update_type == 'Create':
|
||||
client.insert(json.loads(doc.data))
|
||||
elif doc.update_type == 'Update':
|
||||
client.update(json.loads(doc.data))
|
||||
elif doc.update == 'Delete':
|
||||
client.delete(doc.ref_doctype, doc.docname)
|
||||
try:
|
||||
if doc.get('update_type') == 'Create':
|
||||
local_doc = frappe.get_doc(json.loads(doc.get('data'))).insert()
|
||||
doc = frappe.db.set_value(doc.get('ref_doctype'), local_doc.name, 'remote_docname', doc.get('name'))
|
||||
|
||||
#set the last update for node
|
||||
frappe.db.set_value('Node', config.follower_node, 'last_updated', updates_to_be_synced[-1].get('name'))
|
||||
|
||||
if doc.get('update_type') == 'Update':
|
||||
mapped_doc = frappe.get_all(doc.get('ref_doctype'), filters = {'remote_docname': doc.get('name')}, fields = ['name'])
|
||||
local_doc = frappe.get_doc(doc.get('doctype'), mapped_doc[0].get('name'))
|
||||
local_doc.update(json.loads(doc.get('data')))
|
||||
|
||||
if doc.get('update_type') == 'Delete':
|
||||
mapped_doc = frappe.get_all(doc.get('ref_doctype'), filters = {'remote_docname': doc.get('name')}, fields = ['name'])
|
||||
local_doc = frappe.get_doc(doc.get('doctype'), mapped_doc[0].get('name'))
|
||||
local_doc.delete()
|
||||
frappe.db.commit()
|
||||
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(frappe.get_traceback(), _('Pulling master data failed'))
|
||||
return 'failed'
|
||||
|
||||
client.set_value('Node', remote_node[0].get('name'), 'last_updated', updates_to_be_synced[-1].name)
|
||||
|
||||
else:
|
||||
return 'no updates'
|
||||
|
||||
return 'success'
|
||||
|
|
@ -3,14 +3,8 @@
|
|||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils.background_jobs import get_jobs
|
||||
|
||||
class UpdateLog(Document):
|
||||
def validate(self):
|
||||
'''Sync master data to followers whenever update log is generated'''
|
||||
enqueued_method = 'frappe.offline.doctype.node_configuration.node_configuration.sync_master_data'
|
||||
jobs = get_jobs()
|
||||
if not jobs or enqueued_method not in jobs[frappe.local.site]:
|
||||
frappe.enqueue(enqueued_method, queue = 'default')
|
||||
pass
|
||||
|
|
@ -41,6 +41,8 @@
|
|||
<li><a href="#background_jobs">
|
||||
{%= __("Background Jobs") %}</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" onclick="return frappe.ui.toolbar.pull_master_data();">
|
||||
{%= __("Pull Master Data") %}</a></li>
|
||||
<li><a href="#" onclick="return frappe.app.logout();">
|
||||
{%= __("Logout") %}</a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -300,3 +300,23 @@ frappe.ui.toolbar.setup_session_defaults = function() {
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.toolbar.pull_master_data = function() {
|
||||
frappe.call({
|
||||
method: 'frappe.offline.doctype.node_configuration.node_configuration.pull_master_data',
|
||||
callback: function(r) {
|
||||
if(r.message == 'success') {
|
||||
frappe.show_alert({message:'Successfully pulled master data', indicator:'green'});
|
||||
location.reload(true);
|
||||
}
|
||||
else if(r.message == 'failed') {
|
||||
frappe.show_alert({message:'Failed to pull master data', indicator:'red'});
|
||||
location.reload(true);
|
||||
}
|
||||
else if(r.message == 'no updates') {
|
||||
frappe.show_alert({message:'Already up-to-date', indicator:'blue'});
|
||||
location.reload(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue