diff options
author | Christopher Baines <mail@cbaines.net> | 2023-04-17 09:46:20 +0100 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2023-04-17 09:46:20 +0100 |
commit | 2efcd8b11954708f0b2f26ce6eb9d785e2f6aae4 (patch) | |
tree | 6247fd68a9b6f2afcdd94e2094c2ea479a351187 /guix-build-coordinator/utils.scm | |
parent | 8415837c306f80916485168f56c555b6c6d7cf86 (diff) | |
download | build-coordinator-2efcd8b11954708f0b2f26ce6eb9d785e2f6aae4.tar build-coordinator-2efcd8b11954708f0b2f26ce6eb9d785e2f6aae4.tar.gz |
Attempt to make with-port-timeouts handle the GC restarting poll
From what I'm seeing in strace, I think the GC is breaking the timeout
behaviour by restarting the syscall, these changes should work around that
behaviour.
Diffstat (limited to 'guix-build-coordinator/utils.scm')
-rw-r--r-- | guix-build-coordinator/utils.scm | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/guix-build-coordinator/utils.scm b/guix-build-coordinator/utils.scm index e16b41a..0d2e39d 100644 --- a/guix-build-coordinator/utils.scm +++ b/guix-build-coordinator/utils.scm @@ -309,17 +309,36 @@ upcoming chunk." (record-predicate &port-timeout)) (define* (with-port-timeouts thunk #:key (timeout (* 120 1000))) + + ;; When the GC runs, it restarts the poll syscall, but the timeout remains + ;; unchanged! When the timeout is longer than the time between the syscall + ;; restarting, I think this renders the timeout useless. Therefore, this + ;; code uses a short timeout, and repeatedly calls poll while watching the + ;; clock to see if it has timed out overall. + (define poll-timeout-ms 200) + + (define (wait port mode) + (let ((timeout-internal + (+ (get-internal-real-time) + (* internal-time-units-per-second + (/ timeout 1000))))) + (let loop ((poll-value + (port-poll port mode poll-timeout-ms))) + (if (= poll-value 0) + (if (> (get-internal-real-time) + timeout-internal) + (raise-exception + (make-port-timeout-error)) + (loop (port-poll port mode poll-timeout-ms))) + poll-value)))) + (parameterize ((current-read-waiter (lambda (port) - (when (= (port-poll port "r" timeout) 0) - (raise-exception - (make-port-timeout-error))))) + (wait port "r"))) (current-write-waiter (lambda (port) - (when (= (port-poll port "w" timeout) 0) - (raise-exception - (make-port-timeout-error)))))) + (wait port "w")))) (thunk))) (define* (set-store-connection-timeout store #:key (timeout 120)) |