zeitgeist team mailing list archive
-
zeitgeist team
-
Mailing list archive
-
Message #01757
[Merge] lp:~thekorn/zeitgeist/handle-SIGHUP into lp:zeitgeist
Markus Korn has proposed merging lp:~thekorn/zeitgeist/handle-SIGHUP into lp:zeitgeist.
Requested reviews:
Zeitgeist Framework Team (zeitgeist)
Added a way to shutdown the zeitgeist-daemon in a clean way by sending a SIGHUP signal to the process (as described in [0])
[0] http://lists.zeitgeist-project.com/pipermail/dev/2010-September/000157.html
--
https://code.launchpad.net/~thekorn/zeitgeist/handle-SIGHUP/+merge/35539
Your team Zeitgeist Framework Team is requested to review the proposed merge of lp:~thekorn/zeitgeist/handle-SIGHUP into lp:zeitgeist.
=== modified file '_zeitgeist/engine/main.py'
--- _zeitgeist/engine/main.py 2010-09-02 08:44:39 +0000
+++ _zeitgeist/engine/main.py 2010-09-15 14:26:38 +0000
@@ -130,6 +130,7 @@
return self.__extensions
def close(self):
+ log.debug("closing down the zeitgeist engine ...")
self.extensions.unload()
self._cursor.connection.close()
self._cursor = None
=== modified file '_zeitgeist/engine/remote.py'
--- _zeitgeist/engine/remote.py 2010-09-09 21:40:51 +0000
+++ _zeitgeist/engine/remote.py 2010-09-15 14:26:38 +0000
@@ -345,6 +345,7 @@
"""Terminate the running Zeitgeist engine process; use with caution,
this action must only be triggered with the user's explicit consent,
as it will affect all applications using Zeitgeist"""
+ self._engine.close()
if self._mainloop:
self._mainloop.quit()
=== modified file '_zeitgeist/singleton.py'
--- _zeitgeist/singleton.py 2010-01-23 21:37:08 +0000
+++ _zeitgeist/singleton.py 2010-09-15 14:26:38 +0000
@@ -40,7 +40,7 @@
if dbus_service.NameHasOwner(ZeitgeistDBusInterface.BUS_NAME):
# already running daemon instance
- if _config.options.replace or _config.options.quit:
+ if hasattr(_config, "options") and (_config.options.replace or _config.options.quit):
if _config.options.quit:
logging.info("Stopping the currently running instance.")
else:
@@ -58,13 +58,13 @@
("An existing instance was found. Please use "
"--replace to quit it and start a new instance.")
)
- elif _config.options.quit:
+ elif hasattr(_config, "options") and _config.options.quit:
logging.info("There is no running instance; doing nothing.")
else:
# service is not running, save to start
logging.debug("No running instances found.")
- if _config.options.quit:
+ if hasattr(_config, "options") and _config.options.quit:
sys.exit(0)
bus = dbus.service.BusName(ZeitgeistDBusInterface.BUS_NAME, sbus, do_not_queue=True)
=== modified file 'doc/zeitgeist-daemon.1'
--- doc/zeitgeist-daemon.1 2010-05-26 16:34:39 +0000
+++ doc/zeitgeist-daemon.1 2010-09-15 14:26:38 +0000
@@ -71,6 +71,9 @@
The ZEITGEIST_DEFAULT_EXTENSIONS and the ZEITGEIST_EXTRA_EXTENSIONS
variable require a no-space comma separated list of module.class names.
+.SH SIGNALS
+\fISIGHUP\f1: zeitgeist\-daemon will shut itself down in a clean way.
+
.SH EXAMPLES
.PP
.B environment variables
=== modified file 'test/remote-test.py'
--- test/remote-test.py 2010-08-02 13:15:11 +0000
+++ test/remote-test.py 2010-09-15 14:26:38 +0000
@@ -4,6 +4,9 @@
import os
import sys
import logging
+import signal
+import time
+from subprocess import Popen, PIPE
# DBus setup
import gobject
@@ -15,6 +18,7 @@
from zeitgeist.client import ZeitgeistDBusInterface, ZeitgeistClient
from zeitgeist.datamodel import (Event, Subject, Interpretation, Manifestation,
TimeRange, StorageState)
+from _zeitgeist.engine.remote import RemoteInterface
import testutils
from testutils import parse_events
@@ -315,6 +319,34 @@
iface = self.client._iface # we know that client._iface is as clean as possible
registry = iface.get_extension("DataSourceRegistry", "data_source_registry")
registry.GetDataSources()
+
+class ZeitgeistRemoteInterfaceTest(unittest.TestCase):
+
+ def testQuit(self):
+ """calling Quit() on the remote interface should shutdown the
+ engine in a clean way"""
+ interface = RemoteInterface()
+ self.assertEquals(interface._engine.is_closed(), False)
+ interface.Quit()
+ self.assertEquals(interface._engine.is_closed(), True)
+
+class ZeitgeistDaemonTest(unittest.TestCase):
+
+ def testSIGHUP(self):
+ """sending a SIGHUP signal to a running deamon instance results
+ in a clean shutdown"""
+ daemon = Popen(
+ ["./zeitgeist-daemon.py", "--no-datahub"], stderr=PIPE, stdout=PIPE
+ )
+ # give the daemon some time to wake up
+ time.sleep(3)
+ err = daemon.poll()
+ if err:
+ raise RuntimeError("Could not start daemon, got err=%i" % err)
+ os.kill(daemon.pid, signal.SIGHUP)
+ err = daemon.wait()
+ self.assertEqual(err, 0)
+
if __name__ == "__main__":
unittest.main()
=== modified file 'zeitgeist-daemon.py'
--- zeitgeist-daemon.py 2010-08-02 20:46:47 +0000
+++ zeitgeist-daemon.py 2010-09-15 14:26:38 +0000
@@ -26,6 +26,7 @@
import gettext
import logging
import optparse
+import signal
from copy import copy
# Make sure we can find the private _zeitgeist namespace
@@ -94,7 +95,7 @@
mainloop = gobject.MainLoop()
try:
- RemoteInterface(mainloop = mainloop)
+ interface = RemoteInterface(mainloop = mainloop)
except RuntimeError, e:
logging.error(unicode(e))
sys.exit(1)
@@ -110,5 +111,11 @@
logging.warning(
_("File \"%s\" not found, not starting datahub") % passive_loggers)
+def handle_sighup(signum, frame):
+ """We are using the SIGHUP signal to shutdown zeitgeist in a clean way"""
+ logging.info("got SIGHUP signal, shutting down zeitgeist interface")
+ interface.Quit()
+signal.signal(signal.SIGHUP, handle_sighup)
+
logging.info(_(u"Starting Zeitgeist service..."))
mainloop.run()