Commit 309a413b authored by Boris Kocherov's avatar Boris Kocherov

correctly terminate libreoffice daemon

parent 81eba22c
...@@ -63,10 +63,7 @@ class OpenOffice(Application): ...@@ -63,10 +63,7 @@ class OpenOffice(Application):
self.last_test_error = None self.last_test_error = None
self._cleanRequest() self._cleanRequest()
def _testOpenOffice(self): def _run_libreoffice_tester(self, args=[]):
"""Test if OpenOffice was started correctly"""
logger.debug("Test OpenOffice %s - Pid %s" % (self.getConnection(),
self.pid()))
python = join(self.office_binary_path, "python") python = join(self.office_binary_path, "python")
args = [exists(python) and python or "python", args = [exists(python) and python or "python",
pkg_resources.resource_filename("cloudooo", pkg_resources.resource_filename("cloudooo",
...@@ -74,18 +71,41 @@ class OpenOffice(Application): ...@@ -74,18 +71,41 @@ class OpenOffice(Application):
"helper", "openoffice_tester.py")), "helper", "openoffice_tester.py")),
"--connection=%s" % self.getConnection(), "--connection=%s" % self.getConnection(),
"--uno_path=%s" % self.uno_path, "--uno_path=%s" % self.uno_path,
"--office_binary_path=%s" % self.office_binary_path] "--office_binary_path=%s" % self.office_binary_path] + args
stdout, stderr = Popen(args, stdout=PIPE, stdout, stderr = Popen(args, stdout=PIPE,
stderr=PIPE, close_fds=True).communicate() stderr=PIPE, close_fds=True).communicate()
if stdout == "": if stdout == "":
logger.error("openoffice_tester.py cmdline: %s", " ".join(args)) logger.error("openoffice_tester.py cmdline: %s", " ".join(args))
logger.error("openoffice_tester.py stdout: %s", stdout) logger.error("openoffice_tester.py stdout: %s", stdout)
logger.error("openoffice_tester.py stderr: %s", stderr) logger.error("openoffice_tester.py stderr: %s", stderr)
return False return False, stderr
stdout = json.loads(stdout) stdout = json.loads(stdout)
return stdout, stderr
def _testOpenOffice(self):
"""Test if LibreOffice was started correctly"""
logger.debug("%s instance testing - Pid %s" % (self.getConnection(),
self.pid()))
stdout, stderr = self._run_libreoffice_tester()
self.last_test_error = stderr self.last_test_error = stderr
if stdout == True: if stdout == True:
logger.debug("Instance %s works" % self.getConnection()) logger.debug("%s instance works" % self.getConnection())
return stdout
def _terminate(self):
"""Send LibreOffice daemon terminate command"""
logger.debug("%s instance terminating - Pid %s" % (self.getConnection(),
self.pid()))
stdout, stderr = self._run_libreoffice_tester(["--terminate"])
if stderr:
logger.error(stderr)
if stdout == True:
for num in range(5):
if not exists(self.lock_file):
logger.debug("%s terminate" % self.getConnection())
return stdout
sleep(1)
logger.error("%s can not terminate" % self.getConnection())
return stdout return stdout
def _cleanRequest(self): def _cleanRequest(self):
...@@ -104,6 +124,9 @@ class OpenOffice(Application): ...@@ -104,6 +124,9 @@ class OpenOffice(Application):
if environment_dict is None: if environment_dict is None:
environment_dict = {} environment_dict = {}
Application.loadSettings(self, hostname, port, path_run_dir) Application.loadSettings(self, hostname, port, path_run_dir)
self.path_user_installation = join(self.path_run_dir, \
"cloudooo_instance_%s" % self.port)
self.lock_file = join(self.path_user_installation, '.lock')
self.office_binary_path = office_binary_path self.office_binary_path = office_binary_path
self.uno_path = uno_path self.uno_path = uno_path
self.default_language = default_language self.default_language = default_language
...@@ -141,13 +164,10 @@ class OpenOffice(Application): ...@@ -141,13 +164,10 @@ class OpenOffice(Application):
def start(self, init=True): def start(self, init=True):
"""Start Instance.""" """Start Instance."""
self.path_user_installation = join(self.path_run_dir, \ if exists(self.lock_file):
"cloudooo_instance_%s" % self.port)
lock_file = join(self.path_user_installation, '.lock')
if exists(lock_file):
pids = processUsedFilesInPath(self.path_user_installation) pids = processUsedFilesInPath(self.path_user_installation)
if len(pids) == 0: if len(pids) == 0:
logger.debug("Stalled lock file: %s", lock_file) logger.debug("Stalled lock file: %s", self.lock_file)
else: else:
logger.debug("kill process used workdir: %s", self.path_user_installation) logger.debug("kill process used workdir: %s", self.path_user_installation)
_, alive = kill_procs_tree(pids, sig=signal.SIGKILL, timeout=self.timeout) _, alive = kill_procs_tree(pids, sig=signal.SIGKILL, timeout=self.timeout)
...@@ -182,12 +202,22 @@ class OpenOffice(Application): ...@@ -182,12 +202,22 @@ class OpenOffice(Application):
else: else:
logger.error("%s libreoffice not started", self.getConnection()) logger.error("%s libreoffice not started", self.getConnection())
def stop(self, pid=None): def reset(self, *args, **kw):
"""Stop the instance by pid. By the default if Application.stop(self, *args, **kw):
the signal is 15."""
if Application.stop(self, pid=pid):
self._cleanRequest() self._cleanRequest()
def stop(self, pid=None):
if hasattr(self, 'process'):
if pid is not None and self.process.pid != pid:
return False
returncode = self.process.poll()
if returncode is None or returncode == 0:
self._terminate()
if Application.stop(self, pid=pid):
self._cleanRequest()
return True
return False
def isLocked(self): def isLocked(self):
"""Verify if OOo instance is being used.""" """Verify if OOo instance is being used."""
return self._lock.locked() return self._lock.locked()
......
...@@ -9,10 +9,17 @@ except ImportError: ...@@ -9,10 +9,17 @@ except ImportError:
import simplejson as json import simplejson as json
def test_openoffice(connection, uno_path, office_binary_path): def test_openoffice(connection, uno_path, office_binary_path, terminate=False):
import pyuno import pyuno
try: try:
helper_util.getServiceManager(connection, uno_path, office_binary_path) sm = helper_util.getServiceManager(connection, uno_path, office_binary_path)
if terminate:
try:
sm.createInstance("com.sun.star.frame.Desktop").terminate()
except pyuno.getClass("com.sun.star.beans.UnknownPropertyException"):
pass
except pyuno.getClass("com.sun.star.lang.DisposedException"):
pass
return True return True
except pyuno.getClass("com.sun.star.connection.NoConnectException"): except pyuno.getClass("com.sun.star.connection.NoConnectException"):
return False return False
...@@ -22,12 +29,14 @@ def main(): ...@@ -22,12 +29,14 @@ def main():
try: try:
opt_list, arg_list = getopt(sys.argv[1:], "", opt_list, arg_list = getopt(sys.argv[1:], "",
["connection=", "uno_path=", ["connection=", "uno_path=",
"office_binary_path="]) "office_binary_path=",
"terminate"])
except GetoptError as e: except GetoptError as e:
sys.stderr.write("%s \nUse --connection" % e) sys.stderr.write("%s \nUse --connection" % e)
sys.exit(2) sys.exit(2)
connection = uno_path = office_binary_path = None connection = uno_path = office_binary_path = None
terminate = False
for opt, arg in opt_list: for opt, arg in opt_list:
if opt == "--connection": if opt == "--connection":
connection = arg connection = arg
...@@ -37,9 +46,12 @@ def main(): ...@@ -37,9 +46,12 @@ def main():
sys.path.append(uno_path) sys.path.append(uno_path)
elif opt == "--office_binary_path": elif opt == "--office_binary_path":
office_binary_path = arg office_binary_path = arg
elif opt == "--terminate":
terminate = True
output = json.dumps(test_openoffice(connection, output = json.dumps(test_openoffice(connection,
uno_path, office_binary_path)) uno_path, office_binary_path,
terminate=terminate))
sys.stdout.write(output) sys.stdout.write(output)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -75,7 +75,7 @@ class MonitorMemory(Monitor, Process): ...@@ -75,7 +75,7 @@ class MonitorMemory(Monitor, Process):
pid = self.openoffice.pid() pid = self.openoffice.pid()
if self.get_memory_usage(pid) > self.limit: if self.get_memory_usage(pid) > self.limit:
logger.debug("Stopping OpenOffice on memory limit increase") logger.debug("Stopping OpenOffice on memory limit increase")
self.openoffice.stop(pid=pid) self.openoffice.reset(pid=pid)
sleep(self.interval) sleep(self.interval)
logger.debug("Stop MonitorMemory") logger.debug("Stop MonitorMemory")
......
...@@ -52,7 +52,7 @@ class MonitorTimeout(Monitor, Process): ...@@ -52,7 +52,7 @@ class MonitorTimeout(Monitor, Process):
logger.debug("Stop OpenOffice - Port %s - Pid %s" % (port, pid)) logger.debug("Stop OpenOffice - Port %s - Pid %s" % (port, pid))
# using pid is not necessary here # using pid is not necessary here
# but safe if incorrect use # but safe if incorrect use
self.openoffice.stop(pid=pid) self.openoffice.reset(pid=pid)
def terminate(self): def terminate(self):
"""Stop the process""" """Stop the process"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment