[Kimchi-devel] [RFC] asynchronous (websocket based) notification (Wok #16)
Daniel Henrique Barboza
dhbarboza82 at gmail.com
Tue Feb 14 12:08:02 UTC 2017
On 02/14/2017 09:51 AM, Aline Manera wrote:
>
>
> On 02/13/2017 02:29 PM, Daniel Henrique Barboza wrote:
>>
>>
>> On 02/13/2017 12:47 PM, Aline Manera wrote:
>>> Hi Daniel,
>>>
>>> On 02/08/2017 05:07 PM, Daniel Henrique Barboza wrote:
>>>> Hi everyone,
>>>>
>>>> I want to start a discussion on
>>>> https://github.com/kimchi-project/wok/issues/16,
>>>> "Asynchronous event notification".
>>>>
>>>> As most of you are aware, WoK does not have any sort of push
>>>> notification. WoK
>>>> UI works based on a polling strategy using the Notifications API to
>>>> fetch for any
>>>> backend notifications. This polling is on a 3 second interval to
>>>> not overload the server
>>>> with these requests. The problems with this approach are obvious:
>>>> the cost of
>>>> the polling process for both UI and backend, the interval for a
>>>> backend event to be
>>>> delivered to the UI and so forth.
>>>>
>>>> - The idea
>>>>
>>>> This work aims to implement an asynchronous strategy to deliver
>>>> server to client
>>>> messages. The idea is to use websockets* to establish a socket
>>>> connection between
>>>> the UI and the backend. The backend can send any message using this
>>>> socket and
>>>> the UI, after receiving it, can act upon immediately.
>>>>
>>>>
>>>> - Push server implementation
>>>>
>>>> This socket in the backend side would act as a 'push server' that
>>>> will receive the
>>>> connections and push the same messages to all of them. Only server
>>>> to client
>>>> messages will be sent.
>>>>
>>>> This push server can be implemented in two ways:
>>>>
>>>> * from scratch
>>>>
>>>> * using an external library
>>>>
>>>> One library that seems to do this asynchronous socket
>>>> implementation is tornado
>>>> ( https://github.com/tornadoweb/tornado ). It is present in all
>>>> distros we support
>>>> and it has Apache 2.0 licensing. I'll experiment with it and see if
>>>> it helps. I am
>>>> opened to any other suggestion of libraries that can be used in the
>>>> push server
>>>> implementation. If no library is good enough for us, I'll have to
>>>> implement it from
>>>> scratch.
>>>>
>>>
>>> I am OK in using it as it is available for Fedora 25, Ubuntu 16.10,
>>> openSUSE 42.2 and centOS 7.
>>>
>>> It would be good to confirm it is also available for Debian 8 as
>>> Lucio is working to get the package into the official distro.
>>>
>>>>
>>>> - WoK backend design
>>>>
>>>> In WoK backend, my idea is to reuse the 'add_notification' method
>>>> from the
>>>> existing Notifications API. When adding a notification, fire a
>>>> message to the
>>>> push server and notify all the listeners too.
>>>>
>>>
>>> Could you elaborate more on that?
>>> For example, in Kimchi, after adding/starting/deleting a VM we will
>>> need to notify all the browsers sessions to update the data in UI.
>>> Or on Wok, after enabling/disabling a plugin.
>>>
>>> How will that be done with the notifications API?
>>>
>>> From the documentation, the notifications API is as below:
>>>
>>> * **GET**: Retrieve the full description of the Notification
>>> * code: message ID
>>> * message: message text already translated
>>> * timestamp: first time notification was emitted
>>>
>>>> This approach has the following advantages:
>>>>
>>>> - it will work out of the box for all backend messages in all
>>>> plug-ins that
>>>> uses the 'add_notification' method;
>>>>
>>>
>>> Today, the notifications API is only shown on UI as a warning
>>> message to the user.
>>> So I think much UI changes will be required.
>>>
>>>> - we can re-use the same JSON message format of the Notifications API,
>>>> reducing the amount of UI work we'll have to adapt the existing UIs;
>>>>
>>>
>>> Same I commented above.
>>>
>>>> - it will be harmless to implement. Given that the push server will
>>>> send
>>>> messages to all connected UI endpoints, if no endpoint is connect
>>>> no message will be sent.
>>>>
>>>>
>>>> - WoK frontend design
>>>>
>>>> For any tab that wants to receive the push notifications, just connect
>>>> to the push server via websocket and react to the messages sent - just
>>>> like it is done today with the notifications API but without the
>>>> need of
>>>> sending the GET /notifications messages.
>>>>
>>>> We will need to be careful to not open unnecessary websockets when
>>>> tab switching. We will need to pay attention to closing up the
>>>> connections
>>>> we don't need anymore.
>>>>
>>>
>>> Why do not open just one on Wok and reuse for all the plugins?
>>
>> Imagine that a single socket 'wokchannel' is created. The plug-ins would
>> need to register in this channel to see the incoming messages. Now,
>> imagine
>> a kimchi function "refreshVMsList" that would refresh the VMs in the
>> listing.
>> While in the Guest tab the function would work as intended. However, when
>> going to any other tab, "refreshVMList" will start to fail because
>> the elements
>> the function references will no longer exists.
>>
>> There is a Ginger bugs I've fixed in the past with this scenario:
>> https://github.com/kimchi-project/ginger/issues/482 . In this bug, the
>> ginger.getSensorsInput were being called out of the Administration
>> tab, causing
>> JS errors.
>>
>> The solution in this case would be to remove the listeners when
>> switching to
>> a new tab. Add the listener when the tab is created, remove it when it is
>> no longer needed. This is the exact same behavior I need to implement
>> with
>> the Websockets.
>>
>> Thus, I don't see any obvious gain or simplification by having only
>> one connection
>> and add/remove listeners versus one connection for each tab.
>>
>
> Hrm... I was thinking in something like:
>
> 1) The plugins would register a listener globally
>
> On wok.main.js:
>
> wok.notificationsListeners = {}
>
> On kimchi.main.js:
>
> wok.notificationsListeners['<code-to-list-vms>'] = <functions-to-list-vms>
>
> 2) Reuse the notifications listener we have today and use the "code"
> to proper treat it.
>
> Let's call it handleNotification() which will do
>
> {
> // One notification arrived
> // Gets its code and redirect to the proper listener
> func = wok.notificationsListeners.get(<code>)
> if func !== undefined
> // call func
> func();
> }
>
> So that way, I don't think the plugins need to unregister a listener
> when switching tabs.
> Wok would proper gets the logic to do that avoiding errors.
hmmmmm I think we can develop something in this direction. I'll experiment
with it and see what I got.
Daniel
>
>>
>> Daniel
>>
>>>
>>>> I am planning to do a proof of concept of an UI working with this new
>>>> push server notifications in the 'User Log' tab, together with this
>>>> backend
>>>> work. When a new log entry is created, a push notification is sent
>>>> and the
>>>> UI would refresh automatically. This implementation would be used
>>>> as a base
>>>> for the other tabs/plug-ins.
>>>>
>>>>
>>>> Let me know what you think!
>>>>
>>>>
>>>> Daniel
>>>>
>>>>
>>>> PS: for the record, before deciding to use websockets I've
>>>> considered using SSE
>>>> (Server-side Events), a HTML5 standard, but gave up due to lack of
>>>> SSE support
>>>> from Microsoft browsers.
>>>>
>>>>
>>>> _______________________________________________
>>>> Kimchi-devel mailing list
>>>> Kimchi-devel at ovirt.org
>>>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ovirt.org/pipermail/kimchi-devel/attachments/20170214/7d00a4b1/attachment.html>
More information about the Kimchi-devel
mailing list