summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Othacehe <othacehe@gnu.org>2020-09-25 11:00:11 +0200
committerMathieu Othacehe <othacehe@gnu.org>2020-09-28 09:38:15 +0200
commit461e07e14e1c8013343c0a2cb26c0e022e10d5e4 (patch)
tree13e8be6175f69202389690375857cb1fd7594897
parentd1386d85ca54d77c68709a661170bce3bbe29f1d (diff)
downloadcuirass-461e07e14e1c8013343c0a2cb26c0e022e10d5e4.tar
cuirass-461e07e14e1c8013343c0a2cb26c0e022e10d5e4.tar.gz
Limit builds insertion queries.
Once the evaluation is over, the new builds are registered. This registration tries to insert a new build for each derivation returned by the evaluation phase. If the new build does not add a new output, the insertion query is then rollbacked. This means that there are at least as many insertion queries as new derivations. SQlite allows at most one writer at a time, and even though we are using WAL mode, performing a lot of insertions will reduce the reading perforances. When multiple evaluations are performed in parallel, the large number of concurrent insertion queries also causes contention. To avoid those issues, check first in the "Outputs" table which derivations are already registered. This means that most of the insertion queries will be replaced by reading queries, that are much less expensive and more suitable for Cuirass concurrent implementation. * src/cuirass/base.scm (new-outputs?): New procedure. (build-packages): Use it to insert only builds registering new outputs.
-rw-r--r--src/cuirass/base.scm46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/cuirass/base.scm b/src/cuirass/base.scm
index bce151a..9b9d89f 100644
--- a/src/cuirass/base.scm
+++ b/src/cuirass/base.scm
@@ -694,6 +694,17 @@ by PRODUCT-SPECS."
(#:path . ,product))))))
product-specs))
+(define (new-outputs? outputs)
+ "Return #t if OUTPUTS contains at least one unregistered output and #f
+otherwise."
+ (let ((new-outputs
+ (filter-map (match-lambda
+ ((name . path)
+ (let ((drv (db-get-output path)))
+ (and (not drv) path))))
+ outputs)))
+ (not (null? new-outputs))))
+
(define (build-packages store jobs eval-id)
"Build JOBS and return a list of Build results."
(define (register job)
@@ -711,25 +722,26 @@ by PRODUCT-SPECS."
`(,name . ,path))))
(derivation-path->output-paths drv)))
(cur-time (time-second (current-time time-utc))))
- (let ((build `((#:derivation . ,drv)
- (#:eval-id . ,eval-id)
- (#:job-name . ,job-name)
- (#:system . ,system)
- (#:nix-name . ,nix-name)
-
- ;; XXX: We'd leave LOG to #f (i.e., NULL) but that
- ;; currently violates the non-NULL constraint.
- (#:log . ,(or log ""))
-
- (#:status . ,(build-status scheduled))
- (#:outputs . ,outputs)
- (#:timestamp . ,cur-time)
- (#:starttime . 0)
- (#:stoptime . 0))))
- (db-add-build build))))
+ (and (new-outputs? outputs)
+ (let ((build `((#:derivation . ,drv)
+ (#:eval-id . ,eval-id)
+ (#:job-name . ,job-name)
+ (#:system . ,system)
+ (#:nix-name . ,nix-name)
+
+ ;; XXX: We'd leave LOG to #f (i.e., NULL) but that
+ ;; currently violates the non-NULL constraint.
+ (#:log . ,(or log ""))
+
+ (#:status . ,(build-status scheduled))
+ (#:outputs . ,outputs)
+ (#:timestamp . ,cur-time)
+ (#:starttime . 0)
+ (#:stoptime . 0))))
+ (db-add-build build)))))
(define derivations
- (filter-map register jobs))
+ (with-time-logging "registration" (filter-map register jobs)))
(log-message "evaluation ~a registered ~a new derivations"
eval-id (length derivations))