(zilch nix daemon): generate new logger instance per startWorking

In the case of CA handling, a large quantity (32+) of daemon
connections may exist at once. Handling this with one single derivation
build counter is counterintuitive, and is why the Ninja CLI did not yet
use the counter.

Change-Id: Ia88b4f014ae8df8b1a900b881ac821ff6a6a6964
This commit is contained in:
puck 2025-11-20 12:56:53 +00:00
parent 222b0eb5a3
commit c4ec32eac3
2 changed files with 69 additions and 49 deletions

View file

@ -78,6 +78,7 @@
;; Defaults to a simple logger to the current output port.
(define *logger*
(make-parameter
(lambda ()
(lambda (event data)
(cond
((eqv? event 'next) (write-string data))
@ -89,23 +90,26 @@
((and (eqv? event 'activity-result) (eqv? (nix-activity-id data) build-activity) (eqv? (nix-activity-type data) 105))
(let* ((ndata (nix-activity-fields data)) (done-builds (vector-ref ndata 0)) (total-builds (vector-ref ndata 1)) (running-builds (vector-ref ndata 2)))
(when (or (> done-builds 0) (> total-builds 1) (> running-builds 0))
(printf "[~S/~S builds, ~S running]\n" done-builds total-builds running-builds))))))))
(printf "[~S/~S builds, ~S running]\n" done-builds total-builds running-builds)))))))))
;; Reads a list of log events until `STDERR_LAST` is seen.
;; This is the client-side equivalent of `startWorking` / `stopWorking` in the
;; Nix daemon.
(define (daemon-read-log-events link)
(define val (daemon-read-u64 link))
(define logger ((*logger*)))
(let loop ()
(let
((val (daemon-read-u64 link)))
(case val
((#x6f6c6d67) ((*logger*) 'next (daemon-read-string link)) (daemon-read-log-events link)) ; STDERR_NEXT
((#x64617461) (daemon-write-u64 link (daemon-read-u64 link)) (daemon-read-log-events link)) ; STDERR_READ
((#x64617416) ((*logger*) 'write (daemon-read-string link)) (daemon-read-log-events link)) ; STDERR_WRITE
((#x616c7473) ((*logger*) 'last '()) (list)) ; STDERR_LAST
((#x63787470) ((*logger*) 'error (daemon-read-error link))) ; STDERR_ERROR
((#x53545254) ((*logger*) 'activity-start (daemon-read-activity-start link)) (daemon-read-log-events link)) ; STDERR_START_ACTIVITY
((#x53544f50) ((*logger*) 'activity-stop (daemon-read-u64 link)) (daemon-read-log-events link))
((#x52534c54) ((*logger*) 'activity-result (daemon-read-activity-result link)) (daemon-read-log-events link))
(else => (error (string-append "read-log-events: unknown event #x" (number->string val 16))))))
((#x6f6c6d67) (logger 'next (daemon-read-string link)) (loop)) ; STDERR_NEXT
((#x64617461) (daemon-write-u64 link (daemon-read-u64 link)) (loop)) ; STDERR_READ
((#x64617416) (logger 'write (daemon-read-string link)) (loop)) ; STDERR_WRITE
((#x616c7473) (logger 'last '()) (list)) ; STDERR_LAST
((#x63787470) (logger 'error (daemon-read-error link))) ; STDERR_ERROR
((#x53545254) (logger 'activity-start (daemon-read-activity-start link)) (loop)) ; STDERR_START_ACTIVITY
((#x53544f50) (logger 'activity-stop (daemon-read-u64 link)) (loop))
((#x52534c54) (logger 'activity-result (daemon-read-activity-result link)) (loop))
(else => (error (string-append "read-log-events: unknown event #x" (number->string val 16))))))))
;; Read a list of activity fields from the provided <daemon-link>.
(define (daemon-read-activity-fields link)

View file

@ -93,10 +93,9 @@
(redraw-thread-thunk)))
(define redraw-thread (make-thread redraw-thread-thunk "redraw thread"))
(define last-builds-activity-id #f)
(define last-builds-activity-data (vector 0 0 0 0))
(define last-activity-start-id #f)
(define last-activity-start "")
(define shared-activity-data (vector 0 0 0 0))
(define nix-count 0)
(define statusbar-msg "")
(define (write-err-line buf start end)
(if print-logs
@ -107,8 +106,7 @@
(fprintf err-port "\n")
(set! need-redraw #t))
(begin
(set! last-activity-start-id #f)
(set! last-activity-start (utf8->string (bytevector-copy buf start end)))
(set! statusbar-msg (utf8->string (bytevector-copy buf start end)))
(draw-status-bar))))
(define (write-out-line buf start end)
@ -150,43 +148,61 @@
(set! rerender-status-bar
(lambda ()
(mutex-lock! out-mutex)
(set! status-bar (sprintf "[~S drv ~S bld ~S ifd | nix: ~S/~S builds, ~S running] ~A"
(set! status-bar (sprintf "[~S drv ~S bld ~S ifd | nix: ~S; ~S/~S builds, ~S running] ~A"
(vector-ref zilch-magic-counters 0)
(vector-ref zilch-magic-counters 1)
(vector-ref zilch-magic-counters 2)
(vector-ref last-builds-activity-data 0)
(vector-ref last-builds-activity-data 1)
(vector-ref last-builds-activity-data 2)
last-activity-start))
nix-count
(vector-ref shared-activity-data 0)
(vector-ref shared-activity-data 1)
(vector-ref shared-activity-data 2)
statusbar-msg))
(set! need-redraw #t)
(mutex-unlock! out-mutex)))
(define (handle-log-event event data)
(cond
((eqv? event 'next) (bypass-write (string->utf8 (string-copy data 0 (- (string-length data) 1)))))
((eqv? event 'write) (bypass-write (string->utf8 data))) ; TODO(puck): is this ever called?
((eqv? event 'error) (error data))
((and (eqv? event 'activity-start) (eq? (nix-activity-type data) 104)) (set! last-builds-activity-id (nix-activity-id data)))
((and (eqv? event 'activity-start) (eq? (nix-activity-type data) 105))
(set! build-activity-mapping
(mapping-set! build-activity-mapping (nix-activity-id data)
(string-drop (string-drop-while (vector-ref (nix-activity-fields data) 0) (lambda (f) (not (char=? f #\-)))) 1))))
((eqv? event 'activity-start) (set! last-activity-start-id (nix-activity-id data)) (set! last-activity-start (nix-activity-string data)) (rerender-status-bar))
((eqv? event 'activity-stop)
(set! build-activity-mapping (mapping-delete! build-activity-mapping data)))
((and (eqv? event 'activity-result) (eqv? (nix-activity-type data) 101))
(let ((drv-name (mapping-ref/default build-activity-mapping (nix-activity-id data) #f)))
(when drv-name
(let ((msg (string-append drv-name "> " (vector-ref (nix-activity-fields data) 0))))
(mutex-lock! out-mutex)
(set! last-activity-start msg)
(set! last-activity-start-id (nix-activity-id data))
(mutex-unlock! out-mutex)
(when print-logs
(bypass-write (string->utf8 msg)))))))
((and (eqv? event 'activity-result) (eqv? (nix-activity-id data) last-builds-activity-id))
(set! last-builds-activity-data (nix-activity-fields data))
(rerender-status-bar))))
(define (make-logger)
(when (mutex-lock! out-mutex)
(set! nix-count (+ nix-count 1))
(mutex-unlock! out-mutex))
(define build-activity-mapping (mapping (make-default-comparator)))
(define last-builds-activity-id #f)
(define last-builds-activity-data (vector 0 0 0 0))
(define (set-new-data new-data done)
(mutex-lock! out-mutex)
(when done (set! nix-count (- nix-count 1)))
(do ((i 0 (+ i 1))) ((= i 4) #f)
(vector-set! shared-activity-data i
(+ (- (vector-ref shared-activity-data i) (vector-ref last-builds-activity-data i))
(vector-ref new-data i))))
(mutex-unlock! out-mutex)
(set! last-builds-activity-data new-data)
(rerender-status-bar))
(define (handle-log-event event data)
(cond
((eqv? event 'last) (set-new-data (vector 0 0 0 0) #t))
((eqv? event 'next) (bypass-write (string->utf8 (string-copy data 0 (- (string-length data) 1)))))
((eqv? event 'write) (bypass-write (string->utf8 data))) ; TODO(puck): is this ever called?
((eqv? event 'error) (set-new-data (vector 0 0 0 0) #t) (error data))
((and (eqv? event 'activity-start) (eq? (nix-activity-type data) 104)) (set! last-builds-activity-id (nix-activity-id data)))
((and (eqv? event 'activity-start) (eq? (nix-activity-type data) 105))
(set! build-activity-mapping
(mapping-set! build-activity-mapping (nix-activity-id data)
(string-drop (string-drop-while (vector-ref (nix-activity-fields data) 0) (lambda (f) (not (char=? f #\-)))) 1))))
((eqv? event 'activity-start) (set! statusbar-msg (nix-activity-string data)) (rerender-status-bar))
((eqv? event 'activity-stop)
(set! build-activity-mapping (mapping-delete! build-activity-mapping data)))
((and (eqv? event 'activity-result) (eqv? (nix-activity-type data) 101))
(let ((drv-name (mapping-ref/default build-activity-mapping (nix-activity-id data) #f)))
(when drv-name
(let ((msg (string-append drv-name "> " (vector-ref (nix-activity-fields data) 0))))
(mutex-lock! out-mutex)
(set! statusbar-msg msg)
(mutex-unlock! out-mutex)
(when print-logs
(bypass-write (string->utf8 msg)))))))
((and (eqv? event 'activity-result) (eqv? (nix-activity-id data) last-builds-activity-id))
(set-new-data (nix-activity-fields data) #f))))
handle-log-event)
(thread-start! redraw-thread)
(thread-start! terminal-width-thread)
(define (set-print-logs val) (set! print-logs val))
(values new-out-port new-err-port set-print-logs handle-log-event))))
(values new-out-port new-err-port set-print-logs make-logger))))