core-async

2023-05-09T15:50:20.287699Z

Communicating errors in both directions Hey team, I am trying to wrap the callbacks of a websocket connection with core.async. My idea is to have every socket connection have it's own core.async go-loop. Here's a rough idea:

(defn add-socket! [socket]
  (swap! sockets assoc (:id socket) socket))

(defn remove-socket! [socket-id]
  (swap! sockets dissoc socket-id))

(defn undertow-config [{:keys [start-fn]}]
  (let [socket-id (UUID/randomUUID)
        receive-ch (a/chan)]
    {:undertow/websocket
     {:on-open
      (fn [{transport :channel}]
        (let [socket {:id socket-id
                      :transport transport
                      :receive-ch receive-ch}]
          (start-fn socket)
          (add-socket! socket)))
      :on-message (fn [{:keys [message]}]
                    (a/>!! receive-ch (<-json message)))
      :on-close-message (fn [{:keys [message]}]
                          (a/>!! receive-ch (ex-info "socket closed"
                                                     {:message message}))
                          (a/close! receive-ch)
                          (remove-socket! socket-id))
      :on-error (fn [{:keys [error]}]
                  (a/>!! receive-ch error)
                  (a/close! receive-ch)
                  (remove-socket! socket-id))}}))
Here's how it could be used:
(defn connect-get [_req]
  (socket/undertow-config {:start-fn (fn [{:keys [receive-ch]}]
                                       (log/infof "starting socket!")
                                       (a/go-loop []
                                         (when-let [msg (a/<! receive-ch)]
                                           (log/infof "got message: %s" msg)
                                           (recur))))}))
Problem: I currently handling the case, where if a websocket connection closes or there's some unknown error, the worker that takes from receive-ch can be notified and shutdown gracefully. But, what about the other way around? What if my start-fn worker fails? I'd likely want this error to propagate up and close the websocket connection. What would be an idiomatic way to achieve this?

2023-05-10T14:04:24.164709Z

For posterity: I think I was overthinking this. I can use an error-ch for the worker to report back.