diff mbox series

[scarthgap,2.8,1/1] prserv: commit new revisions when a request succeeds

Message ID 6b443060ee96a62efb94723c97f22b51c9b20507.1792020468.git.yoann.congal@smile.fr
State RFC, archived
Delegated to: Yoann Congal
Headers show
Series [scarthgap,2.8,1/1] prserv: commit new revisions when a request succeeds | expand

Commit Message

Yoann Congal Oct. 15, 2026, 5:04 a.m. UTC
From: Wadim Mueller <wafgo01@gmail.com>

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>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
---
 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 dc4be5b62..cff57a8cc 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'''