aboutsummaryrefslogtreecommitdiff
path: root/guix-build-coordinator/agent-messaging/http.scm
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2021-11-14 14:29:01 +0000
committerChristopher Baines <mail@cbaines.net>2021-11-14 14:29:01 +0000
commite4f6b6061c7a04944c7d7ba0bc0fb0a878b207ca (patch)
tree89e70cbdaf63fb53863f700c9a71cc14b5ee7c85 /guix-build-coordinator/agent-messaging/http.scm
parent898a87c9fa4089fc3648ffe721df15f7719e02fe (diff)
downloadbuild-coordinator-e4f6b6061c7a04944c7d7ba0bc0fb0a878b207ca.tar
build-coordinator-e4f6b6061c7a04944c7d7ba0bc0fb0a878b207ca.tar.gz
Implement initial support for resuming HTTP uploads
This means agents reattempting uploads don't have to start from scratch, and can instead pick up from what's already been uploaded to the coordinator.
Diffstat (limited to 'guix-build-coordinator/agent-messaging/http.scm')
-rw-r--r--guix-build-coordinator/agent-messaging/http.scm62
1 files changed, 42 insertions, 20 deletions
diff --git a/guix-build-coordinator/agent-messaging/http.scm b/guix-build-coordinator/agent-messaging/http.scm
index a29c908..2252293 100644
--- a/guix-build-coordinator/agent-messaging/http.scm
+++ b/guix-build-coordinator/agent-messaging/http.scm
@@ -253,6 +253,20 @@
#:key
(log default-log)
report-bytes-sent)
+ (define (get-partial-upload-bytes)
+ (let-values (((body response)
+ (coordinator-http-request
+ log
+ interface
+ (string-append "/build/" build-id
+ "/output/" output-name
+ "/partial")
+ #:method 'HEAD)))
+ (if (eq? (response-code response)
+ 404)
+ #f
+ (response-content-length response))))
+
(define auth-value
(string-append
"Basic "
@@ -262,10 +276,11 @@
":"
(slot-ref interface 'password))))))
- (define uri
+ (define* (uri #:key resume?)
(coordinator-uri-for-path
(slot-ref interface 'coordinator-uri)
- (string-append "/build/" build-id "/output/" output-name)))
+ (string-append "/build/" build-id "/output/" output-name
+ (if resume? "/partial" ""))))
(define path-info
(with-store store
@@ -287,24 +302,31 @@
(lambda ()
(call-with-input-file template
(lambda (file-port)
- (let-values (((response body)
- (call-with-streaming-http-request
- uri
- (lambda (port)
- (with-time-logging
- (simple-format #f "sending ~A" file)
- (dump-port file-port port
- #:buffer-size 65536)))
- #:headers `((Authorization . ,auth-value)))))
- (when (>= (response-code response) 400)
- (raise-exception
- (make-exception-with-message
- (coordinator-handle-failed-request log
- 'PUT
- (uri-path uri)
- response
- body))))))))
- #:times 12
+ (let ((bytes (get-partial-upload-bytes)))
+ (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 (lambda (bytes) (when (eq? bytes 65536) (error "FOO"))))))
+ (when (>= (response-code response) 400)
+ (raise-exception
+ (make-exception-with-message
+ (coordinator-handle-failed-request log
+ 'PUT
+ (uri-path uri)
+ response
+ body)))))))))
+ #:times 100
#:delay (random 15))
(delete-file template)))