Project

General

Profile

Tâche #13839

Scénario #13757: Étude pré-scénario (45-47)

Étude demande 6022 Plantage EAD

Added by Scrum Master over 5 years ago. Updated over 5 years ago.

Status:
Fermé
Priority:
Normal
Assigned To:
Start date:
11/02/2015
Due date:
% Done:

100%

Estimated time:
3.00 h
Spent time:
Remaining (hours):
0.0

Related issues

Related to controle-vnc - Scénario #6022: La commande manage_station.py ne rend pas la main en cas de timeout Terminé (Sprint) 11/13/2015 11/20/2015

History

#1 Updated by Joël Cuissinat over 5 years ago

  • Subject changed from Etude demnade 6022 Plantage EAD to Étude demande 6022 Plantage EAD

#2 Updated by Scrum Master over 5 years ago

  • Status changed from Nouveau to En cours

#3 Updated by Scrum Master over 5 years ago

  • Assigned To set to Daniel Dehennin

#4 Updated by Daniel Dehennin over 5 years ago

  • Remaining (hours) changed from 3.0 to 2.0

#5 Updated by Daniel Dehennin over 5 years ago

Le problème est double :

  • Il n’y a aucune gestion des timeout sur les appels de commande dans ead.
  • La commande manage_station.py ne s’arrête jamais si la commande distante est bloquante

Ce deuxième point n’est pas résolu par la gestion actuelle du timeout, en effet :

Cela conduit a la levée d’exception AlreadyCalledError.

Pour que la commande ne soit plus bloquante, il faut :

  1. Ne plus tester si callback() a bien été appelé sur l’objet Deferred car c’est toujours le cas
  2. Sauvegarder l’exception de timeout dans l’objet ClientScribe et arrêter le reactor sans exécuter les callback() et errback()
  3. Lever l’exception si elle est définie avant de sortir du script
diff --git a/backend/cliscribe.py b/backend/cliscribe.py
index 041288a..96b8101 100755
--- a/backend/cliscribe.py
+++ b/backend/cliscribe.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-# -*- coding: UTF-8 -*-
+# -*- coding: utf-8 -*-

 ###########################################################################
 # Eole NG - 2007
@@ -56,6 +56,8 @@ class Cliscribe:#(policies.TimeoutMixin):
         self.d = self.factory.getRootObject()
         # gestion du timeout
         self.setmytimeout(tmout)
+        # Exception raised
+        self.exception = None

     def test_port(self):
         # appel de la mthode remote_logon avec type_os en argument
@@ -154,20 +156,27 @@ class Cliscribe:#(policies.TimeoutMixin):
         except: msg = 'Erreur, %s'%val
         log.err(msg)
         self.factory.disconnect()
+        self.exception = val
         return val

     def setmytimeout(self, secds):
         """Deferred.setTimeout est deprecated et "it seems to work but it actually doesn't" (exarkun)
         si self.d.called != False => return self.d.called sinon exécute la fonction self.timeout
         """ 
-        self.d.mytimeout = reactor.callLater(secds, lambda: self.d.called or self.timeout())
+        self.d.mytimeout = reactor.callLater(secds, self.timeout)
         return self.d.mytimeout

     def timeout(self):
-        """ "fire" le deferred self.d pour passer au callback suivant (pour avoir au moins un retour dans l'appli
+        """ Stop the reactor without running any errBack
+
+        We just stop the reactor since we can not call ``errback()``
+        on a Deferred if ``callback()`` was already called
+        https://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.Deferred.html#errback
+
         """ 
         log.msg('Timeout %s'%self.ip)
-        self.d.errback(failure.Failure(TimeoutError("Callback timed out")))
+        self.exception = failure.Failure(TimeoutError("Callback timed out"))
+        reactor.crash()

 def valid_ip(ip):
diff --git a/backend/manage_stations.py b/backend/manage_stations.py
index 776a437..60419a1 100755
--- a/backend/manage_stations.py
+++ b/backend/manage_stations.py
@@ -1,15 +1,27 @@
 #!/usr/bin/env python
-# -*- coding: UTF-8 -*-
+# -*- coding: utf-8 -*-

 from optparse import OptionParser

 import sys
 sys.path.append('/usr/share/eole/controlevnc')
-from cliscribe import Cliscribe, reactor
+from cliscribe import Cliscribe, reactor, log
 from connexions import Connexions

 c=Connexions()

+log.startLogging(open('/var/log/controle-vnc/manage_station.log', 'a+'),
+                 setStdout=False)
+
+def stop_reactor(ret):
+    log.msg("Stop the reactor with {0}".format(ret))
+    if not reactor.running:
+        log.msg("Reactor is not running")
+    else:
+        reactor.stop()
+
+    return ret
+
 def shutdown_sta(ip, reboot):
     """Appelle la fonction distante remote_shutdown du client Scribe
     reboot : 0=halt, 1=reboot, 2=logoff
@@ -33,10 +45,14 @@ def shutdown_sta(ip, reboot):
             print "Option reboot inconnue %s" % str(reboot)
             sys.exit(1)

-        d = Cliscribe(ip, disconnect=False).shutdown(reboot=reboot, force=force)
-        d.addCallback(lambda ret: reactor.stop())
-        d.addErrback(lambda ret: reactor.stop())
+        cli = Cliscribe(ip, disconnect=False)
+        d = cli.shutdown(reboot=reboot, force=force)
+        d.addBoth(stop_reactor)
         reactor.run()
+
+        if cli.exception:
+            raise cli.exception
+
         print '%s %s' % (label, nom)
     except Exception, e:
         print "L'action sur %s a échoué, Erreur : %s" % (nom, e)

#6 Updated by Daniel Dehennin over 5 years ago

  • % Done changed from 0 to 100

#7 Updated by Daniel Dehennin over 5 years ago

  • Remaining (hours) changed from 2.0 to 0.25

#8 Updated by Scrum Master over 5 years ago

  • Status changed from En cours to Résolu

#9 Updated by Scrum Master over 5 years ago

  • Status changed from Résolu to Fermé
  • Remaining (hours) changed from 0.25 to 0.0

Also available in: Atom PDF