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

commit b904fdb16108da1d604ba9c2c46811e41d4736b4
Author: Christopher Baines <m...@cbaines.net>
AuthorDate: Mon Mar 17 10:26:21 2025 +0000
    Try to address the issue of missing derivation outputs
---
 guix-data-service/jobs/load-new-guix-revision.scm | 98 +++++++++++++++--------
 guix-data-service/model/derivation.scm            | 22 +++--
 2 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/guix-data-service/jobs/load-new-guix-revision.scm 
b/guix-data-service/jobs/load-new-guix-revision.scm
index 4ba7d5e..1d740a7 100644
--- a/guix-data-service/jobs/load-new-guix-revision.scm
+++ b/guix-data-service/jobs/load-new-guix-revision.scm
@@ -135,7 +135,24 @@
                #:on-exception on-exception))
             (raise-exception exn)))
     thunk
-    #:unwind? #t))
+    #:unwind? #t
+    #:unwind-for-type &missing-store-item-error))
+
+(define* (retry-on-missing-derivation-output thunk #:key on-exception)
+  (with-exception-handler
+      (lambda (exn)
+        (simple-format (current-error-port)
+                       "missing derivation output ~A ~A, retrying ~A\n"
+                       (missing-derivation-output-error-name exn)
+                       (missing-derivation-output-error-path exn)
+                       thunk)
+        (when on-exception (on-exception))
+        (retry-on-missing-store-item
+         thunk
+         #:on-exception on-exception))
+    thunk
+    #:unwind? #t
+    #:unwind-for-type &missing-derivation-output-error))
 
 (define (inferior-guix-systems inf)
   ;; The order shouldn't matter here, but bugs in Guix can lead to different
@@ -1182,6 +1199,32 @@ SELECT 1 FROM derivation_source_file_nars WHERE 
derivation_source_file_id = $1"
                 (values derivations
                         derivation-ids)))))))
 
+  (define (insert-input-derivations derivations)
+    (with-time-logging
+        (string-append
+         "insert-missing-derivations: ensure-input-derivations-exist ("
+         log-tag ")")
+      (let ((input-derivations
+             (vector-fold
+              (lambda (_ result drv)
+                (append! (map derivation-input-derivation
+                              (derivation-inputs drv))
+                         result))
+              '()
+              derivations)))
+        (unless (null? input-derivations)
+          ;; Ensure all the input derivations exist
+          (chunk-for-each!
+           (lambda (chunk)
+             (insert-missing-derivations
+              postgresql-connection-pool
+              call-with-utility-thread
+              derivation-ids-hash-table
+              chunk
+              #:log-tag log-tag))
+           1000
+           input-derivations)))))
+
   (let ((derivations
          derivation-ids
          (insert-derivations)))
@@ -1204,44 +1247,29 @@ SELECT 1 FROM derivation_source_file_nars WHERE 
derivation_source_file_id = $1"
                                          (derivation-outputs derivation)))
             derivation-ids
             derivations)))
-
-       (with-time-logging
-           (string-append
-            "insert-missing-derivations: ensure-input-derivations-exist ("
-            log-tag ")")
-         (let ((input-derivations
-                (vector-fold
-                 (lambda (_ result drv)
-                   (append! (map derivation-input-derivation
-                                 (derivation-inputs drv))
-                            result))
-                 '()
-                 derivations)))
-           (unless (null? input-derivations)
-             ;; Ensure all the input derivations exist
-             (chunk-for-each!
-              (lambda (chunk)
-                (insert-missing-derivations
-                 postgresql-connection-pool
-                 call-with-utility-thread
-                 derivation-ids-hash-table
-                 chunk
-                 #:log-tag log-tag))
-              1000
-              input-derivations)))))
+       (insert-input-derivations derivations))
 
       (simple-format
        (current-error-port)
        "debug: insert-missing-derivations: done parallel (~A)\n" log-tag)
-      (with-resource-from-pool postgresql-connection-pool conn
-        (with-time-logging
-            (simple-format
-             #f "insert-missing-derivations: inserting inputs for ~A 
derivations (~A)"
-             (vector-length derivations)
-             log-tag)
-          (insert-derivation-inputs conn
-                                    derivation-ids
-                                    derivations))))))
+      (retry-on-missing-derivation-output
+       (lambda ()
+         (with-resource-from-pool postgresql-connection-pool conn
+           (with-time-logging
+               (simple-format
+                #f "insert-missing-derivations: inserting inputs for ~A 
derivations (~A)"
+                (vector-length derivations)
+                log-tag)
+             (insert-derivation-inputs conn
+                                       derivation-ids
+                                       derivations))))
+       #:on-exception
+       (lambda ()
+         ;; If this has happened because derivations have been removed, it
+         ;; might be necessary to insert them in the database where they
+         ;; previously existed
+         (hash-clear! derivation-ids-hash-table)
+         (insert-input-derivations derivations))))))
 
 (define (fix-derivation file-name)
   (define (derivation-missing-inputs? conn drv-id)
diff --git a/guix-data-service/model/derivation.scm 
b/guix-data-service/model/derivation.scm
index 215b46f..6ee7de1 100644
--- a/guix-data-service/model/derivation.scm
+++ b/guix-data-service/model/derivation.scm
@@ -21,6 +21,7 @@
   #:use-module (ice-9 vlist)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
+  #:use-module (ice-9 exceptions)
   #:use-module (ice-9 binary-ports)
   #:use-module (rnrs bytevectors)
   #:use-module (squee)
@@ -73,7 +74,12 @@
             update-derivation-inputs-statistics
             vacuum-derivation-inputs-table
             update-derivation-outputs-statistics
-            vacuum-derivation-outputs-table))
+            vacuum-derivation-outputs-table
+
+            &missing-derivation-output-error
+            missing-derivation-output-error?
+            missing-derivation-output-error-name
+            missing-derivation-output-error-path))
 
 (define (valid-targets conn)
   '("arm-linux-gnueabihf"
@@ -1128,12 +1134,19 @@ ON CONFLICT DO NOTHING"
                 (vector->list (json-string->scm env_vars)))
            system))))
 
+(define-exception-type &missing-derivation-output-error &error
+  make-derivation-output-error
+  missing-derivation-output-error?
+  (name missing-derivation-output-error-name)
+  (path missing-derivation-output-error-path))
+
 (define select-derivation-output-id
   (mlambda (conn name path)
     (match (exec-query
             conn
             "
-SELECT derivation_outputs.id FROM derivation_outputs
+SELECT derivation_outputs.id
+FROM derivation_outputs
 INNER JOIN derivations
   ON derivation_outputs.derivation_id = derivations.id
 WHERE derivations.file_name = $1
@@ -1143,9 +1156,8 @@ WHERE derivations.file_name = $1
       (((id))
        id)
       (()
-       (error (simple-format
-               #f "cannot find derivation-output with name ~A and path ~A"
-               name path))))))
+       (raise-exception
+        (make-derivation-output-error name path))))))
 
 (define (select-derivation-outputs-by-derivation-id conn id)
   (define query

Reply via email to