|
11 | 11 | ;; |
12 | 12 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | 13 |
|
14 | | -(texmacs-module (telemetry telemetry-track) |
15 | | - (:use (telemetry telemetry-utils))) |
| 14 | +(texmacs-module (telemetry telemetry-track) (:use (telemetry telemetry-utils))) |
16 | 15 |
|
17 | 16 | (import (scheme base) |
18 | 17 | (liii base) |
19 | | - (liii json) |
20 | 18 | (liii os) |
21 | 19 | (liii path) |
22 | 20 | (liii string) |
23 | 21 | (liii list) |
24 | | -) |
| 22 | +) ;import |
25 | 23 |
|
26 | 24 | (define-public *telemetry-event-queue* '()) |
27 | 25 |
|
|
31 | 29 | (if (and (string? event-type) (not (string-null? event-type))) |
32 | 30 | (begin |
33 | 31 | (set! *telemetry-event-queue* |
34 | | - (cons (telemetry-make-event event-type properties) |
35 | | - *telemetry-event-queue*)) |
| 32 | + (cons (telemetry-make-event event-type properties) *telemetry-event-queue*) |
| 33 | + ) ;set! |
36 | 34 | (let ((len (length *telemetry-event-queue*))) |
37 | | - (display (string-append "[telemetry] track: " event-type |
38 | | - " (queue: " (number->string len) |
39 | | - "/" (number->string (telemetry-get-buffer-size)) ")\n")) |
| 35 | + (display (string-append "[telemetry] track: " |
| 36 | + event-type |
| 37 | + " (queue: " |
| 38 | + (number->string len) |
| 39 | + "/" |
| 40 | + (number->string (telemetry-get-buffer-size)) |
| 41 | + ")\n" |
| 42 | + ) ;string-append |
| 43 | + ) ;display |
40 | 44 | (if (> len telemetry-max-queue-size) |
41 | | - (set! *telemetry-event-queue* |
42 | | - (list-head *telemetry-event-queue* telemetry-max-queue-size))) |
43 | | - (if (>= len (telemetry-get-buffer-size)) |
44 | | - (telemetry-flush))) |
45 | | - #t) |
46 | | - #f))) |
47 | | - |
48 | | -(define-public (telemetry-queue-length) |
49 | | - (length *telemetry-event-queue*)) |
| 45 | + (begin |
| 46 | + (set! *telemetry-event-queue* |
| 47 | + (list-head *telemetry-event-queue* telemetry-max-queue-size) |
| 48 | + ) ;set! |
| 49 | + (display (string-append "[telemetry] warn: queue truncated to " |
| 50 | + (number->string telemetry-max-queue-size) |
| 51 | + "\n" |
| 52 | + ) ;string-append |
| 53 | + ) ;display |
| 54 | + ) ;begin |
| 55 | + ) ;if |
| 56 | + (if (>= len (telemetry-get-buffer-size)) (telemetry-flush)) |
| 57 | + ) ;let |
| 58 | + #t |
| 59 | + ) ;begin |
| 60 | + #f |
| 61 | + ) ;if |
| 62 | + ) ;if |
| 63 | +) ;define-public |
| 64 | + |
| 65 | +(define-public (telemetry-queue-length) (length *telemetry-event-queue*)) |
50 | 66 |
|
51 | 67 | (define-public (telemetry-flush-if-needed) |
52 | 68 | (if (not (telemetry-enabled?)) |
53 | 69 | #t |
54 | | - (if (not (null? *telemetry-event-queue*)) |
55 | | - (telemetry-flush) |
56 | | - #t))) |
| 70 | + (if (not (null? *telemetry-event-queue*)) (telemetry-flush) #t) |
| 71 | + ) ;if |
| 72 | +) ;define-public |
57 | 73 |
|
58 | 74 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
59 | | -;; Flush implementation: lightweight append-only file writes |
60 | | -;; Complex logic (size limits, stale filtering) handled by liii subprocess |
| 75 | +;; Flush implementation: independent jsonl files + atomic meta update |
61 | 76 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
62 | 77 |
|
63 | | -(define telemetry-lock-timeout-seconds 30) |
64 | | - |
65 | | -(define (telemetry-lock-info owner now) |
66 | | - `(("owner" . ,owner) ("created_at" . ,now))) |
67 | | - |
68 | | -(define (telemetry-read-lock-info) |
69 | | - (catch #t |
70 | | - (lambda () |
71 | | - (let ((text (string-load (system->url (telemetry-lock-info-path))))) |
72 | | - (if (and (string? text) (> (string-length text) 0)) |
73 | | - (string->json text) |
74 | | - #f))) |
75 | | - (lambda args #f))) |
76 | | - |
77 | | -(define (telemetry-lock-expired? now) |
78 | | - (let ((info (telemetry-read-lock-info))) |
79 | | - (if info |
80 | | - (let ((created (json-ref-number info "created_at" 0))) |
81 | | - (> (- now created) telemetry-lock-timeout-seconds)) |
82 | | - #t))) |
83 | | - |
84 | | -(define (telemetry-remove-lock) |
85 | | - (catch #t |
86 | | - (lambda () |
87 | | - (path-unlink (telemetry-lock-info-path) #t) |
88 | | - (rmdir (telemetry-lock-path))) |
89 | | - (lambda args #f))) |
90 | | - |
91 | | -(define (telemetry-acquire-lock) |
92 | | - (telemetry-ensure-dir) |
93 | | - (let ((owner (telemetry-lock-owner)) |
94 | | - (now (inexact->exact (truncate (current-time))))) |
95 | | - (catch #t |
96 | | - (lambda () |
97 | | - (mkdir (telemetry-lock-path)) |
98 | | - (string-save |
99 | | - (json->string (telemetry-lock-info owner now)) |
100 | | - (system->url (telemetry-lock-info-path))) |
101 | | - owner) |
102 | | - (lambda args |
103 | | - (if (telemetry-lock-expired? now) |
104 | | - (begin |
105 | | - (telemetry-remove-lock) |
106 | | - (catch #t |
107 | | - (lambda () |
108 | | - (mkdir (telemetry-lock-path)) |
109 | | - (string-save |
110 | | - (json->string (telemetry-lock-info owner now)) |
111 | | - (system->url (telemetry-lock-info-path))) |
112 | | - owner) |
113 | | - (lambda args2 #f))) |
114 | | - #f))))) |
115 | | - |
116 | | -(define (telemetry-release-lock owner) |
117 | | - (let ((info (telemetry-read-lock-info))) |
118 | | - (if (and info |
119 | | - (string=? (json-ref-string info "owner" "") owner)) |
120 | | - (telemetry-remove-lock) |
121 | | - (begin |
122 | | - (display (string-append "[telemetry] warn: lock owner mismatch, skipping release " |
123 | | - "(expected " owner ", got " |
124 | | - (if info (json-ref-string info "owner" "") "none") ")\n")) |
125 | | - #f)))) |
126 | | - |
127 | 78 | (define-public (telemetry-write-pending events) |
128 | 79 | (if (null? events) |
129 | 80 | #t |
130 | | - (let ((path (telemetry-pending-path)) |
131 | | - (lines (map json->string events))) |
| 81 | + (let* ((filename (telemetry-generate-filename)) |
| 82 | + (filepath (telemetry-full-path filename)) |
| 83 | + (lines (map telemetry->json events)) |
| 84 | + ) ; |
132 | 85 | (catch #t |
133 | 86 | (lambda () |
134 | | - (let ((text (string-append (string-join lines "\n") "\n"))) |
135 | | - (string-append-to-file text (system->url path)) |
136 | | - (display (string-append "[telemetry] flush: " |
137 | | - (number->string (length events)) |
138 | | - " events -> " |
139 | | - path "\n")) |
140 | | - #t)) |
| 87 | + (let ((text (string-append (string-join lines "\n") "\n"))) |
| 88 | + (string-save text (system->url filepath)) |
| 89 | + (if (telemetry-meta-add-entry filename) |
| 90 | + (begin |
| 91 | + (display (string-append "[telemetry] flush: " |
| 92 | + (number->string (length events)) |
| 93 | + " events -> " |
| 94 | + filename |
| 95 | + "\n" |
| 96 | + ) ;string-append |
| 97 | + ) ;display |
| 98 | + #t |
| 99 | + ) ;begin |
| 100 | + (begin |
| 101 | + (display (string-append "[telemetry] error: meta update failed for " |
| 102 | + filename |
| 103 | + "\n" |
| 104 | + ) ;string-append |
| 105 | + ) ;display |
| 106 | + #f |
| 107 | + ) ;begin |
| 108 | + ) ;if |
| 109 | + ) ;let |
| 110 | + ) ;lambda |
141 | 111 | (lambda args |
142 | | - (display (string-append "[telemetry] error: write failed: " |
143 | | - (object->string args) "\n")) |
144 | | - #f))))) |
| 112 | + (display (string-append "[telemetry] error: write failed: " (object->string args) "\n") |
| 113 | + ) ;display |
| 114 | + #f |
| 115 | + ) ;lambda |
| 116 | + ) ;catch |
| 117 | + ) ;let* |
| 118 | + ) ;if |
| 119 | +) ;define-public |
145 | 120 |
|
146 | 121 | (define-public (telemetry-flush) |
147 | 122 | (if (null? *telemetry-event-queue*) |
148 | 123 | #t |
149 | | - (let ((owner (telemetry-acquire-lock))) |
150 | | - (if owner |
151 | | - (let ((ok? (telemetry-write-pending (reverse *telemetry-event-queue*)))) |
152 | | - (if ok? |
153 | | - (begin |
154 | | - (set! *telemetry-event-queue* '()) |
155 | | - (telemetry-release-lock owner) |
156 | | - #t) |
157 | | - (begin |
158 | | - (display (string-append "[telemetry] error: flush failed, keeping " |
159 | | - (number->string (length *telemetry-event-queue*)) |
160 | | - " events in memory queue\n")) |
161 | | - (telemetry-release-lock owner) |
162 | | - #f))) |
163 | | - #f)))) |
| 124 | + (let ((ok? (telemetry-write-pending (reverse *telemetry-event-queue*)))) |
| 125 | + (if ok? |
| 126 | + (begin |
| 127 | + (set! *telemetry-event-queue* '()) |
| 128 | + #t |
| 129 | + ) ;begin |
| 130 | + (begin |
| 131 | + (display (string-append "[telemetry] error: flush failed, keeping " |
| 132 | + (number->string (length *telemetry-event-queue*)) |
| 133 | + " events in memory queue\n" |
| 134 | + ) ;string-append |
| 135 | + ) ;display |
| 136 | + #f |
| 137 | + ) ;begin |
| 138 | + ) ;if |
| 139 | + ) ;let |
| 140 | + ) ;if |
| 141 | +) ;define-public |
0 commit comments