0

I recently added a RPC backend to an existing single-threaded application as shown below

lock = Lock() def update_state(address, value): with lock: state[address] = value class ExistingClass: def __init__(self, *args, **kwargs): thread = Thread(target=self.start_listener) thread.start() def start_listener(self): self.server = SimpleXMLRPCServer(("localhost", 8002) , allow_none=True) self.server.register_function(update_state, "update_state") self.server.serve_forever() def read_state(self, address): with lock: return state[address] def write_state(self, address, value): with lock: return state[address] = value ec = ExistingClass() ec.server.shutdown() 

The RPC backend is run in a separate thread to allow the application to keep running.

The problem is that shutting down the application requires explicitly stopping the server and the function SimpleXMLRPCServer.shutdown() does not work after a client has called the PRC update_state i.e. the command ps shows that the process is still alive post shutdown.

Initially I thought the problem could be due to the absence of a lock but that didn't resolve the problem.

2 Answers 2

0

The issue you're facing is likely due to the fact that the server is blocked waiting for a client request to be completed. You can create a signal or flag that indicates when the server should stop. To gracefully shutdown the server, You can use a threading.Event for this purpose.

from threading import Thread, Event from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler # ... class ExistingClass: def __init__(self, *args, **kwargs): self.shutdown_event = Event() thread = Thread(target=self.start_listener) thread.start() def start_listener(self): self.server = SimpleXMLRPCServer(("localhost", 8002), allow_none=True, requestHandler=SimpleXMLRPCRequestHandler) self.server.register_function(update_state, "update_state") while not self.shutdown_event.is_set(): self.server.handle_request() # Handle client requests def shutdown(self): self.shutdown_event.set() # Set the shutdown event self.server.server_close() # Close the server socket # ... ec = ExistingClass() # To shut down the server gracefully: ec.shutdown() 
Sign up to request clarification or add additional context in comments.

Comments

0

I found the answer. Turns out to be simple but I'm positing this for posterity.

The RPC thread should be flagged as a daemon, i.e.

thread.daemon = True

This allows the thread to terminate when the RPC server stops.

See this post for more discussions about the daemon property.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.