diff mbox series

[2.8] prserv: commit new revisions when a request succeeds

Message ID 20261006134052.1778484-1-wafgo01@gmail.com
State New
Headers show
Series [2.8] prserv: commit new revisions when a request succeeds | expand

Commit Message

Wadim Mueller Oct. 6, 2026, 1:40 p.m. UTC
PRServerClient.dispatch_message() is meant to commit new PR values after
every request that succeeds:

    try:
        return await super().dispatch_message(msg)
    except:
        self.server.table.sync()
        raise
    else:
        self.server.table.sync_if_dirty()

The else clause of a try statement does not run when the try suite leaves
through a return statement, so sync_if_dirty() is never called after a
successful request. The database connection keeps an open EXCLUSIVE
transaction and the values are written to the database file only when the
server stops or receives a signal. Until then the file stays unchanged and
other readers fail with "database is locked".

A long running server therefore holds all revisions it has handed out since
its start only in memory. After a crash, a kill or a power loss the file
returns to the state of the last clean stop, the numbering restarts there and
a client sees package revisions go backwards.

Reproduced with a server started with --file on an empty database: three
getPR() calls for new checksums leave the file untouched until the server is
stopped. With this change the entries are in the file after each request.

Keep the response, commit, then return it.

This is specific to the 2.8 branch. The server was reworked for master and
2.10 ("prserv: enable database sharing" and the commits around it), which
commits where values are stored and uses WAL, so master does not have this
problem and the commit cannot be backported as it is.

Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
---
 lib/prserv/serv.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/lib/prserv/serv.py b/lib/prserv/serv.py
index dc4be5b..cff57a8 100644
--- a/lib/prserv/serv.py
+++ b/lib/prserv/serv.py
@@ -39,12 +39,12 @@  class PRServerClient(bb.asyncrpc.AsyncServerConnection):
 
     async def dispatch_message(self, msg):
         try:
-            return await super().dispatch_message(msg)
+            response = await super().dispatch_message(msg)
         except:
             self.server.table.sync()
             raise
-        else:
-            self.server.table.sync_if_dirty()
+        self.server.table.sync_if_dirty()
+        return response
 
     async def handle_test_pr(self, request):
         '''Finds the PR value corresponding to the request. If not found, returns None and doesn't insert a new value'''