guix-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Mathieu Othacehe
Date: Tue, 24 Nov 2020 11:52:58 -0500 (EST)

branch: wip-offload
commit 89ef7a380354f16afe62bbcb91d4bffb893c37b6
Author: Mathieu Othacehe <othacehe@gnu.org>
AuthorDate: Thu Nov 19 11:33:19 2020 +0100

    offload support.
---
 bin/cuirass.in       | 159 ++++++++++++++++++++++++++-------------------------
 src/cuirass/base.scm |  49 +++++++++++++++-
 2 files changed, 127 insertions(+), 81 deletions(-)

diff --git a/bin/cuirass.in b/bin/cuirass.in
index aef4a65..5b1327a 100644
--- a/bin/cuirass.in
+++ b/bin/cuirass.in
@@ -141,84 +141,87 @@ exec ${GUILE:-@GUILE@} --no-auto-compile -e main -s "$0" 
"$@"
            (lambda ()
              (with-database
                (with-queue-writer-worker
-                (and specfile
-                     (let ((new-specs (save-module-excursion
-                                       (lambda ()
-                                         (set-current-module (make-user-module 
'()))
-                                         (primitive-load specfile)))))
-                       (for-each db-add-specification new-specs)))
-
-                (when queries-file
-                  (log-message "Enable SQL query logging.")
-                  (db-log-queries queries-file))
-
-                (if one-shot?
-                    (process-specs (db-get-specifications))
-                    (let ((exit-channel (make-channel)))
-                      (start-watchdog)
-                      (if (option-ref opts 'web #f)
-                          (begin
-                            (spawn-fiber
-                             (essential-task
-                              'web exit-channel
-                              (lambda ()
-                                (run-cuirass-server #:host host #:port port)))
-                             #:parallel? #t)
-
-                            (spawn-fiber
-                             (essential-task
-                              'monitor exit-channel
-                              (lambda ()
-                                (while #t
-                                  (log-monitoring-stats)
-                                  (sleep 600))))))
-
-                          (begin
-                            (clear-build-queue)
-
-                            ;; If Cuirass was stopped during an evaluation,
-                            ;; abort it. Builds that were not registered
-                            ;; during this evaluation will be registered
-                            ;; during the next evaluation.
-                            (db-abort-pending-evaluations)
-
-                            ;; First off, restart builds that had not
-                            ;; completed or were not even started on a
-                            ;; previous run.
-                            (spawn-fiber
-                             (essential-task
-                              'restart-builds exit-channel
-                              (lambda ()
-                                (restart-builds))))
-
-                            (spawn-fiber
-                             (essential-task
-                              'build exit-channel
-                              (lambda ()
-                                (while #t
-                                  (process-specs (db-get-specifications))
-                                  (log-message
-                                   "next evaluation in ~a seconds" interval)
-                                  (sleep interval)))))
-
-                            (spawn-fiber
-                             (essential-task
-                              'metrics exit-channel
-                              (lambda ()
-                                (while #t
-                                  (with-time-logging
-                                   "Metrics update"
-                                   (db-update-metrics))
-                                  (sleep 3600)))))
-
-                            (spawn-fiber
-                             (essential-task
-                              'monitor exit-channel
-                              (lambda ()
-                                (while #t
-                                  (log-monitoring-stats)
-                                  (sleep 600)))))))
-                      (primitive-exit (get-message exit-channel)))))))
+                 (with-build-offload-thread
+                  (and specfile
+                       (let ((new-specs (save-module-excursion
+                                         (lambda ()
+                                           (set-current-module
+                                            (make-user-module '()))
+                                           (primitive-load specfile)))))
+                         (for-each db-add-specification new-specs)))
+
+                  (when queries-file
+                    (log-message "Enable SQL query logging.")
+                    (db-log-queries queries-file))
+
+                  (if one-shot?
+                      (process-specs (db-get-specifications))
+                      (let ((exit-channel (make-channel)))
+                        (start-watchdog)
+                        (if (option-ref opts 'web #f)
+                            (begin
+                              (spawn-fiber
+                               (essential-task
+                                'web exit-channel
+                                (lambda ()
+                                  (run-cuirass-server #:host host
+                                                      #:port port)))
+                               #:parallel? #t)
+
+                              (spawn-fiber
+                               (essential-task
+                                'monitor exit-channel
+                                (lambda ()
+                                  (while #t
+                                    (log-monitoring-stats)
+                                    (sleep 600))))))
+
+                            (begin
+                              (clear-build-queue)
+
+                              ;; If Cuirass was stopped during an evaluation,
+                              ;; abort it. Builds that were not registered
+                              ;; during this evaluation will be registered
+                              ;; during the next evaluation.
+                              (db-abort-pending-evaluations)
+
+                              ;; First off, restart builds that had not
+                              ;; completed or were not even started on a
+                              ;; previous run.
+                              (spawn-fiber
+                               (essential-task
+                                'restart-builds exit-channel
+                                (lambda ()
+                                  (restart-builds))))
+
+                              (spawn-fiber
+                               (essential-task
+                                'build exit-channel
+                                (lambda ()
+                                  (while #t
+                                    (process-specs (db-get-specifications))
+                                    (log-message
+                                     "next evaluation in ~a seconds" interval)
+                                    (sleep interval)))))
+
+                              (spawn-fiber
+                               (essential-task
+                                'metrics exit-channel
+                                (lambda ()
+                                  (while #t
+                                    (with-time-logging
+                                     "Metrics update"
+                                     (db-update-metrics))
+                                    (sleep 3600)))))
+
+                              (spawn-fiber
+                               (essential-task
+                                'monitor exit-channel
+                                (lambda ()
+                                  (while #t
+                                    (log-monitoring-stats)
+                                    (sleep 600)))))))
+                        (primitive-exit (get-message exit-channel))))))))
 
            ;; Most of our code is I/O so preemption doesn't matter much (it
            ;; could help while we're doing SQL requests, for instance, but it
diff --git a/src/cuirass/base.scm b/src/cuirass/base.scm
index 1966ad6..e9bd943 100644
--- a/src/cuirass/base.scm
+++ b/src/cuirass/base.scm
@@ -22,6 +22,7 @@
 
 (define-module (cuirass base)
   #:use-module (fibers)
+  #:use-module (fibers channels)
   #:use-module (cuirass logging)
   #:use-module (cuirass database)
   #:use-module (cuirass utils)
@@ -29,6 +30,7 @@
   #:use-module (gnu packages)
   #:use-module (guix build utils)
   #:use-module (guix derivations)
+  #:use-module (guix offload)
   #:use-module (guix store)
   #:use-module (guix git)
   #:use-module (guix cache)
@@ -36,9 +38,13 @@
   #:use-module ((guix config) #:select (%state-directory))
   #:use-module (git)
   #:use-module (ice-9 binary-ports)
+  #:use-module ((ice-9 suspendable-ports)
+                #:select (current-read-waiter
+                          current-write-waiter))
   #:use-module (ice-9 format)
   #:use-module (ice-9 match)
   #:use-module (ice-9 popen)
+  #:use-module (ice-9 ports internal)
   #:use-module (ice-9 rdelim)
   #:use-module (ice-9 receive)
   #:use-module (ice-9 regex)
@@ -65,6 +71,7 @@
             prepare-git
             process-specs
             evaluation-log-file
+            with-build-offload-thread
 
             ;; Parameters.
             %package-cachedir
@@ -110,6 +117,9 @@
   ;; Define whether to fall back to building when the substituter fails.
   (make-parameter #f))
 
+(define %build-offload-channel
+  (make-parameter #f))
+
 (define %package-cachedir
   ;; Define to location of cache directory of this package.
   (make-parameter (or (getenv "CUIRASS_CACHEDIR")
@@ -436,6 +446,36 @@ Essentially this procedure inverts the 
inversion-of-control that
                   (raise c))
                  (x x)))))))
 
+(define (make-build-offload-thread)
+  (let ((channel (make-channel)))
+    (call-with-new-thread
+     (lambda ()
+       (parameterize (((@@ (fibers internal) current-fiber) #f)
+                      (current-read-waiter (lambda (port)
+                                             (port-poll port "r")))
+                      (current-write-waiter (lambda (port)
+                                              (port-poll port "w"))))
+         (let ((socket (offload-socket)))
+           (let loop ()
+             (offload-poll socket handle-build-event
+                           #:cache-directory "/tmp/offload")
+             (match (get-message-with-timeout channel
+                                              #:seconds 1
+                                              #:retry? #f)
+               ((drvs . systems)
+                (offload-build socket drvs systems))
+               ('timeout #f))
+             (loop))))))
+    channel))
+
+(define-syntax-rule (with-build-offload-thread body ...)
+  (parameterize ((%build-offload-channel
+                  (make-build-offload-thread)))
+    body ...))
+
+(define (build-derivations/offload drvs systems)
+  (put-message (%build-offload-channel) (cons drvs systems)))
+
 
 ;;;
 ;;; Building packages.
@@ -641,7 +681,9 @@ started)."
       ;; Those in VALID can be restarted.  If some of them were built in the
       ;; meantime behind our back, that's fine: 'spawn-builds' will DTRT.
       (log-message "restarting ~a pending builds" (length valid))
-      (spawn-builds store valid)
+      (let* ((builds (filter-map (cut db-get-build <>) valid))
+             (systems (map (cut assq-ref <> #:system) builds)))
+        (build-derivations/offload valid systems))
       (log-message "done with restarted builds"))))
 
 (define (create-build-outputs build product-specs)
@@ -734,8 +776,9 @@ by PRODUCT-SPECS."
                  (log-message "fetching input '~a' of spec '~a'"
                               (assq-ref input #:name)
                               (assq-ref spec #:name))
-                 (fetch-input store input
-                              #:writable-copy? (compile? input)))))
+                 (parameterize ((current-error-port (%make-void-port "rw+")))
+                   (fetch-input store input
+                                #:writable-copy? (compile? input))))))
            inputs))
          (results (map %non-blocking thunks)))
     (map (lambda (checkout)



reply via email to

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