<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    <div class="moz-cite-prefix">On 02/13/2017 02:29 PM, Daniel Henrique
      Barboza wrote:<br>
    </div>
    <blockquote
      cite="mid:373551a4-2764-9a27-3856-cb36c9682964@gmail.com"
      type="cite">
      <meta content="text/html; charset=windows-1252"
        http-equiv="Content-Type">
      <br>
      <br>
      <div class="moz-cite-prefix">On 02/13/2017 12:47 PM, Aline Manera
        wrote:<br>
      </div>
      <blockquote
        cite="mid:61da2e28-228b-92b0-2a9d-d1597f46fbad@linux.vnet.ibm.com"
        type="cite">
        <meta content="text/html; charset=windows-1252"
          http-equiv="Content-Type">
        Hi Daniel,<br>
        <br>
        <div class="moz-cite-prefix">On 02/08/2017 05:07 PM, Daniel
          Henrique Barboza wrote:<br>
        </div>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite">
          <meta http-equiv="content-type" content="text/html;
            charset=windows-1252">
          Hi everyone,<br>
          <br>
          I want to start a discussion on <a moz-do-not-send="true"
            class="moz-txt-link-freetext"
            href="https://github.com/kimchi-project/wok/issues/16">https://github.com/kimchi-project/wok/issues/16</a>,<br>
          "<span class="js-issue-title" style="box-sizing: border-box;">Asynchronous
            event notification".<br>
            <br>
            As most of you are aware, WoK does not have any sort of push
            notification. WoK<br>
            UI works based on a polling strategy using the Notifications
            API to fetch for any<br>
            backend notifications. This polling is on a 3 second
            interval to not overload the server<br>
            with these requests. The problems with this approach are
            obvious: the cost of<br>
            the polling process for both UI and backend, the interval
            for a backend event to be<br>
            delivered to the UI and so forth.<br>
            <br>
            - The idea<br>
            <br>
            This work aims to implement an asynchronous strategy to
            deliver server to client<br>
            messages. The idea is to use websockets* to establish a
            socket connection between<br>
            the UI and the backend. The backend can send any message
            using this socket and<br>
            the UI, after receiving it, can act upon immediately.<br>
            <br>
            <br>
            - Push server implementation<br>
            <br>
            This socket in the backend side would act as a 'push server'
            that will receive the<br>
            connections and push the same messages to all of them. Only
            server to client<br>
            messages will be sent. <br>
            <br>
            This push server can be implemented in two ways:<br>
            <br>
            * from scratch<br>
            <br>
            * using an external library<br>
            <br>
            One library that seems to do this asynchronous socket
            implementation is tornado<br>
            ( <a moz-do-not-send="true" class="moz-txt-link-freetext"
              href="https://github.com/tornadoweb/tornado">https://github.com/tornadoweb/tornado</a>
            ). It is present in all distros we support<br>
            and it has Apache 2.0 licensing. I'll experiment with it and
            see if it helps. I am<br>
            opened to any other suggestion of libraries that can be used
            in the push server<br>
            implementation. If no library is good enough for us, I'll
            have to implement it from<br>
            scratch.<br>
            <br>
          </span></blockquote>
        <br>
        I am OK in using it as it is available for Fedora 25, Ubuntu
        16.10, openSUSE 42.2 and centOS 7.<br>
        <br>
        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.<br>
        <br>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite"><span class="js-issue-title" style="box-sizing:
            border-box;"> <br>
            - WoK backend design<br>
            <br>
            In WoK backend, my idea is to reuse the 'add_notification'
            method from the<br>
            existing Notifications API. When adding a notification, fire
            a message to the<br>
            push server and notify all the listeners too.<br>
            <br>
          </span></blockquote>
        <br>
        Could you elaborate more on that?<br>
        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.<br>
        Or on Wok, after enabling/disabling a plugin.<br>
        <br>
        How will that be done with the notifications API?<br>
        <br>
        From the documentation, the notifications API is as below:<br>
        <br>
        * **GET**: Retrieve the full description of the
        Notification                    <br>
            * code: message
        ID                                                          <br>
            * message: message text already
        translated                                  <br>
            * timestamp: first time notification was emitted    <br>
        <br>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite"><span class="js-issue-title" style="box-sizing:
            border-box;"> This approach has the following advantages:<br>
            <br>
            - it will work out of the box for all backend messages in
            all plug-ins that<br>
            uses the 'add_notification' method;<br>
            <br>
          </span></blockquote>
        <br>
        Today, the notifications API is only shown on UI as a warning
        message to the user.<br>
        So I think much UI changes will be required.<br>
        <br>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite"><span class="js-issue-title" style="box-sizing:
            border-box;"> - we can re-use the same JSON message format
            of the Notifications API,<br>
            reducing the amount of UI work we'll have to adapt the
            existing UIs;<br>
            <br>
          </span></blockquote>
        <br>
        Same I commented above.<br>
        <br>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite"><span class="js-issue-title" style="box-sizing:
            border-box;"> - it will be harmless to implement. Given that
            the push server will send<br>
            messages to all connected UI endpoints, if no endpoint is
            connect<br>
            no message will be sent.<br>
            <br>
            <br>
            - WoK frontend design<br>
            <br>
            For any tab that wants to receive the push notifications,
            just connect<br>
            to the push server via websocket and react to the messages
            sent - just<br>
            like it is done today with the notifications API but without
            the need of<br>
            sending the GET /notifications messages.<br>
            <br>
            We will need to be careful to not open unnecessary
            websockets when<br>
            tab switching. We will need to pay attention to closing up
            the connections<br>
            we don't need anymore.<br>
            <br>
          </span></blockquote>
        <br>
        Why do not open just one on Wok and reuse for all the plugins?<br>
      </blockquote>
      <br>
      Imagine that a single socket 'wokchannel' is created. The plug-ins
      would<br>
      need to register in this channel to see the incoming messages.
      Now, imagine<br>
      a kimchi function "refreshVMsList" that would refresh the VMs in
      the listing.<br>
      While in the Guest tab the function would work as intended.
      However, when<br>
      going to any other tab, "refreshVMList" will start to fail because
      the elements<br>
      the function references will no longer exists.<br>
      <br>
      There is a Ginger bugs I've fixed in the past with this scenario:<br>
      <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="https://github.com/kimchi-project/ginger/issues/482">https://github.com/kimchi-project/ginger/issues/482</a>
      . In this bug, the<br>
      ginger.getSensorsInput were being called out of the Administration
      tab, causing<br>
      JS errors.<br>
      <br>
      The solution in this case would be to remove the listeners when
      switching to<br>
      a new tab. Add the listener when the tab is created, remove it
      when it is<br>
      no longer needed. This is the exact same behavior I need to
      implement with<br>
      the Websockets.<br>
      <br>
      Thus, I don't see any obvious gain or simplification by having
      only one connection<br>
      and add/remove listeners versus one connection for each tab.<br>
      <br>
    </blockquote>
    <br>
    Hrm... I was thinking in something like:<br>
    <br>
    1) The plugins would register a listener globally <br>
    <br>
    On wok.main.js:<br>
    <br>
    wok.notificationsListeners = {}<br>
    <br>
    On kimchi.main.js:<br>
    <br>
    wok.notificationsListeners['&lt;code-to-list-vms&gt;'] =
    &lt;functions-to-list-vms&gt;<br>
    <br>
    2) Reuse the notifications listener we have today and use the "code"
    to proper treat it.<br>
    <br>
    Let's call it handleNotification() which will do<br>
    <br>
    {<br>
        // One notification arrived<br>
        // Gets its code and redirect to the proper listener<br>
        func = wok.notificationsListeners.get(&lt;code&gt;)<br>
        if func !== undefined<br>
            // call func<br>
            func();<br>
    }<br>
    <br>
    So that way, I don't think the plugins need to unregister a listener
    when switching tabs.<br>
    Wok would proper gets the logic to do that avoiding errors.<br>
    <br>
    <blockquote
      cite="mid:373551a4-2764-9a27-3856-cb36c9682964@gmail.com"
      type="cite"> <br>
      Daniel<br>
      <br>
      <blockquote
        cite="mid:61da2e28-228b-92b0-2a9d-d1597f46fbad@linux.vnet.ibm.com"
        type="cite"> <br>
        <blockquote
          cite="mid:2bf265f6-8c40-4517-0776-191d8dcdc2d3@gmail.com"
          type="cite"><span class="js-issue-title" style="box-sizing:
            border-box;"> I am planning to do a proof of concept of an
            UI working with this new<br>
            push server notifications in the 'User Log' tab, together
            with this backend<br>
            work. When a new log entry is created, a push notification
            is sent and the<br>
            UI would refresh automatically. This implementation would be
            used as a base<br>
            for the other tabs/plug-ins.<br>
            <br>
            <br>
            Let me know what you think!<br>
            <br>
            <br>
            Daniel<br>
            <br>
            <br>
            PS: for the record, before deciding to use websockets I've
            considered using SSE<br>
            (Server-side Events), a HTML5 standard, but gave up due to
            lack of SSE support<br>
            from Microsoft browsers.<br>
          </span> <br>
          <fieldset class="mimeAttachmentHeader"></fieldset>
          <br>
          <pre wrap="">_______________________________________________
Kimchi-devel mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:Kimchi-devel@ovirt.org">Kimchi-devel@ovirt.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://lists.ovirt.org/mailman/listinfo/kimchi-devel">http://lists.ovirt.org/mailman/listinfo/kimchi-devel</a>
</pre>
        </blockquote>
        <br>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>