From 5b1eaf016819b74e884982bb5a8423ee8ab58526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Star=C3=BD=20Novotn=C3=BD?= Date: Wed, 30 Oct 2024 13:14:49 +0100 Subject: [PATCH 1/2] Add `--stop-after` parameter to `unoserver` --- README.rst | 4 +++- src/unoserver/server.py | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 715dafd..e2d9437 100644 --- a/README.rst +++ b/README.rst @@ -98,7 +98,8 @@ Unoserver unoserver [-h] [-v] [--interface INTERFACE] [--uno-interface UNO_INTERFACE] [--port PORT] [--uno-port UNO_PORT] [--daemon] [--executable EXECUTABLE] [--user-installation USER_INSTALLATION] - [--libreoffice-pid-file LIBREOFFICE_PID_FILE] + [--libreoffice-pid-file LIBREOFFICE_PID_FILE] [--conversion-timeout CONVERSION_TIMEOUT] + [--stop-after STOP_AFTER] * `--interface`: The interface used by the XMLRPC server, defaults to "127.0.0.1" * `--port`: The port used by the XMLRPC server, defaults to "2003" @@ -110,6 +111,7 @@ Unoserver * `--libreoffice-pid-file`: If set, unoserver will write the Libreoffice PID to this file. If started in daemon mode, the file will not be deleted when unoserver exits. * `--conversion-timeout`: Terminate Libreoffice and exit if a conversion does not complete in the given time (in seconds). +* `--stop-after`: Terminate Libreoffice and exit after the given number of requests. * `-v, --version`: Display version and exit. Unoconvert diff --git a/src/unoserver/server.py b/src/unoserver/server.py index 3748c4f..3ccaff9 100644 --- a/src/unoserver/server.py +++ b/src/unoserver/server.py @@ -52,6 +52,7 @@ def __init__( uno_port="2002", user_installation=None, conversion_timeout=None, + stop_after=None, ): self.interface = interface self.uno_interface = uno_interface @@ -59,11 +60,16 @@ def __init__( self.uno_port = uno_port self.user_installation = user_installation self.conversion_timeout = conversion_timeout + self.stop_after = stop_after self.libreoffice_process = None self.xmlrcp_thread = None self.xmlrcp_server = None self.intentional_exit = False + if self.stop_after is not None: + self.thread_lock = threading.Lock() + self.number_of_requests = 0 + def start(self, executable="libreoffice"): logger.info(f"Starting unoserver {__version__}.") @@ -138,6 +144,19 @@ def serve(self): self.xmlrcp_server = server server.register_introspection_functions() + def stop_after(): + if self.stop_after is None: + return + with self.thread_lock: + self.number_of_requests += 1 + if self.number_of_requests == self.stop_after: + logger.info( + "Processed %d requests, exiting.", + self.stop_after, + ) + self.intentional_exit = True + self.libreoffice_process.terminate() + @server.register_function def info(): import_filters = self.conv.get_filter_names( @@ -180,7 +199,7 @@ def convert( infiltername, ) try: - return future.result(timeout=self.conversion_timeout) + result = future.result(timeout=self.conversion_timeout) except futures.TimeoutError: logger.error( "Conversion timeout, terminating conversion and exiting." @@ -188,6 +207,9 @@ def convert( self.conv.local_context.dispose() self.libreoffice_process.terminate() raise + else: + stop_after() + return result @server.register_function def compare( @@ -214,7 +236,7 @@ def compare( filetype, ) try: - return future.result(timeout=self.conversion_timeout) + result = future.result(timeout=self.conversion_timeout) except futures.TimeoutError: logger.error( "Comparison timeout, terminating conversion and exiting." @@ -222,6 +244,9 @@ def compare( self.conv.local_context.dispose() self.libreoffice_process.terminate() raise + else: + stop_after() + return result server.serve_forever() @@ -304,6 +329,11 @@ def main(): help="Terminate Libreoffice and exit if a conversion does not complete in the " "given time (in seconds).", ) + parser.add_argument( + "--stop-after", + type=int, + help="Terminate Libreoffice and exit after the given number of requests.", + ) args = parser.parse_args() if args.daemon: @@ -328,6 +358,7 @@ def main(): args.uno_port, user_installation, args.conversion_timeout, + args.stop_after, ) if args.executable is not None: From cc5d209a3ad30a964b9189fe2a2a1659a6b32574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Star=C3=BD=20Novotn=C3=BD?= Date: Fri, 1 Nov 2024 00:18:27 +0100 Subject: [PATCH 2/2] Remove a needless mutex --- src/unoserver/server.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/unoserver/server.py b/src/unoserver/server.py index 3ccaff9..263afec 100644 --- a/src/unoserver/server.py +++ b/src/unoserver/server.py @@ -66,10 +66,6 @@ def __init__( self.xmlrcp_server = None self.intentional_exit = False - if self.stop_after is not None: - self.thread_lock = threading.Lock() - self.number_of_requests = 0 - def start(self, executable="libreoffice"): logger.info(f"Starting unoserver {__version__}.") @@ -144,18 +140,19 @@ def serve(self): self.xmlrcp_server = server server.register_introspection_functions() + self.number_of_requests = 0 + def stop_after(): if self.stop_after is None: return - with self.thread_lock: - self.number_of_requests += 1 - if self.number_of_requests == self.stop_after: - logger.info( - "Processed %d requests, exiting.", - self.stop_after, - ) - self.intentional_exit = True - self.libreoffice_process.terminate() + self.number_of_requests += 1 + if self.number_of_requests == self.stop_after: + logger.info( + "Processed %d requests, exiting.", + self.stop_after, + ) + self.intentional_exit = True + self.libreoffice_process.terminate() @server.register_function def info():