Browse Source

better handling of progress bar update

Il whoall originale cicla una sola volta sulla lista dei thread,
bloccandosi su ogni thread finche' non ha finito la sua operazione.
In questo scenario una progress bar non e' molto indicativa: mettiamo
che il primo thread ci metta molto piu' degli altri a finire la sua
operazione: la barra rimarra' ferma all'inizio finche' il primo thread
non ha finito, e poi schizzera' velocemente a 100% perche' gli altri
thread avranno gia' finito la loro operazione nel frattempo.

Questo commit introduce un join (quasi) asincrono dei diversi thread
di whoall, e fa in modo che la progress bar si aggiorni uniformemente
man mano che i thread finiscono di lavorare. whoall non attende piu' che
un thread finisca prima di andare a fare il join di quello successivo,
ma spazza la lista continuamente aggiornando la progress bar ogni volta
che un thread fa il join.
bluehood 8 years ago
parent
commit
dbff8f53f5
1 changed files with 23 additions and 12 deletions
  1. 23 12
      whoall

+ 23 - 12
whoall

@@ -342,18 +342,29 @@ for node in nodes:
 index = 0
 print ' Querying ' + str(num) + ' hosts...'
 
-# Rejoin them when their work is done
-# NB a progress bar does not make much sense if join is not asynchronous (blue)
-for node in nodes:
-    node.join()
-    if progressbar:
-        # Progessbar
-        index += 1
-        stdout.write('\r ['
-                     + '='*index
-                     + '>'*(1-int(index/num))
-                     + ' '*(num-index-1) + ']')
-        stdout.flush()
+# Try to join each node in turn
+# Remove their reference from nodescopy as they finish
+iterator = 0
+nodescopy = nodes[:] # shallow copy of nodes list
+while len(nodescopy) > 0:
+    node = nodescopy[iterator%len(nodescopy)]
+    iterator += 1
+    node.join(0)
+    if node.isAlive():
+        # Not done yet, let's come back later
+        continue
+    else:
+        # Node is done, remove it from nodescopy
+        nodescopy.remove(node)
+        # Update progressbar
+        if progressbar:
+            # Progessbar
+            index += 1
+            stdout.write('\r ['
+                         + '='*index
+                         + '>'*(1-int(index/num))
+                         + ' '*(num-index-1) + ']')
+            stdout.flush()
 
 if progressbar:
     # Newline