This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-17
Channels
- # announcements (24)
- # babashka (22)
- # beginners (49)
- # cider (16)
- # clj-kondo (8)
- # cljsrn (4)
- # clojure (87)
- # clojure-australia (7)
- # clojure-europe (44)
- # clojure-nl (4)
- # clojure-sweden (7)
- # clojure-uk (24)
- # clojurescript (5)
- # core-async (7)
- # cryogen (8)
- # cursive (22)
- # data-oriented-programming (2)
- # datomic (1)
- # emacs (6)
- # events (4)
- # fulcro (11)
- # google-cloud (1)
- # introduce-yourself (1)
- # java (8)
- # jobs (3)
- # lsp (10)
- # observability (1)
- # off-topic (12)
- # polylith (12)
- # re-frame (6)
- # reitit (36)
- # remote-jobs (1)
- # ring (4)
- # ring-swagger (1)
- # rum (4)
- # schema (1)
- # shadow-cljs (18)
- # sql (56)
- # tools-deps (33)
continuing my adventures with “server-side re-frame”, i’m looking for a small code review.
in normal re-frame, views are calculated by the app-db being a reagent atom cascading a series of subscriptions. this means that you don’t have to inform or generate any view-specific information in an event handler (`reg-event-fx`), you just make changes to :db
and let the rest flow naturally.
however, in my server re-frame, views don’t exist because how could they? instead, i have effect handlers that send the new/changed data to the clients (using websockets). that data has to come from somewhere, so I can either create it in the event handler and make the effect handler really simple (receive and send pre-generated data to clients) or in an effect handler (receive needed information, generate and send data to clients).
Here’s an example of the former style event and effect handlers (don’t mind the reuse of send-event-list!
, trying to figure out a better way to do all this):
(executor/reg-event-fx
:lobby/list
[executor/unwrap]
(fn send-lobby-list
[cofx data]
(when-let [uid (:uid data)]
(let [db (:db cofx)
lobbies (:lobbies db)
lobby (uid->lobby lobbies uid)]
{:fx [[:lobby/broadcast-list (prepare-lobby-list (vals lobbies) [(uid->user db uid)])]
(if lobby
[:lobby/state (prepare-lobby-state lobby)]
[:lobby/clear uid])]}))))
(defn send-event-list!
[event-list]
(doseq [[uid ev] event-list]
(ws/chsk-send! uid ev)))
(executor/reg-fx :lobby/broadcast-list #'send-event-list!)
(executor/reg-fx :lobby/state #'send-event-list!)
(executor/reg-fx :lobby/clear (fn [uid] (ws/chsk-send! uid [:lobby/clear])))
and here’s the same example, but where the conversion of db data to client data happens in the effect handlers:
(executor/reg-event-fx
:lobby/list
[executor/unwrap]
(fn send-lobby-list
[cofx data]
(when-let [uid (:uid data)]
(let [db (:db cofx)
lobbies (:lobbies db)
lobby (uid->lobby lobbies uid)]
{:fx [[:lobby/broadcast-list [(vals lobbies) [(uid->user db uid)]]]
(if lobby
[:lobby/state lobby]
[:lobby/clear uid])]}))))
(executor/reg-fx
:lobby/broadcast-list
(fn send-broadcast-list!
[[lobbies users]]
(doseq [[uid ev] (prepare-lobby-list lobbies users)]
(ws/chsk-send! uid ev))))
(executor/reg-fx
:lobby/state
(fn send-state!
[lobby]
(doseq [[uid ev] (prepare-lobby-state lobby)]
(ws/chsk-send! uid ev))))
(executor/reg-fx :lobby/clear (fn [uid] (ws/chsk-send! uid [:lobby/clear])))
having written this out, maybe I didn’t pick the best examples, lol, but i think it works close enough
(should have picked an example that changes :db
)
the underlying question is: how much pre-calculation should an event handler do before passing off to effect handlers?