inspection: simplify VMs visit

Currently, the handling of the 'vm_added' element in the queue (added as
consequence of the 'vm-added' signal) is to act as trigger to rescan
every VM in every local connection; this operation is "fast" because
every VM except the newly added is already marked as visited. Still, it
is an not really efficient way to visit new VMs.

Instead, just push in the queue all the data we get in vm_added, so when
processing the queue we can process each VM straight away.  Because of
this, make sure to gracefully handle VMs that were removed while the
'vm_added' item for them was sitting in the queue (which is something
the old code did not handle properly).
This commit is contained in:
Pino Toscano 2017-02-23 11:22:21 +01:00 committed by Cole Robinson
parent 0c019fb8e3
commit ea5a6a3014

View File

@ -64,9 +64,7 @@ class vmmInspection(vmmGObject):
# Called by the main thread whenever a VM is added to vmlist. # Called by the main thread whenever a VM is added to vmlist.
def vm_added(self, conn, connkey): def vm_added(self, conn, connkey):
ignore = conn obj = ("vm_added", conn.get_uri(), connkey)
ignore = connkey
obj = ("vm_added")
self._q.put(obj) self._q.put(obj)
def start(self): def start(self):
@ -84,7 +82,6 @@ class vmmInspection(vmmGObject):
def _run(self): def _run(self):
while True: while True:
self._process_queue() self._process_queue()
self._process_vms()
# Process everything on the queue. If the queue is empty when # Process everything on the queue. If the queue is empty when
# called, block. # called, block.
@ -107,21 +104,27 @@ class vmmInspection(vmmGObject):
uri = conn.get_uri() uri = conn.get_uri()
self._conns[uri] = conn self._conns[uri] = conn
conn.connect("vm-added", self.vm_added) conn.connect("vm-added", self.vm_added)
# No need to push the VMs of the newly added
# connection manually into the queue, as the above
# connect() will emit vm-added signals for all of
# its VMs.
elif obj[0] == "conn_removed": elif obj[0] == "conn_removed":
uri = obj[1] uri = obj[1]
del self._conns[uri] del self._conns[uri]
elif obj[0] == "vm_added": elif obj[0] == "vm_added":
# Nothing - just a signal for the inspection thread to wake up. uri = obj[1]
pass if not (uri in self._conns):
# This connection disappeared in the meanwhile.
# Any VMs we've not seen yet? If so, process them. return
def _process_vms(self): conn = self._conns[uri]
for conn in self._conns.itervalues(): if not conn.is_active():
for vm in conn.list_vms(): return
if not conn.is_active(): connkey = obj[2]
break vm = conn.get_vm(connkey)
if not vm:
self._process_vm(conn, vm) # The VM was removed in the meanwhile.
return
self._process_vm(conn, vm)
# Try processing a single VM, keeping into account whether it was # Try processing a single VM, keeping into account whether it was
# visited already, and whether there are cached data for it. # visited already, and whether there are cached data for it.