diff options
Diffstat (limited to 'guix-build-coordinator/agent-messaging/http.scm')
-rw-r--r-- | guix-build-coordinator/agent-messaging/http.scm | 120 |
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 |