diff options
author | Christopher Baines <mail@cbaines.net> | 2023-05-02 15:10:05 +0200 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2023-05-02 15:10:05 +0200 |
commit | 5a17584c6a0dcf2fb05817c53ed005b6ee5b5306 (patch) | |
tree | a3e2cd4d4055a2b8ae5dbd69bfb8ea595ce25359 /guix-build-coordinator/utils | |
parent | 7ef920a7616bb6703e59bf67e88e8da4b0c40670 (diff) | |
download | build-coordinator-5a17584c6a0dcf2fb05817c53ed005b6ee5b5306.tar build-coordinator-5a17584c6a0dcf2fb05817c53ed005b6ee5b5306.tar.gz |
Add a timeout for using the worker threads
Otherwise operations can build up while the thread pool is busy, and this'll
hopefully make it clearer when there are issues with the thread pools.
Diffstat (limited to 'guix-build-coordinator/utils')
-rw-r--r-- | guix-build-coordinator/utils/fibers.scm | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/guix-build-coordinator/utils/fibers.scm b/guix-build-coordinator/utils/fibers.scm index 921da8d..4a7572d 100644 --- a/guix-build-coordinator/utils/fibers.scm +++ b/guix-build-coordinator/utils/fibers.scm @@ -2,11 +2,14 @@ #:use-module (ice-9 match) #:use-module (ice-9 threads) #:use-module (fibers) + #:use-module (fibers timers) #:use-module (fibers channels) + #:use-module (fibers operations) #:use-module (fibers conditions) #:use-module (guix-build-coordinator utils) #:export (make-worker-thread-channel call-with-worker-thread + worker-thread-timeout-error? call-with-sigint @@ -100,14 +103,46 @@ arguments of the worker thread procedure." (iota parallelism)) channel)) -(define* (call-with-worker-thread channel proc #:key duration-logger) +(define &worker-thread-timeout + (make-exception-type '&worker-thread-timeout + &error + '())) + +(define make-worker-thread-timeout-error + (record-constructor &worker-thread-timeout)) + +(define worker-thread-timeout-error? + (record-predicate &worker-thread-timeout)) + +(define* (call-with-worker-thread channel proc #:key duration-logger + (timeout 30)) "Send PROC to the worker thread through CHANNEL. Return the result of PROC. If already in the worker thread, call PROC immediately." (let ((args (%worker-thread-args))) (if args (call-with-delay-logging proc #:args args) - (let ((reply (make-channel))) - (put-message channel (list reply (get-internal-real-time) proc)) + (let* ((reply (make-channel)) + (operation-success? + (perform-operation + (let ((put + (wrap-operation + (put-operation channel + (list reply + (get-internal-real-time) + proc)) + (const #t)))) + + (if timeout + (choice-operation + put + (wrap-operation (sleep-operation timeout) + (const #f))) + put))))) + + (unless operation-success? + (raise-exception + (make-worker-thread-timeout-error))) + (match (get-message reply) (('worker-thread-error duration exn) (when duration-logger |