Last active
April 16, 2025 11:30
-
-
Save HassanYA/10a04080c3ef00131944797c313b7579 to your computer and use it in GitHub Desktop.
on-close datastar clj test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 8b849864109e7a5dd4da40b00269125837611ac2 | |
(ns app.web.realtime | |
(:require [starfederation.datastar.clojure.adapter.http-kit :as hk-gen :refer [->sse-response]] | |
[starfederation.datastar.clojure.api :refer [console-log!]] | |
[tick.core :as t] | |
[chime.core :refer [chime-at periodic-seq]])) | |
(def !conn-user-map (atom {})) | |
(defn- assoc-user-conn | |
[conn-map k v] | |
(assoc conn-map k (conj (get conn-map k []) v))) | |
(defn- dissoc-user-conn | |
[conn-map k v] | |
(let [conns (get conn-map k []) | |
updated-conns (remove (partial = v) conns)] | |
(if (empty? updated-conns) | |
(dissoc conn-map k) | |
(assoc conn-map k updated-conns)))) | |
(defn broadcast! [user-id] | |
(fn [f & args] | |
(for [sse-gen (get @!conn-user-map user-id [])] | |
(apply f sse-gen args)))) | |
(defn connect-handler [{:keys [user] :as req}] | |
(->sse-response req | |
{hk-gen/on-open | |
(fn [sse-gen] | |
(swap! !conn-user-map assoc-user-conn (:db/id user) sse-gen)) | |
hk-gen/on-close | |
(fn [sse-gen status] | |
(println "I am being unused") | |
(swap! !conn-user-map dissoc-user-conn (:db/id user) sse-gen))})) | |
(chime-at (rest | |
(periodic-seq (t/now) (t/new-duration 5 :seconds))) | |
(fn [dtime] | |
(println (str "Pinging Connections: " dtime)) | |
#p (->> @!conn-user-map | |
vals | |
(reduce concat) | |
(mapv #(console-log! % "pinged"))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I don't see any obvious mistake with your use of the SDK.
2 quick pointers:
doseq
instead offor
here. Clojure'sfor
is lazy and should be used for creating a new collection, not for side effects. Because of Clojure's lazy/chunked sequences you might not see the difference until you store to many connections and events don't go through for some of them. If you need the sequence of connections for some reason you can keep the for and dodoall
,vec
or just use mapv.disj
instead of scanning the whole vector withremove
.To test the code you could try setting up a simple endpoint using this and curl to see what happens. With http-kit, terminating the curl process is sufficient to get the on-close callback call. There is an example in the SDK for a simple broacast here and a simpler one testing with storing just one connection here.