diff options
author | Christopher Baines <mail@cbaines.net> | 2020-04-26 16:19:12 +0100 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2020-04-26 16:19:12 +0100 |
commit | 48ed0eead59119c269993dbfa2c9ca8302b52d3d (patch) | |
tree | 23e65d6c2347789a83984c8e2a29b48a8bdfac84 | |
parent | 3ee79ba7b683275ef066f4d61b1ce50b64bd19ac (diff) | |
download | build-coordinator-48ed0eead59119c269993dbfa2c9ca8302b52d3d.tar build-coordinator-48ed0eead59119c269993dbfa2c9ca8302b52d3d.tar.gz |
Read chunked request bodies in different threads to avoid blocking
Not sure if this'll work, but hopefully offloading reading the chunked
requests to other threads will avoid blocking.
-rw-r--r-- | guix-build-coordinator/agent-messaging/http.scm | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/guix-build-coordinator/agent-messaging/http.scm b/guix-build-coordinator/agent-messaging/http.scm index 75689c2..7d96054 100644 --- a/guix-build-coordinator/agent-messaging/http.scm +++ b/guix-build-coordinator/agent-messaging/http.scm @@ -80,6 +80,12 @@ if there was no request body." (define hook-channel (make-hook-channel datastore hooks)) + (define chunked-request-channel + ;; I can't work out how to stop the blocking when reading the chunked + ;; request bodies, so just do it in a different thread. + (make-worker-thread-channel (const '()) + #:parallelism 4)) + (trigger-build-allocation) (call-with-error-handling (lambda () @@ -98,7 +104,8 @@ if there was no request body." secret-key-base datastore trigger-build-allocation - hook-channel))) + hook-channel + chunked-request-channel))) 'fibers (list #:host host #:port port))) @@ -146,7 +153,8 @@ port. Also, the port used can be changed by passing the --port option.\n" secret-key-base datastore trigger-build-allocation - hook-channel) + hook-channel + chunked-request-channel) (define (authenticated? uuid request) (let* ((authorization-base64 (match (assq-ref (request-headers request) @@ -233,15 +241,21 @@ port. Also, the port used can be changed by passing the --port option.\n" (let ((output-file-name (build-log-file-location datastore uuid format))) (mkdir-p (dirname output-file-name)) - (call-with-output-file output-file-name - (lambda (output-port) - (let loop ((line (get-line body))) - (unless (eof-object? line) - (base64-decode line - base64-alphabet - output-port) - (loop (get-line body)))))) - (no-content)) + (if (call-with-worker-thread + chunked-request-channel + (lambda () + (call-with-output-file output-file-name + (lambda (output-port) + (let loop ((line (get-line body))) + (unless (eof-object? line) + (base64-decode line + base64-alphabet + output-port) + (loop (get-line body)))))))) + (no-content) + (render-json + "error" + #:code 500))) (render-json "access denied" #:code 403)))) @@ -252,15 +266,22 @@ port. Also, the port used can be changed by passing the --port option.\n" (let ((output-file-name (build-output-file-location datastore uuid output-name))) (mkdir-p (dirname output-file-name)) - (call-with-output-file output-file-name - (lambda (output-port) - (let loop ((line (get-line body))) - (unless (eof-object? line) - (base64-decode line - base64-alphabet - output-port) - (loop (get-line body)))))) - (no-content)) + (if (call-with-worker-thread + chunked-request-channel + (lambda () + (call-with-output-file output-file-name + (lambda (output-port) + (let loop ((line (get-line body))) + (unless (eof-object? line) + (base64-decode line + base64-alphabet + output-port) + (loop (get-line body)))))) + #t)) + (no-content) + (render-json + "error" + #:code 500))) (render-json "access denied" #:code 403)))) |