Blame SOURCES/ovirt-Wait-machine-to-start-before-connecting-to-it.patch

8f6169
From 90ab2f639a083754719c147a97631e2f8f1020a0 Mon Sep 17 00:00:00 2001
8f6169
From: "Zeeshan Ali (Khattak)" <zeeshanak@gnome.org>
8f6169
Date: Tue, 28 Jul 2015 16:37:48 +0100
8f6169
Subject: [PATCH] ovirt: Wait machine to start before connecting to it
8f6169
8f6169
Apparently the starting process is asynchronous in the sense that even
8f6169
after the async Ovirt.Vm.start_async() returns, the state change is not
8f6169
not guaranteed to have taken place and communicated back from server.
8f6169
This results in Boxes giving up on connecting on slower networks where
8f6169
state change (and it's communication etc) can take a few seconds.
8f6169
8f6169
This patch tries to solve the issue by waiting for state change to
8f6169
happen for 3 seconds (more specifically, for 1 second 3 times) before
8f6169
giving up on the state change and hence connecting to it.
8f6169
8f6169
https://bugzilla.gnome.org/show_bug.cgi?id=752966
8f6169
---
8f6169
 src/ovirt-machine.vala | 33 ++++++++++++++++++++++++++++++++-
8f6169
 1 file changed, 32 insertions(+), 1 deletion(-)
8f6169
8f6169
diff --git a/src/ovirt-machine.vala b/src/ovirt-machine.vala
8f6169
index 6eae4b2..4d4449f 100644
8f6169
--- a/src/ovirt-machine.vala
8f6169
+++ b/src/ovirt-machine.vala
8f6169
@@ -3,6 +3,11 @@
8f6169
 using Gtk;
8f6169
 
8f6169
 private class Boxes.OvirtMachine: Boxes.Machine {
8f6169
+    private const uint STATE_CHANGE_TIMEOUT = 1000; // 1 second
8f6169
+    // We only try changing state once, this controls how many times we wait
8f6169
+    // STATE_CHANGE_TIMEOUT miliseconds for state change to happen.
8f6169
+    private const uint8 STATE_CHANGE_RETRIES = 3;
8f6169
+
8f6169
     private Ovirt.Vm vm;
8f6169
     private Ovirt.Proxy proxy;
8f6169
 
8f6169
@@ -31,13 +36,14 @@ public override async void connect_display (Machine.ConnectFlags flags) throws G
8f6169
         if (state == MachineState.STOPPED)
8f6169
             try {
8f6169
                 yield vm.start_async (proxy, connecting_cancellable);
8f6169
-                this.update_state ();
8f6169
             } catch (IOError.CANCELLED error) {
8f6169
                 debug ("connection to %s was cancelled", name);
8f6169
             } catch (GLib.Error error) {
8f6169
                 throw new Boxes.Error.INVALID ("Couldn't start oVirt VM '%s': %s", vm.name, error.message);
8f6169
             }
8f6169
 
8f6169
+        yield wait_for_state (MachineState.RUNNING, connecting_cancellable);
8f6169
+
8f6169
         if (state != MachineState.RUNNING)
8f6169
             throw new Boxes.Error.INVALID ("oVirt VM '%s' is not RUNNING", vm.name);
8f6169
 
8f6169
@@ -100,6 +106,31 @@ private Display create_display_connection () throws GLib.Error {
8f6169
             throw new Boxes.Error.INVALID ("unsupported display type %d for %s", vm.display.type, vm.name);
8f6169
         }
8f6169
     }
8f6169
+
8f6169
+    private async void wait_for_state (Machine.MachineState desired_state, Cancellable cancellable) {
8f6169
+        for (var i = 0; i < STATE_CHANGE_RETRIES; i++) {
8f6169
+            this.update_state ();
8f6169
+
8f6169
+            if (state == desired_state)
8f6169
+                break;
8f6169
+
8f6169
+            SourceFunc callback = wait_for_state.callback;
8f6169
+            Timeout.add (STATE_CHANGE_TIMEOUT, () => {
8f6169
+                callback ();
8f6169
+
8f6169
+                return false;
8f6169
+            });
8f6169
+
8f6169
+            yield;
8f6169
+
8f6169
+            if (cancellable.is_cancelled ()) {
8f6169
+                debug ("connection to %s was cancelled", name);
8f6169
+
8f6169
+                return;
8f6169
+            }
8f6169
+        }
8f6169
+    }
8f6169
+
8f6169
     private void update_state () {
8f6169
         switch (vm.state) {
8f6169
             case VmState.UP:
8f6169
-- 
8f6169
2.4.3
8f6169