[PATCH] [Wok] Use async websockets notifications to send overall notifications to Wok sessions
by Aline Manera
Instead of polling the server time by time for notifications, use async
websockets notifications for that.
This patch also improved the listener for the user logs changes and make
some notifications handlers persistent accross tabs switching.
Signed-off-by: Aline Manera <aline.manera(a)gmail.com>
---
src/wok/model/notifications.py | 5 +++++
src/wok/reqlogger.py | 2 --
ui/css/bootstrap.custom.css | 6 ------
.../src/vendor/bootstrap-sass/bootstrap/_alerts.scss | 1 -
ui/css/src/wok.scss | 8 +++++---
ui/css/wok.css | 6 ++++--
ui/js/src/wok.main.js | 19 +++++++++++--------
ui/js/src/wok.utils.js | 18 +++++-------------
ui/js/wok.user-log.js | 4 +---
ui/pages/wok-ui.html.tmpl | 1 +
10 files changed, 32 insertions(+), 38 deletions(-)
diff --git a/src/wok/model/notifications.py b/src/wok/model/notifications.py
index f4eb542..59c4244 100644
--- a/src/wok/model/notifications.py
+++ b/src/wok/model/notifications.py
@@ -21,6 +21,7 @@ from datetime import datetime
from wok.exception import NotFoundError, OperationFailed
from wok.message import WokMessage
+from wok.pushserver import send_wok_notification
from wok.utils import wok_log
@@ -45,6 +46,8 @@ def add_notification(code, args=None, plugin_name=None):
args.update({"_plugin_name": plugin_name, "timestamp": timestamp})
notificationsStore[code] = args
+ send_wok_notification('', 'notifications', 'POST')
+
def del_notification(code):
global notificationsStore
@@ -54,6 +57,8 @@ def del_notification(code):
except Exception as e:
raise OperationFailed("WOKNOT0002E", {'id': str(code), 'msg': e.msg()})
+ send_wok_notification('', 'notification', 'DELETE')
+
class NotificationsModel(object):
def __init__(self, **kargs):
diff --git a/src/wok/reqlogger.py b/src/wok/reqlogger.py
index 02cd1d1..2959ddb 100644
--- a/src/wok/reqlogger.py
+++ b/src/wok/reqlogger.py
@@ -69,8 +69,6 @@ WOK_REQUEST_LOGGER = "wok_request_logger"
# AsyncTask handling
ASYNCTASK_REQUEST_METHOD = 'TASK'
-NEW_LOG_ENTRY_MESSAGE = 'new_log_entry'
-
def log_request(code, params, exception, method, status, app=None, user=None,
ip=None, class_name=None, action_name=None):
diff --git a/ui/css/bootstrap.custom.css b/ui/css/bootstrap.custom.css
index d2c2a32..1147fee 100644
--- a/ui/css/bootstrap.custom.css
+++ b/ui/css/bootstrap.custom.css
@@ -4954,12 +4954,6 @@ a.thumbnail.active {
border-color: #3a393b;
}
-@media (min-width: 1200px) {
- #alert-fields {
- padding-top: 10px;
- }
-}
-
.alert {
padding: 8px 15px;
margin-bottom: 10px;
diff --git a/ui/css/src/vendor/bootstrap-sass/bootstrap/_alerts.scss b/ui/css/src/vendor/bootstrap-sass/bootstrap/_alerts.scss
index 79c6c12..f121c8e 100644
--- a/ui/css/src/vendor/bootstrap-sass/bootstrap/_alerts.scss
+++ b/ui/css/src/vendor/bootstrap-sass/bootstrap/_alerts.scss
@@ -8,7 +8,6 @@
#alert-fields {
@media (min-width: $screen-lg-min) {
- padding-top: 10px;
}
}
diff --git a/ui/css/src/wok.scss b/ui/css/src/wok.scss
index 9e76200..ac6d961 100644
--- a/ui/css/src/wok.scss
+++ b/ui/css/src/wok.scss
@@ -162,8 +162,10 @@ html.in-progress [disabled],
}
}
-#notification-container .alert {
- margin: 10px;
+#alert-container {
+ padding-left: 80px;
+ padding-right: 60px;
+ padding-top: 10px;
}
// session expiring
@@ -224,4 +226,4 @@ html.in-progress [disabled],
// Utils
@import "modules/utils";
// Animation
-@import "modules/animation";
\ No newline at end of file
+@import "modules/animation";
diff --git a/ui/css/wok.css b/ui/css/wok.css
index b9b7c92..d46ea86 100644
--- a/ui/css/wok.css
+++ b/ui/css/wok.css
@@ -153,8 +153,10 @@ html.in-progress .disabled {
cursor: not-allowed !important;
}
-#notification-container .alert {
- margin: 10px;
+#alert-container {
+ padding-left: 80px;
+ padding-right: 60px;
+ padding-top: 10px;
}
.session-expiring {
diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js
index 411b05e..617a1c2 100644
--- a/ui/js/src/wok.main.js
+++ b/ui/js/src/wok.main.js
@@ -30,7 +30,7 @@ wok.getConfig(function(result) {
});
wok.notificationListeners = {};
-wok.addNotificationListener = function(msg, func) {
+wok.addNotificationListener = function(msg, func, persist) {
var listenerArray = wok.notificationListeners[msg];
if (listenerArray == undefined) {
listenerArray = [];
@@ -38,10 +38,13 @@ wok.addNotificationListener = function(msg, func) {
listenerArray.push(func);
wok.notificationListeners[msg] = listenerArray;
$(window).one("hashchange", function() {
- var listenerArray = wok.notificationListeners[msg];
- var del_index = listenerArray.indexOf(func);
- listenerArray.splice(del_index, 1);
- wok.notificationListeners[msg] = listenerArray;
+ // Some notification may persist while switching tabs
+ if (persist == undefined) {
+ var listenerArray = wok.notificationListeners[msg];
+ var del_index = listenerArray.indexOf(func);
+ listenerArray.splice(del_index, 1);
+ wok.notificationListeners[msg] = listenerArray;
+ }
});
};
@@ -78,7 +81,6 @@ wok.startNotificationWebSocket = function () {
};
};
-
wok.main = function() {
wok.isLoggingOut = false;
wok.popable();
@@ -513,10 +515,11 @@ wok.main = function() {
}
);
- setTimeout(wok.notificationsLoop, wok.NOTIFICATION_INTERVAL);
+ wok.notificationsLoop();
+ wok.addNotificationListener('POST:/wok/notifications', wok.notificationsLoop, true);
+ wok.addNotificationListener('DELETE:/wok/notification', wok.notificationsLoop, true);
};
-
wok.checkHelpFile = function(path) {
var lang = wok.lang.get();
var url = path.replace("tabs", "help/" + lang);
diff --git a/ui/js/src/wok.utils.js b/ui/js/src/wok.utils.js
index 80bdb77..7d03060 100644
--- a/ui/js/src/wok.utils.js
+++ b/ui/js/src/wok.utils.js
@@ -1,7 +1,7 @@
/*
* Project Wok
*
- * Copyright IBM Corp, 2015-2016
+ * Copyright IBM Corp, 2015-2017
*
* Code derived from Project Kimchi
*
@@ -209,26 +209,18 @@ wok.urlSafeB64Encode = function(str) {
return $.base64.btoa(str, true).replace(/\+/g, '-').replace(/\//g, '_');
}
-wok.notificationsLoop = function notificationsLoop() {
+wok.notificationsLoop = function() {
wok.getNotifications(
function(notifications){
if(notifications && notifications.length > 0) {
$.each(notifications, function(i, notif) {
// Check if notification is being displayed
- if (!$("#notification-container").length) {
- $('.navbar.toolbar').next().prepend('<div id="notification-container"></div>');
- }
- if (($("#notification-container").find("div:contains('" + notif.message + "')").length) == 0) {
- wok.message.notify(notif, '#notification-container');
+ if (($("#alert-container").find("div:contains('" + notif.message + "')").length) == 0) {
+ wok.message.notify(notif, '#alert-container');
}
});
}
- setTimeout(notificationsLoop, wok.NOTIFICATION_INTERVAL);
- },
- function(data){
- setTimeout(notificationsLoop, wok.NOTIFICATION_INTERVAL);
- }
- );
+ }, undefined);
}
wok.datetimeLocaleConverter = function datetimeLocaleConverter(datetime_string, locale){
diff --git a/ui/js/wok.user-log.js b/ui/js/wok.user-log.js
index d5ba36d..a5e8bd0 100644
--- a/ui/js/wok.user-log.js
+++ b/ui/js/wok.user-log.js
@@ -154,9 +154,7 @@ wok.initUserLogContent = function() {
wok.initUserLogConfigGridData();
});
- wok.addNotificationListener('POST:/wok/logs', function(message) {
- $("#refresh-button").click();
- });
+ wok.addNotificationListener('POST:/wok/logs', wok.initUserLogConfigGridData);
};
wok.initUserLogWindow = function() {
diff --git a/ui/pages/wok-ui.html.tmpl b/ui/pages/wok-ui.html.tmpl
index 8780e0b..c3c545e 100644
--- a/ui/pages/wok-ui.html.tmpl
+++ b/ui/pages/wok-ui.html.tmpl
@@ -145,6 +145,7 @@
</nav>
</div>
<div class="content">
+ <div id="alert-container"></div>
<div id="main">
</div>
</div>
--
2.9.5
7 years, 4 months
[PATCH] [Kimchi] Remove alert-container as it is being provided by Wok basic-template
by Aline Manera
Signed-off-by: Aline Manera <aline.manera(a)gmail.com>
---
ui/js/src/kimchi.network_edit_main.js | 2 +-
ui/pages/tabs/guests.html.tmpl | 3 +--
ui/pages/tabs/network.html.tmpl | 3 +--
ui/pages/tabs/storage.html.tmpl | 1 -
ui/pages/tabs/templates.html.tmpl | 3 +--
5 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/ui/js/src/kimchi.network_edit_main.js b/ui/js/src/kimchi.network_edit_main.js
index d0174dd..d1382e9 100644
--- a/ui/js/src/kimchi.network_edit_main.js
+++ b/ui/js/src/kimchi.network_edit_main.js
@@ -1,7 +1,7 @@
/*
* Project Kimchi
*
- * Copyright IBM Corp, 2016
+ * Copyright IBM Corp, 2016-2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/ui/pages/tabs/guests.html.tmpl b/ui/pages/tabs/guests.html.tmpl
index 938e38a..d19fe15 100644
--- a/ui/pages/tabs/guests.html.tmpl
+++ b/ui/pages/tabs/guests.html.tmpl
@@ -1,7 +1,7 @@
#*
* Project Kimchi
*
- * Copyright IBM Corp, 2013-2016
+ * Copyright IBM Corp, 2013-2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,6 @@
<input type="text" class="filter form-control search" id="search_input" placeholder="$_("Filter")">
</div>
</div>
- <div id="alert-container"></div>
<div id="guestListField" style="display: none">
<ul class="wok-guest-list">
<li class="wok-guest-list-header">
diff --git a/ui/pages/tabs/network.html.tmpl b/ui/pages/tabs/network.html.tmpl
index edffed0..bd7aca0 100644
--- a/ui/pages/tabs/network.html.tmpl
+++ b/ui/pages/tabs/network.html.tmpl
@@ -1,7 +1,7 @@
#*
* Project Kimchi
*
- * Copyright IBM Corp, 2013-2016
+ * Copyright IBM Corp, 2013-2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,6 @@
<input type="text" class="filter form-control" placeholder="$_("Filter")">
</div>
</div>
- <div id="alert-container"></div>
<div id="networkGrid" class="hidden">
<div>
<span class="column-state"><span class="sr-only">$_("State")</span></span><!--
diff --git a/ui/pages/tabs/storage.html.tmpl b/ui/pages/tabs/storage.html.tmpl
index ad88b65..06bfab5 100644
--- a/ui/pages/tabs/storage.html.tmpl
+++ b/ui/pages/tabs/storage.html.tmpl
@@ -37,7 +37,6 @@
<input type="text" class="filter form-control" placeholder="$_("Filter")">
</div>
</div>
- <div id="alert-container"></div>
<div id='storageGrid' class="hidden">
<div>
<span class="column-state"><span class="sr-only">$_("State")</span></span><!--
diff --git a/ui/pages/tabs/templates.html.tmpl b/ui/pages/tabs/templates.html.tmpl
index 2700dd7..8642770 100644
--- a/ui/pages/tabs/templates.html.tmpl
+++ b/ui/pages/tabs/templates.html.tmpl
@@ -1,7 +1,7 @@
#*
* Project Kimchi
*
-* Copyright IBM Corp, 2013-2016
+* Copyright IBM Corp, 2013-2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +54,6 @@
<input type="text" class="filter form-control search" id="search_input" placeholder="$_("Filter")">
</div>
</div>
- <div id="alert-container"></div>
<ul id="templates-grid" class="wok-vm-list hidden empty-when-logged-off">
<li class="wok-vm-header">
<span class="column-name" title="$_('Template Name (ID)')">$_("Template Name (ID)")</span><!--
--
2.9.5
7 years, 4 months
[PATCH] [Kimchi] Add Template listeners to update page according to user interations
by Aline Manera
From: Aline Manera <alinefm(a)linux.vnet.ibm.com>
It makes use of the async websockets notification mechanism provided by
Wok to update the Template tab content when a template is added, removed
or updated without the need to polling requests to server.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.template_main.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ui/js/src/kimchi.template_main.js b/ui/js/src/kimchi.template_main.js
index 8755167..dd91dd5 100644
--- a/ui/js/src/kimchi.template_main.js
+++ b/ui/js/src/kimchi.template_main.js
@@ -1,7 +1,7 @@
/*
* Project Kimchi
*
- * Copyright IBM Corp, 2013-2016
+ * Copyright IBM Corp, 2013-2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -189,5 +189,10 @@ kimchi.template_main = function() {
});
}
+ // Register listeners to update the page according to user interactions
+ wok.addNotificationListener('POST:/kimchi/templates', kimchi.doListTemplates);
+ wok.addNotificationListener('DELETE:/kimchi/template', kimchi.doListTemplates);
+ wok.addNotificationListener('PUT:/kimchi/template', kimchi.doListTemplates);
+
kimchi.doListTemplates();
};
--
2.9.4
7 years, 4 months
[PATCH] [Kimchi 0/6] Make use of async websockets notification mechanism
by Aline Manera
This patch set also register for libvirt events to update the page
accordindly.
Aline Manera (6):
Register for libvirt storage pools events to update the UI accordindly
Add Storage Pools listeners to update page according to user
interations
Register for libvirt network events to update the UI accordindly
Add Network listeners to update page according to user interations
Register for libvirt domain events to update the UI accordindly
Add Domain listeners to update page according to user interations
model/libvirtevents.py | 53 +++++++++++++++++++++++++++++++++++++++-
model/model.py | 18 +++++++++++---
ui/js/src/kimchi.guest_main.js | 18 ++------------
ui/js/src/kimchi.network.js | 11 +++++++--
ui/js/src/kimchi.storage_main.js | 1 +
5 files changed, 79 insertions(+), 22 deletions(-)
--
2.9.4
7 years, 4 months