fix: use persistent maps for STM state store — fixes corruption under load
ober
fc1c905c503dfcd00838c57282aca0e7645928bd
--- a/edge.ss +++ b/edge.ss @@ -32,7 +32,8 @@ (std stm) (std transducer) (std text json) - (std crypto native)) + (std crypto native) + (std pmap)) ;; ═══════════════════════════════════════════════════════════════ ;; Configuration @@ -61,28 +62,29 @@ ;; atomic and produces an immutable snapshot — no locks, no races. ;; ═══════════════════════════════════════════════════════════════ -(def events-ref (make-ref (make-hash-table))) +(def events-ref (make-ref (make-persistent-map))) (def watchers-ref (make-ref '())) (def (store-result! event status) (dosync (alter events-ref (lambda (st) - (hash-put! st (hash-ref event "id") + (persistent-map-set st (hash-ref event "id") (list->hash-table `(("type" . ,(hash-ref event "type")) ("status" . ,status) ("received" . ,(hash-ref event "received")) - ("processed" . ,(format "~a" (time-second (current-time))))))) - st)))) + ("processed" . ,(format "~a" (time-second (current-time))))))))))) (def (get-event id) - (hash-get (ref-deref events-ref) id)) + (let ([st (ref-deref events-ref)]) + (and (persistent-map-has? st id) + (persistent-map-ref st id)))) (def (event-stats) (let ([st (ref-deref events-ref)] [total 0] [ok-n 0] [err-n 0]) - (hash-for-each + (persistent-map-for-each (lambda (id record) (set! total (+ total 1)) (if (string=? (hash-ref record "status" "") "ok")