me
/
guix
Archived
1
0
Fork 0

inferior: Inferior caches store connections.

Fixes <https://issues.guix.gnu.org/48007>.
Reported by Ricardo Wurmus <rekado@elephly.net>.

Previously, at each 'inferior-eval-with-store' call, the inferior would
create a new <store-connection> object with empty caches.  Consequently,
when repeatedly calling 'inferior-package-derivation', we would not
benefit from any caching and instead recompute all the derivations for
every package.  This patch fixes it by caching <store-connection>
objects in the inferior.

* guix/inferior.scm (port->inferior): Define '%store-table' in the inferior.
(inferior-eval-with-store): Cache store connections in %STORE-TABLE.
Remove now unneeded 'dynamic-wind' with 'close-port' call.
Ludovic Courtès 2022-01-27 08:55:59 +01:00
parent bd86bbd300
commit c71910a095
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 33 additions and 21 deletions

View File

@ -225,6 +225,8 @@ inferior."
(inferior-eval '(use-modules (srfi srfi-34)) result)
(inferior-eval '(define %package-table (make-hash-table))
result)
(inferior-eval '(define %store-table (make-hash-table))
result)
result))
(_
#f)))
@ -617,7 +619,12 @@ process."
thus be the code of a one-argument procedure that accepts a store."
(let* ((major (store-connection-major-version store))
(minor (store-connection-minor-version store))
(proto (logior major minor)))
(proto (logior major minor))
;; The address of STORE itself is not a good identifier because it
;; keeps changing through the use of "functional caches". The
;; address of its socket port makes more sense.
(store-id (object-address (store-connection-socket store))))
(ensure-store-bridge! inferior)
(send-inferior-request
`(let ((proc ,code)
@ -628,26 +635,31 @@ thus be the code of a one-argument procedure that accepts a store."
store-protocol-error-message
nix-protocol-error-message)))
;; 'port->connection' appeared in June 2018 and we can hardly
;; emulate it on older versions. Thus fall back to
;; 'open-connection', at the risk of talking to the wrong daemon or
;; having our build result reclaimed (XXX).
(let ((store (if (defined? 'port->connection)
(port->connection %bridge-socket #:version ,proto)
(open-connection))))
(dynamic-wind
(const #t)
(lambda ()
;; Serialize '&store-protocol-error' conditions. The
;; exception serialization mechanism that
;; 'read-repl-response' expects is unsuitable for SRFI-35
;; error conditions, hence this special case.
(guard (c ((error? c)
`(store-protocol-error ,(error-message c))))
`(result ,(proc store))))
(lambda ()
(unless (defined? 'port->connection)
(close-port store))))))
;; Cache connections to STORE-ID. This ensures that the caches within
;; <store-connection> (in particular the object cache) are reused
;; across calls to 'inferior-eval-with-store', which makes a
;; significant difference when it is called repeatedly.
(let ((store (or (hashv-ref %store-table ,store-id)
;; 'port->connection' appeared in June 2018 and we
;; can hardly emulate it on older versions. Thus
;; fall back to 'open-connection', at the risk of
;; talking to the wrong daemon or having our build
;; result reclaimed (XXX).
(let ((store (if (defined? 'port->connection)
(port->connection %bridge-socket
#:version ,proto)
(open-connection))))
(hashv-set! %store-table ,store-id store)
store))))
;; Serialize '&store-protocol-error' conditions. The
;; exception serialization mechanism that
;; 'read-repl-response' expects is unsuitable for SRFI-35
;; error conditions, hence this special case.
(guard (c ((error? c)
`(store-protocol-error ,(error-message c))))
`(result ,(proc store)))))
inferior)
(proxy inferior store)