This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-18
Channels
- # 100-days-of-code (10)
- # announcements (2)
- # aws (3)
- # beginners (120)
- # boot (6)
- # calva (6)
- # cider (22)
- # cljsrn (3)
- # clojure (145)
- # clojure-greece (1)
- # clojure-italy (7)
- # clojure-nl (24)
- # clojure-russia (90)
- # clojure-spec (21)
- # clojure-uk (80)
- # clojurescript (175)
- # core-async (1)
- # datomic (17)
- # emacs (8)
- # ethereum (5)
- # figwheel (1)
- # figwheel-main (140)
- # fulcro (137)
- # jobs (6)
- # jobs-discuss (3)
- # luminus (3)
- # mount (1)
- # nyc (3)
- # off-topic (39)
- # onyx (1)
- # pedestal (1)
- # re-frame (21)
- # reagent (13)
- # shadow-cljs (60)
- # spacemacs (25)
- # test-check (4)
- # tools-deps (14)
- # uncomplicate (3)
- # vim (18)
Hello,
i have a kind of design question. I am building a small compojure app for collecting BI data. It returns 204
immediately and uses async/chan
and a producer/consumer pattern to handle the request asynchronously. Here is a minimal working example (`lein new compojure mwe`, put this in the src/mwe/handler.clj
, update dependencies in project.clj
and lein ring server headless
):
(ns mwe.handler
(:require [clojure.core.async :as async]
[compojure.core :refer :all]
[ring.middleware.defaults :refer [wrap-defaults api-defaults]]))
;; instantiate channel
(def channel (ref (async/chan 1000)))
(defn producer-handler
"Returns 204 and puts request on channel for async processing"
[request-map]
(do
(async/go (async/>! (deref channel) request-map))
{:status 204}))
(defn consumer
"Minimal working example of a consumer. 'Processes' the request"
[]
(async/go-loop
[]
(when-let [request (async/<! (deref channel))]
(println request)
(recur))))
;; instantiate consumer
(def consumer-instance (consumer))
(defroutes app-routes
(GET "/" [] "Hello there")
(GET "/collect" r (producer-handler r)))
;; instantiate app
(def app
(wrap-defaults app-routes api-defaults))
The question i have is the following: The code looks to be pretty much like something i would do in object oriented programming. I instantiate a producer 'object' (the routes/app) a channel 'object' (with a ref) and a consumer 'object' in the form of an infinite loop. Now this works, but I wonder if there is a more clojure-eske way of doing such things. Many toy examples i found on the interwebz instantiate channels on the fly in a let
binding and consume them straight away, but i don't see how i would do that in this scenario. I can also live with an 'all is well' answer. It is simply hard to judge if the question is 'Is there a better way' instead of 'How do i do this?'