diff options
Diffstat (limited to 'guix/store.scm')
-rw-r--r-- | guix/store.scm | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/guix/store.scm b/guix/store.scm index 8746d3c2d6..ae52628545 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -27,6 +27,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-9 gnu) + #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) @@ -93,6 +94,7 @@ path-info-nar-size references + references/substitutes requisites referrers optimize-store @@ -502,8 +504,12 @@ encoding conversion errors." (status k)))))))) (define %default-substitute-urls - ;; Default list of substituters. - '("http://hydra.gnu.org")) + ;; Default list of substituters. This is *not* the list used by + ;; 'guix-daemon', and few clients use it ('guix build --log-file' uses it.) + (map (if (false-if-exception (resolve-interface '(gnutls))) + (cut string-append "https://" <>) + (cut string-append "http://" <>)) + '("hydra.gnu.org"))) (define* (set-build-options server #:key keep-failed? keep-going? fallback? @@ -724,6 +730,63 @@ error if there is no such root." "Return the list of references of PATH." store-path-list)) +(define %reference-cache + ;; Brute-force cache mapping store items to their list of references. + ;; Caching matters because when building a profile in the presence of + ;; grafts, we keep calling 'graft-derivation', which in turn calls + ;; 'references/substitutes' many times with the same arguments. Ideally we + ;; would use a cache associated with the daemon connection instead (XXX). + (make-hash-table 100)) + +(define (references/substitutes store items) + "Return the list of list of references of ITEMS; the result has the same +length as ITEMS. Query substitute information for any item missing from the +store at once. Raise a '&nix-protocol-error' exception if reference +information for one of ITEMS is missing." + (let* ((local-refs (map (lambda (item) + (or (hash-ref %reference-cache item) + (guard (c ((nix-protocol-error? c) #f)) + (references store item)))) + items)) + (missing (fold-right (lambda (item local-ref result) + (if local-ref + result + (cons item result))) + '() + items local-refs)) + + ;; Query all the substitutes at once to minimize the cost of + ;; launching 'guix substitute' and making HTTP requests. + (substs (substitutable-path-info store missing))) + (when (< (length substs) (length missing)) + (raise (condition (&nix-protocol-error + (message "cannot determine \ +the list of references") + (status 1))))) + + ;; Intersperse SUBSTS and LOCAL-REFS. + (let loop ((items items) + (local-refs local-refs) + (result '())) + (match items + (() + (let ((result (reverse result))) + (for-each (cut hash-set! %reference-cache <> <>) + items result) + result)) + ((item items ...) + (match local-refs + ((#f tail ...) + (loop items tail + (cons (any (lambda (subst) + (and (string=? (substitutable-path subst) item) + (substitutable-references subst))) + substs) + result))) + ((head tail ...) + (loop items tail + (cons head result))))))))) + (define* (fold-path store proc seed path #:optional (relatives (cut references store <>))) "Call PROC for each of the RELATIVES of PATH, exactly once, and return the @@ -811,7 +874,9 @@ topological order." (operation (query-substitutable-path-infos (store-path-list paths)) "Return information about the subset of PATHS that is substitutable. For each substitutable path, a `substitutable?' object is -returned." +returned; thus, the resulting list can be shorter than PATHS. Furthermore, +that there is no guarantee that the order of the resulting list matches the +order of PATHS." substitutable-path-list)) (define-operation (optimize-store) |