Uploaded image for project: 'SX Spring Python'
  1. SX Spring Python
  2. SESPRINGPYTHONPY-99

PyroServiceExporter daemon shutting down abruptly in Python 2.6

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.0.0.GA
    • Fix Version/s: 1.1.0.M2
    • Component/s: Remoting
    • Labels:
      None
    • Environment:
      Ubuntu Linux 9.04
      Python 2.5/2.6 (Ubuntu repository version)
      Spring Python 1.0.0-RELEASE
      Pyro 3.7-2 (Ubuntu repository version)

      Description

      While coding a sample application to try SpringPython functionnality, I encountered an abrupt stop of a my remote server as soon as it is launched, without any

      Here is the log of the launch:
      ====
      /usr/lib/python2.6/dist-packages/Pyro/protocol.py:11: DeprecationWarning: the md5 module is deprecated; use hashlib instead
      import socket, struct, os, time, sys, md5, hmac, types, random
      /usr/lib/python2.6/sets.py:85: DeprecationWarning: functions overriding warnings.showwarning() must support the 'line' argument
      stacklevel=2)
      /var/lib/python-support/python2.6/amara/bindery.py:4: DeprecationWarning: the sets module is deprecated
      import sets
      2009-07-03 15:39:45,755 - springpython.container.ObjectContainer - DEBUG - === Scanning configuration <_main_.MySampleServerApplicationContext object at 0x97c4fac> for object definitions ===
      2009-07-03 15:39:45,797 - springpython.config.PythonConfig - DEBUG - ==============================================================
      2009-07-03 15:39:45,798 - springpython.config.PythonConfig - DEBUG - Parsing <_main_.MySampleServerApplicationContext object at 0x97c4fac>
      2009-07-03 15:39:45,799 - springpython.config.PythonConfig - DEBUG - ==============================================================
      2009-07-03 15:39:45,799 - springpython.container.ObjectContainer - DEBUG - mySampleService object definition does not exist. Adding to list of definitions.
      2009-07-03 15:39:45,799 - springpython.container.ObjectContainer - DEBUG - mySampleServiceExporter object definition does not exist. Adding to list of definitions.
      2009-07-03 15:39:45,800 - springpython.container.ObjectContainer - DEBUG - === Done reading object definitions. ===
      2009-07-03 15:39:45,811 - springpython.context.ApplicationContext - DEBUG - Eagerly fetching mySampleServiceExporter
      2009-07-03 15:39:45,811 - springpython.context.ApplicationContext - DEBUG - Did NOT find object 'mySampleServiceExporter' in the singleton storage.
      2009-07-03 15:39:45,812 - springpython.context.ApplicationContext - DEBUG - Creating an instance of id=mySampleServiceExporter props=[] scope=scope.SINGLETON factory=PythonObjectFactory(<bound method MySampleServerApplicationContext.mySampleServiceExporter of <_main_.MySampleServerApplicationContext object at 0x97c4fac>>)
      2009-07-03 15:39:45,812 - springpython.factory.PythonObjectFactory - DEBUG - Creating an instance of mySampleServiceExporter
      2009-07-03 15:39:45,812 - springpython.config.objectSingleton<function mySampleServiceExporter at 0x97a3c6c> - (<_main_.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - This IS the top-level object, calling mySampleServiceExporter().
      2009-07-03 15:39:45,812 - springpython.config.objectSingleton<function mySampleService at 0x97a3bc4> - (<_main_.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - This is NOT the top-level object mySampleServiceExporter, deferring to container.
      2009-07-03 15:39:45,812 - springpython.config.objectSingleton<function mySampleService at 0x97a3bc4> - (<_main_.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - Container = <springpython.context.ApplicationContext object at 0x97ca02c>
      2009-07-03 15:39:45,812 - springpython.context.ApplicationContext - DEBUG - Did NOT find object 'mySampleService' in the singleton storage.
      2009-07-03 15:39:45,812 - springpython.context.ApplicationContext - DEBUG - Creating an instance of id=mySampleService props=[] scope=scope.SINGLETON factory=PythonObjectFactory(<bound method MySampleServerApplicationContext.mySampleService of <_main_.MySampleServerApplicationContext object at 0x97c4fac>>)
      2009-07-03 15:39:45,813 - springpython.factory.PythonObjectFactory - DEBUG - Creating an instance of mySampleService
      2009-07-03 15:39:45,813 - springpython.config.objectSingleton<function mySampleService at 0x97a3bc4> - (<_main_.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - This IS the top-level object, calling mySampleService().
      2009-07-03 15:39:45,814 - springpython.config.objectSingleton<function mySampleService at 0x97a3bc4> - (<_main.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - Found <main_.MySampleService instance at 0x97da30c>
      2009-07-03 15:39:45,814 - springpython.context.ApplicationContext - DEBUG - Stored object 'mySampleService' in container's singleton storage
      2009-07-03 15:39:45,814 - springpython.config.objectSingleton<function mySampleService at 0x97a3bc4> - (<_main.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - Found <main_.MySampleService instance at 0x97da30c> inside the container
      2009-07-03 15:39:45,814 - springpython.config.objectSingleton<function mySampleServiceExporter at 0x97a3c6c> - (<_main_.MySampleServerApplicationContext object at 0x97c4fac>,)scope.SINGLETON - DEBUG - Found <springpython.remoting.pyro.PyroServiceExporter object at 0x97da2ac>
      2009-07-03 15:39:45,814 - springpython.context.ApplicationContext - DEBUG - Stored object 'mySampleServiceExporter' in container's singleton storage
      2009-07-03 15:39:45,836 - springpython.remoting.pyro.PyroServiceExporter - DEBUG - Exporting mySampleService as a Pyro service at localhost:7000
      2009-07-03 15:39:45,837 - springpython.remoting.pyro.PyroDaemonHolder - DEBUG - Registering mySampleService at localhost:7000 with the Pyro server
      2009-07-03 15:39:45,837 - springpython.remoting.pyro.PyroDaemonHolder - DEBUG - Pyro thread needs to be started at 127.0.0.1:7000
      Pyro Server Initialized. Using Pyro V3.7
      2009-07-03 15:39:45,838 - springpython.remoting.pyro.PyroDaemonHolder._PyroThread - DEBUG - Starting up Pyro server thread for 127.0.0.1:7000
      2009-07-03 15:39:45,839 - springpython.database.transaction.AutoTransactionalObject - DEBUG - Linking tx_manager with do_something_interesting
      ====
      And that's all! No shutdown message, no process running!

      Here is the configuration I used:
      ====
      from springpython.config import Object, PythonConfig
      from springpython.remoting.pyro import PyroServiceExporter

      class MySampleServerApplicationContext(PythonConfig):

      @Object
      def mySampleService(self):
      return MySampleService()

      @Object
      def mySampleServiceExporter(self):
      return PyroServiceExporter(self.mySampleService(), "mySampleService", "localhost", service_port=7000)
      ====

      I use Python 2.6, the latest release from Python 2.x branch. From a look on both SpringPython and Python 2.6 source codes, it appears, some new names were introduced in Python 2.6 threading.Thread class. Here is an excerpt:

      ====
      @property
      def daemon(self):
      assert self._initialized, "Thread.init_() not called"
      return self.__daemonic

      @daemon.setter
      def daemon(self, daemonic):
      if not self.__initialized:
      raise RuntimeError("Thread._init_() not called")
      if self.__started.is_set():
      raise RuntimeError("cannot set daemon status of active thread");
      self.__daemonic = daemonic
      ====

      In PyroDaemonHolder class from SpringPython, it appears the subclass _PyroThread is also defining a public daemon variable:

      ====
      class _PyroThread(threading.Thread):
      """
      This is a thread that runs the Pyro daemon. It is instantiated automatically
      from within PyroServiceExporter.
      """
      def _init_(self, host, port):
      """
      When this class is created, it also created a Pyro core daemon to manage.
      """
      threading.Thread._init_(self)
      self.host = host
      self.port = port
      self.logger = logging.getLogger("springpython.remoting.pyro.PyroDaemonHolder._PyroThread")

      self.daemon = Pyro.core.Daemon(host=host, port=port)
      ====

      I suspect one of these two names is overriding the other, as in Python, all names (variables, functions, classes) are mixed in the same namespace and one of the two classes does not behave as expected.
      I launched my sample code with Python 2.5 and the server appeared to boot and run continuously as expected.

      The expected behavior is to be able to use PyroServiceExporter with Python 2.6. Release notes do not (and should not) forbid the use of a Python version superior to 2.5.
      As _PyroThread is a purely internal class, maybe it would be possible to change the name of the 'daemon' variable without affecting any third-party code and then fix the name clash issue?

      Thanks for attention.

        Issue Links

          Activity

          Hide
          gregturn Greg Turnquist added a comment -

          I replicated the problem that Olivier has reported with the following script:

          from springpython.config import Object, PythonConfig
          from springpython.remoting.pyro import PyroServiceExporter

          class MySampleService(object):
          def hey(self):
          print "You have just called the sample service!"

          class MySampleServiceAppContext(PythonConfig):
          def _init_(self):
          PythonConfig._init_(self)

          @Object
          def mySampleService(self):
          return MySampleService()

          @Object
          def mySampleServiceExporter(self):
          return PyroServiceExporter(self.mySampleService(), "service", "localhost", 7000)

          if _name_ == "_main_":
          import logging
          from springpython.context import ApplicationContext

          logger = logging.getLogger("springpython")
          loggingLevel = logging.DEBUG
          logger.setLevel(loggingLevel)
          ch = logging.StreamHandler()
          ch.setLevel(loggingLevel)
          formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
          ch.setFormatter(formatter)
          logger.addHandler(ch)

          print "Starting up context that exposese reported issue..."
          ctx = ApplicationContext(MySampleServiceAppContext())

          Show
          gregturn Greg Turnquist added a comment - I replicated the problem that Olivier has reported with the following script: from springpython.config import Object, PythonConfig from springpython.remoting.pyro import PyroServiceExporter class MySampleService(object): def hey(self): print "You have just called the sample service!" class MySampleServiceAppContext(PythonConfig): def _ init _(self): PythonConfig._ init _(self) @Object def mySampleService(self): return MySampleService() @Object def mySampleServiceExporter(self): return PyroServiceExporter(self.mySampleService(), "service", "localhost", 7000) if _ name _ == "_ main _": import logging from springpython.context import ApplicationContext logger = logging.getLogger("springpython") loggingLevel = logging.DEBUG logger.setLevel(loggingLevel) ch = logging.StreamHandler() ch.setLevel(loggingLevel) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") ch.setFormatter(formatter) logger.addHandler(ch) print "Starting up context that exposese reported issue..." ctx = ApplicationContext(MySampleServiceAppContext())
          Hide
          gregturn Greg Turnquist added a comment -

          Olivier was right. By renaming _PyroThread's self.daemon as self.pyro_daemon, everything started working for python2.6.

          Show
          gregturn Greg Turnquist added a comment - Olivier was right. By renaming _PyroThread's self.daemon as self.pyro_daemon, everything started working for python2.6.

            People

            • Assignee:
              gregturn Greg Turnquist
              Reporter:
              olemerdy Olivier Le Merdy
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: