guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

02/06: Add some utilities to work with PostgreSQL connections in threads


From: Christopher Baines
Subject: 02/06: Add some utilities to work with PostgreSQL connections in threads
Date: Sat, 3 Oct 2020 16:43:17 -0400 (EDT)

cbaines pushed a commit to branch master
in repository data-service.

commit 9723a18df426417476f043b026c58755629c4887
Author: Christopher Baines <mail@cbaines.net>
AuthorDate: Sat Oct 3 09:20:39 2020 +0100

    Add some utilities to work with PostgreSQL connections in threads
---
 guix-data-service/database.scm | 57 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/guix-data-service/database.scm b/guix-data-service/database.scm
index 1d29199..89b1a09 100644
--- a/guix-data-service/database.scm
+++ b/guix-data-service/database.scm
@@ -26,6 +26,9 @@
   #:use-module (guix-data-service config)
   #:export (with-postgresql-connection
 
+            with-postgresql-connection-per-thread
+            with-thread-postgresql-connection
+
             make-postgresql-connection-channel
             close-postgresql-connection-channel
             exec-query/through-channel
@@ -79,6 +82,60 @@
       (lambda (key . args)
         (pg-conn-finish conn)))))
 
+(define %postgresql-connection-parameters
+  (make-parameter #f))
+
+(define %postgresql-connections-hash-table
+  (make-parameter #f))
+
+(define* (with-postgresql-connection-per-thread name thunk
+                                                #:key (statement-timeout #f))
+  (parameterize ((%postgresql-connection-parameters
+                  (list name statement-timeout))
+                 (%postgresql-connections-hash-table
+                  (make-hash-table)))
+    (call-with-values
+        thunk
+      (lambda vals
+        (hash-for-each
+         (lambda (thread conn)
+           (pg-conn-finish conn))
+         (%postgresql-connections-hash-table))
+
+        (apply values vals)))))
+
+(define %thread-postgresql-connection
+  (make-thread-local-fluid))
+
+(define (with-thread-postgresql-connection f)
+  (define (set-current-thread-connection conn)
+    (if conn
+        (hash-set! (%postgresql-connections-hash-table)
+                   (current-thread)
+                   conn)
+        (hash-remove! (%postgresql-connections-hash-table)
+                      (current-thread)))
+    (fluid-set! %thread-postgresql-connection
+                conn))
+
+  (let ((conn (fluid-ref %thread-postgresql-connection)))
+    (if conn
+        ;; Assume an exception here could mean the connection has failed, so
+        ;; close it
+        (with-exception-handler
+            (lambda (exn)
+              (pg-conn-finish conn)
+              (set-current-thread-connection #f)
+              (raise-exception exn))
+          (lambda ()
+            (f conn)))
+
+        (let ((conn (apply open-postgresql-connection
+                           (%postgresql-connection-parameters))))
+          (set-current-thread-connection conn)
+
+          (f conn)))))
+
 (define* (make-postgresql-connection-channel name
                                              #:key
                                              (statement-timeout #f)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]