summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2017-01-09 22:41:59 +0100
committerLudovic Courtès <ludo@gnu.org>2017-01-11 10:13:32 +0100
commitc490a0b03768231d15f6b9b9df70a92e8fa6a9cb (patch)
treed9d653bec8a9af7edec456fcb0241ad573df0e0c
parentea7b5a8f3d3f5d66ba9c45fb0bc76d25b6ba916f (diff)
downloadguix-c490a0b03768231d15f6b9b9df70a92e8fa6a9cb.tar.gz
DRAFT store: Add support for build continuations.
TODO: Add tests; update guix.texi.

* guix/store.scm (<nix-server>)[continuations]: New field.
(open-connection): Adjust accordingly.
(set-build-continuation!, build-continuation): New procedures.
(build-things): Rename to...
(%build-things): ... this.
(build-things, set-build-continuation): New procedures.
* guix/derivations.scm (build-derivations): Add #:continuation?
parameter and pass it to 'built-things'.  Convert the return value to a
list of store items.
-rw-r--r--guix/derivations.scm29
-rw-r--r--guix/store.scm54
2 files changed, 72 insertions, 11 deletions
diff --git a/guix/derivations.scm b/guix/derivations.scm
index d5e4b5730b..c2a74b3a75 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -989,15 +989,28 @@ recursively."
 ;;;
 
 (define* (build-derivations store derivations
-                            #:optional (mode (build-mode normal)))
+                            #:optional (mode (build-mode normal))
+                            #:key (continuations? #t))
   "Build DERIVATIONS, a list of <derivation> objects or .drv file names, using
-the specified MODE."
-  (build-things store (map (match-lambda
-                            ((? string? file) file)
-                            ((and drv ($ <derivation>))
-                             (derivation-file-name drv)))
-                           derivations)
-                mode))
+the specified MODE.  When CONTINUATIONS? is true, run the \"build
+continuations\" of each of DERIVATIONS.  Return the list of store items that
+were built."
+  (let ((things (build-things store (map (match-lambda
+                                           ((? string? file) file)
+                                           ((and drv ($ <derivation>))
+                                            (derivation-file-name drv)))
+                                         derivations)
+                              mode)))
+    ;; Convert the list of .drv file names to a list of output file names.
+    (append-map (match-lambda
+                  ((? derivation-path? drv)
+                   (let ((drv (call-with-input-file drv read-derivation)))
+                     (match (derivation->output-paths drv)
+                       (((outputs . items) ...)
+                        items))))
+                  (x
+                   (list x)))
+                things)))
 
 
 ;;;
diff --git a/guix/store.scm b/guix/store.scm
index 49549d0771..98478bc38f 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -71,6 +71,8 @@
             add-to-store
             build-things
             build
+            set-build-continuation!
+            set-build-continuation
             query-failed-paths
             clear-failed-paths
             add-temp-root
@@ -312,12 +314,16 @@
 
 (define-record-type <nix-server>
   (%make-nix-server socket major minor
-                    ats-cache atts-cache)
+                    continuations ats-cache atts-cache)
   nix-server?
   (socket nix-server-socket)
   (major  nix-server-major-version)
   (minor  nix-server-minor-version)
 
+  ;; Hash table that maps store items to a "build continuation" for that store
+  ;; item.
+  (continuations nix-server-build-continuations)
+
   ;; Caches.  We keep them per-connection, because store paths build
   ;; during the session are temporary GC roots kept for the duration of
   ;; the session.
@@ -400,6 +406,7 @@ for this connection will be pinned.  Return a server object."
                                                     (protocol-major v)
                                                     (protocol-minor v)
                                                     (make-hash-table 100)
+                                                    (make-hash-table 100)
                                                     (make-hash-table 100))))
                         (let loop ((done? (process-stderr conn)))
                           (or done? (process-stderr conn)))
@@ -720,7 +727,19 @@ where FILE is the entry's absolute file name and STAT is the result of
               (hash-set! cache args path)
               path))))))
 
-(define build-things
+(define (set-build-continuation! store item proc)
+  "Register PROC as a \"build continuation\" for when ITEM is built on STORE.
+When 'build-things' is passed ITEM, it calls (PROC STORE ITEM), which must
+return a list of store items to build."
+  (hash-set! (nix-server-build-continuations store) item proc))
+
+(define (build-continuation store item)
+  "Return the procedure that implements a \"build continuation\" for ITEM, or
+#f if there is none."
+  (hash-ref (nix-server-build-continuations store) item))
+
+(define %build-things
+  ;; This is the raw RPC.
   (let ((build (operation (build-things (string-list things)
                                         (integer mode))
                           "Do it!"
@@ -741,6 +760,29 @@ Return #t on success."
                                  (message "unsupported build mode")
                                  (status  1)))))))))
 
+(define* (build-things store things
+                       #:optional (mode (build-mode normal))
+                       #:key (continuations? #t))
+  "Build THINGS, a list of store items which may be either '.drv' files or
+outputs, and return when the worker is done building them.  Elements of THINGS
+that are not derivations can only be substituted and not built locally.  When
+CONTINUATIONS? is true, run the \"build continuations\" of THINGS.  Return the
+list of store items built."
+  (let loop ((things things)
+             (built '()))
+    (match things
+      (()
+       built)
+      (_
+       (and (%build-things store things mode)
+            (loop (append-map (lambda (thing)
+                                (let ((proc (build-continuation store thing)))
+                                  (if proc
+                                      (proc store thing)
+                                      '())))
+                              things)
+                  things))))))
+
 (define-operation (add-temp-root (store-path path))
   "Make PATH a temporary root for the duration of the current session.
 Return #t."
@@ -1184,6 +1226,12 @@ where FILE is the entry's absolute file name and STAT is the result of
   ;; Monadic variant of 'build-things'.
   (store-lift build-things))
 
+(define (set-build-continuation item proc)
+  "Register monadic thunk PROC as a \"build continuation\" for ITEM."
+  (lambda (store)
+    (set-build-continuation! store item (store-lower proc))
+    (values *unspecified* store)))
+
 (define set-build-options*
   (store-lift set-build-options))