aboutsummaryrefslogtreecommitdiff
path: root/guix-data-service
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2024-08-07 16:50:30 +0100
committerChristopher Baines <mail@cbaines.net>2024-08-07 16:50:30 +0100
commit7f746b358b07c434fd8df1c5cf4dacf9d0e8698e (patch)
treeaecd003c47e08d6b31a7f16305c0978560dad8d8 /guix-data-service
parent3d2335cebe118d25f16a95a221f5f33f900bd426 (diff)
downloaddata-service-7f746b358b07c434fd8df1c5cf4dacf9d0e8698e.tar
data-service-7f746b358b07c434fd8df1c5cf4dacf9d0e8698e.tar.gz
Add the fiberize utility
Diffstat (limited to 'guix-data-service')
-rw-r--r--guix-data-service/utils.scm37
1 files changed, 37 insertions, 0 deletions
diff --git a/guix-data-service/utils.scm b/guix-data-service/utils.scm
index 13dce82..0320497 100644
--- a/guix-data-service/utils.scm
+++ b/guix-data-service/utils.scm
@@ -55,6 +55,8 @@
call-with-worker-thread
worker-thread-timeout-error?
+ fiberize
+
fibers-delay
fibers-force
@@ -698,6 +700,41 @@ If already in the worker thread, call PROC immediately."
(duration-logger duration))
(apply values result)))))))
+(define* (fiberize proc #:key (parallelism 1))
+ (let ((channel (make-channel)))
+ (for-each
+ (lambda _
+ (spawn-fiber
+ (lambda ()
+ (while #t
+ (let ((reply-channel args (car+cdr
+ (get-message channel))))
+ (put-message
+ reply-channel
+ (with-exception-handler
+ (lambda (exn)
+ (cons 'exception exn))
+ (lambda ()
+ (with-throw-handler #t
+ (lambda ()
+ (call-with-values
+ (lambda ()
+ (apply proc args))
+ (lambda vals
+ (cons 'result vals))))
+ (lambda _
+ (backtrace))))
+ #:unwind? #t)))))
+ #:parallel? #t))
+ (iota parallelism))
+
+ (lambda args
+ (let ((reply-channel (make-channel)))
+ (put-message channel (cons reply-channel args))
+ (match (get-message reply-channel)
+ (('result . vals) (apply values vals))
+ (('exception . exn) (raise-exception exn)))))))
+
(define-record-type <fibers-promise>
(make-fibers-promise thunk values-box evaluated-condition)
fibers-promise?