Projet

Général

Profil

Tâche #13839

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

Étude demande 6022 Plantage EAD

Ajouté par Scrum Master il y a plus de 8 ans. Mis à jour il y a plus de 8 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Début:
02/11/2015
Echéance:
% réalisé:

100%

Temps estimé:
3.00 h
Temps passé:
Restant à faire (heures):
0.0

Demandes liées

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

Historique

#1 Mis à jour par Joël Cuissinat il y a plus de 8 ans

  • Sujet changé de Etude demnade 6022 Plantage EAD à Étude demande 6022 Plantage EAD

#2 Mis à jour par Scrum Master il y a plus de 8 ans

  • Statut changé de Nouveau à En cours

#3 Mis à jour par Scrum Master il y a plus de 8 ans

  • Assigné à mis à Daniel Dehennin

#4 Mis à jour par Daniel Dehennin il y a plus de 8 ans

  • Restant à faire (heures) changé de 3.0 à 2.0

#5 Mis à jour par Daniel Dehennin il y a plus de 8 ans

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 Mis à jour par Daniel Dehennin il y a plus de 8 ans

  • % réalisé changé de 0 à 100

#7 Mis à jour par Daniel Dehennin il y a plus de 8 ans

  • Restant à faire (heures) changé de 2.0 à 0.25

#8 Mis à jour par Scrum Master il y a plus de 8 ans

  • Statut changé de En cours à Résolu

#9 Mis à jour par Scrum Master il y a plus de 8 ans

  • Statut changé de Résolu à Fermé
  • Restant à faire (heures) changé de 0.25 à 0.0

Formats disponibles : Atom PDF