aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/agent-messaging/http.scm
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2021-11-16 20:35:54 +0000
committerChristopher Baines <mail@cbaines.net>2021-11-16 20:35:54 +0000
commitb37a051b82efbc0c521c533176e22bf68fd7e18f (patch)
tree231c920c5ad7e0e7492c6ca9a97e1bd2b0c60e52 /guix-build-coordinator/agent-messaging/http.scm
parent1288d9c1185bd1111e2fee9459714178a2cb8f13 (diff)
downloadbuild-coordinator-b37a051b82efbc0c521c533176e22bf68fd7e18f.tar
build-coordinator-b37a051b82efbc0c521c533176e22bf68fd7e18f.tar.gz
Check if an output has been uploaded before trying to upload it
This can help if the output has been uploaded, but the hash isn't present, since trying to submit the build result will prompt for the output to be sent again, but it doesn't need to be, the agent just needs to wait. This is a little inelegant, maybe there needs to be some way for the agent to explicitly check for the hash to be computed, but I'm hoping these changes will help with uploading large outputs.
Diffstat (limited to 'guix-build-coordinator/agent-messaging/http.scm')
-rw-r--r--guix-build-coordinator/agent-messaging/http.scm120
1 files changed, 69 insertions, 51 deletions
diff --git a/guix-build-coordinator/agent-messaging/http.scm b/guix-build-coordinator/agent-messaging/http.scm
index 9116b05..ac45ca3 100644
--- a/guix-build-coordinator/agent-messaging/http.scm
+++ b/guix-build-coordinator/agent-messaging/http.scm
@@ -267,6 +267,19 @@
#f
(response-content-length response))))
+ (define (get-completed-upload-bytes)
+ (let-values (((body response)
+ (coordinator-http-request
+ log
+ interface
+ (string-append "/build/" build-id
+ "/output/" output-name)
+ #:method 'HEAD)))
+ (if (eq? (response-code response)
+ 404)
+ #f
+ (response-content-length response))))
+
(define auth-value
(string-append
"Basic "
@@ -286,57 +299,62 @@
(with-store store
(query-path-info store file)))
- (let* ((directory (or (getenv "TMPDIR") "/tmp"))
- (template (string-append directory
- "/guix-build-coordinator-file.XXXXXX"))
- (out (mkstemp! template)))
- (log 'INFO "compressing " file " -> " template " prior to sending")
- (call-with-lzip-output-port out
- (lambda (port)
- (write-file file port))
- #:level 9)
- (close-port out)
-
- (log 'INFO "finished compressing " file ", now sending")
- (retry-on-error
- (lambda ()
- (let ((bytes (get-partial-upload-bytes)))
- ;; Check if the server has all the bytes
- (unless (and bytes
- (eq? bytes (stat:size (stat template))))
-
- ;; Still more to send
- (call-with-input-file template
- (lambda (file-port)
- (when bytes
- (seek file-port bytes SEEK_SET)
- (log 'INFO "resuming upload from byte " bytes))
-
- (let-values (((response body)
- (call-with-streaming-http-request
- (uri #:resume? (integer? bytes))
- (lambda (port)
- (with-time-logging
- (simple-format #f "sending ~A" file)
- (dump-port file-port port
- #:buffer-size 65536)))
- #:headers `((Authorization . ,auth-value))
- #:method (if bytes 'POST 'PUT)
- #:report-bytes-sent report-bytes-sent)))
- (when (>= (response-code response) 400)
- (raise-exception
- (make-exception-with-message
- (coordinator-handle-failed-request
- log
- 'PUT
- (uri-path
- (uri #:resume? (integer? bytes)))
- response
- body))))))))))
- #:times 100
- #:delay (random 15))
-
- (delete-file template)))
+ (define (perform-upload)
+ (let* ((directory (or (getenv "TMPDIR") "/tmp"))
+ (template (string-append directory
+ "/guix-build-coordinator-file.XXXXXX"))
+ (out (mkstemp! template)))
+ (log 'INFO "compressing " file " -> " template " prior to sending")
+ (call-with-lzip-output-port out
+ (lambda (port)
+ (write-file file port))
+ #:level 9)
+ (close-port out)
+
+ (log 'INFO "finished compressing " file ", now sending")
+ (retry-on-error
+ (lambda ()
+ (let ((bytes (or (get-partial-upload-bytes)
+ (get-completed-upload-bytes))))
+ ;; Check if the server has all the bytes
+ (unless (and bytes
+ (eq? bytes (stat:size (stat template))))
+
+ ;; Still more to send
+ (call-with-input-file template
+ (lambda (file-port)
+ (when bytes
+ (seek file-port bytes SEEK_SET)
+ (log 'INFO "resuming upload from byte " bytes))
+
+ (let-values (((response body)
+ (call-with-streaming-http-request
+ (uri #:resume? (integer? bytes))
+ (lambda (port)
+ (with-time-logging
+ (simple-format #f "sending ~A" file)
+ (dump-port file-port port
+ #:buffer-size 65536)))
+ #:headers `((Authorization . ,auth-value))
+ #:method (if bytes 'POST 'PUT)
+ #:report-bytes-sent report-bytes-sent)))
+ (when (>= (response-code response) 400)
+ (raise-exception
+ (make-exception-with-message
+ (coordinator-handle-failed-request
+ log
+ 'PUT
+ (uri-path
+ (uri #:resume? (integer? bytes)))
+ response
+ body))))))))))
+ #:times 100
+ #:delay (random 15))
+
+ (delete-file template)))
+
+ (unless (get-completed-upload-bytes)
+ (perform-upload)))
args))
(define-method (submit-log-file