core.async toggle channel mix - clojure

I am experimenting with core.async's mixes. It seems that muting an input channel in a mix would be one of possible ways of implementing backpressure. I am using the code below:
(def output-chan (chan))
(def input-chan (chan))
(def mixer (admix (mix output-chan) input-chan))
(toggle mixer {input-chan {:mute true}})
Evaluating last line in the REPL gives
CompilerException java.lang.IllegalArgumentException: No implementation of method: :toggle* of protocol: #'clojure.core.async/Mix found for class: java.lang.Boolean.
What is wrong with the above example code?
Thanks!

(def mixer (admix (mix output-chan) input-chan))
You assign the return value of admix to mixer, which is a boolean and not the expected mixer. Try:
(def output-chan (chan))
(def input-chan (chan))
(def mixer (mix output-chan))
(admix mixer input-chan)
(toggle mixer {input-chan {:mute true}})

Related

compojure-api spec coercion on response body

I'm trying to figure out how to do custom coercion with compojure-api and spec. By reading the docs and code I have been able to do coercion on the input (the body) but am unable to do coercion on the response body.
Specifically, I have a custom type, a timestamp, that is represented as a long within my app but for the web API I want to consume and return ISO timestamps (no, I don't want to use Joda internally).
The following is what I have that works for input coercion but I have been unable to properly coerce the response.
(ns foo
(:require [clj-time.core :as t]
[clj-time.coerce :as t.c]
[spec-tools.conform :as conform]
[spec-tools.core :as st]))
(def timestamp (st/create-spec
{:spec pos-int?
:form `pos-int?
:json-schema/default "2017-10-12T05:04:57.585Z"
:type :timestamp}))
(defn json-timestamp->long [_ val]
(t.c/to-long val))
(def custom-json-conforming
(st/type-conforming
(merge
conform/json-type-conforming
{:timestamp json-timestamp->long}
conform/strip-extra-keys-type-conforming)))
(def custom-coercion
(-> compojure.api.coercion.spec/default-options
(assoc-in [:body :formats "application/json"] custom-json-
conforming)
compojure.api.coercion.spec/create-coercion))
;; how do I use this for the response coercion?
(defn timestamp->json-string [_ val]
(t.c/to-string val))
;; I've tried the following but it doesn't work:
#_(def custom-coercion
(-> compojure.api.coercion.spec/default-options
(assoc-in [:body :formats "application/json"] custom-json-
conforming)
(assoc-in [:response :formats "application/json"]
(st/type-conforming
{:timestamp timestamp->json-string}))
compojure.api.coercion.spec/create-coercion))
Problem is that Spec Conforming is a one-way transformation pipeline:
s/conform (and because of that st/conform) does both transform and validate for the result. Your response coercion first converts the integer into date string and the validates it against the original spec predicate, which is pos-int? and it fails on that.
To support two-way transformations, you need to define the end result as either of the possible formats: e.g. change your predicate to something like #(or (pos-int? %) (string? %)) and it should work.
Or you can have two different Spec Records, one for input (timestamp-long with pos-int? predicate) and another for outputs (timestamp-string with string? predicate). But one needs to remember to use correct ones for request & responses.
CLJ-2251 could possible help if there was and extra :transform mode (not written in the issue yet), which would do conforming without validating the end results.
Normally, return transformations are done by the format encoder, but they usually dispatch on value types. For example Cheshire just sees an Long and has no clue that it should be written as date string.
Maybe people on the #clojure-spec slack could help. Would also like to know how to build this kind of two-way transformation with spec.

Clojure - tests with components strategy

I am implementing an app using Stuart Sierra component. As he states in the README :
Having a coherent way to set up and tear down all the state associated
with an application enables rapid development cycles without
restarting the JVM. It can also make unit tests faster and more
independent, since the cost of creating and starting a system is low
enough that every test can create a new instance of the system.
What would be the preferred strategy here ? Something similar to JUnit oneTimeSetUp / oneTimeTearDown , or really between each test (similar to setUp / tearDown) ?
And if between each test, is there a simple way to start/stop a system for all tests (before and after) without repeating the code every time ?
Edit : sample code to show what I mean
(defn test-component-lifecycle [f]
(println "Setting up test-system")
(let [s (system/new-test-system)]
(f s) ;; I cannot pass an argument here ( https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L718 ), so how can I pass a system in parameters of a test ?
(println "Stopping test-system")
(component/stop s)))
(use-fixtures :once test-component-lifecycle)
Note : I am talking about unit-testing here.
I would write a macro, which takes a system-map and starts all components before running tests and stop all components after testing.
For example:
(ns de.hh.new-test
(:require [clojure.test :refer :all]
[com.stuartsierra.component :as component]))
;;; Macro to start and stop component
(defmacro with-started-components [bindings & body]
`(let [~(bindings 0) (component/start ~(bindings 1))]
(try
(let* ~(destructure (vec (drop 2 bindings)))
~#body)
(catch Exception e1#)
(finally
(component/stop ~(bindings 0))))))
;; Test Component
(defprotocol Action
(do-it [self]))
(defrecord TestComponent [state]
component/Lifecycle
(start [self]
(println "====> start")
(assoc self :state (atom state)))
(stop [self]
(println "====> stop"))
Action
(do-it [self]
(println "====> do action")
#(:state self)))
;: TEST
(deftest ^:focused component-test
(with-started-components
[system (component/system-map :test-component (->TestComponent"startup-state"))
test-component (:test-component system)]
(is (= "startup-state" (do-it test-component)))))
Running Test you should see the out put like this
====> start
====> do action
====> stop
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

Reusing a stub/redef across a speclj context

I'm writing tests for a Clojure app using Speclj. I'm accustomed in BDD to do things like this:
context "some context"
stub my-function :return true
it "has behavior one"
should true my-function
it "has behavior two"
should_not false my-function
But in Speclj I can't seem to find an example of how to share the stub across the characteristics, so I'm currently stuck writing code like this:
(describe "this"
(context "that"
(it "accepts nil"
(with-redefs [called-fn (constantly nil)]
(should= nil (my-fn nil)))))
(it "accepts 1"
(with-redefs [called-fn (constantly nil)]
(should= 100 (my-fn 1))))))
(I realize this is a somewhat contrived example and arguably those assertions could all go under one characteristic, but let's suppose for now that I have good reason to write the code like this.)
I want, however, to just have to stub called-fn once, but moving this up out of the its raises errors because the real called-fn gets called instead of my redef.
Is there a way to reuse redefs (or use Speclj stubs) in Speclj so I'm not stuck pushing them all down inside the characteristics?
You can use the around macro to accomplish this.
Here's an example spec:
(ns sample.core-spec
(:require [speclj.core :refer :all]
[sample.core :refer :all]))
(describe "a test"
(it "returns output from fn-a"
(should= 1 (fn-b)))
(describe "using with-redef"
(around [it] (with-redefs [fn-a (fn [] 2)] (it)))
(it "returns the output from redefined function"
(should= 2 (fn-b)))))
Source:
(ns sample.core)
(defn fn-a []
1)
(defn fn-b []
(fn-a))

Code serializing deserializing from Clojure

I am follwing the example here http://patternhatch.com/2013/06/12/messaging-using-clojure-and-zeromq/
I have verified that I can serialize MarketData and have built the protobuf for it.
Instead of using chesire serialization I decided to try my new learned protobuf serialization knowledge. When I modified the functions in that example into their gpb versions, when I run
(future-call market-data-publisher-gpb)
It seems ok. However, when I run the client
(get-market-data-gpb 100)
Nothing happens. I have two questions:
1) Is there some sort of graphical or otherwise debugger for Clojure?
2) If someone can point me in the right direction as to what I am doing wrong on my modfied example that would also be helpful.
I seem to remember that over ZMQ with a [protobuf] binary data payload required a different set of calls?
(ns clj-zmq.core
(:import [org.jeromq ZMQ])
)
(use 'flatland.protobuf.core)
(import com.example.Example$MarketData)
(def MarketData (protodef Example$MarketData))
(def ctx (ZMQ/context 1))
(defn market-data-publisher-gpb
[]
(let [s (.socket ctx ZMQ/PUB)
market-data-event (fn []
{:symbol (rand-nth ["CAT" "UTX"])
:size (rand-int 1000)
:price (format "%.2f" (rand 50.0))})]
(.bind s "tcp://127.0.0.1:6666")
(while :true
(.send s ( protobuf-dump(market-data-event))))))
; Client
(defn get-market-data-gpb
[num-events]
(let [s (.socket ctx ZMQ/SUB)]
(.subscribe s "")
(.connect s "tcp://127.0.0.1:6666")
(dotimes [_ num-events]
(println (protobuf-load MarketData (.recv s))))
(.close s)))
Both Eclipse Counterclockwise and IntelliJ Cursive have Clojure debug support.
Also, your address looks bad - should be "tcp://127.0.0.1:6666".

How do you explicitly specify a namespace when using "apply" on a function in Clojure?

Here "graph" is higher-order function that returns a function with config set in its scope:
(ns bulbs.neo4jserver.graph)
(defn out1
"Test func that simply returns out1."
[config]
"out1")
(defn graph
[config]
(fn [func & args]
(apply func config args)))
You create an instance of graph, which can then be used to call other functions and automatically pass in the config arg:
(def g (graph {:root-uri "http://localhost"}))
(g out1)
;; => "out1"
This works; however, if you require/import graph into another namespace, then you have to prefix each function call with the graph namespace:
(ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph :as graph]))
(def g (graph/graph {:root-uri "http://localhost"}))
;; would rather do (g out1)
(g graph/out1)
Instead, I want to explicitly specify the namespace in the apply function so that users don't have to:
(defn graph
[config]
(fn [func & args]
;; somehow specify the graph namespace here
(apply func config args)))
What's the best way to do this?
Not a direct answer to your question, but the general pattern you're using is more common: having a single stateful data structure that holds connection parameters (to a database or another server). Most frameworks turn this around: instead of calling your functions from within the function holding your connection parameters as you do, they have functions that accept the connection data structure as a parameter.
For example, given a database connetion conn, a typical, fictional database library could look like this (note: examples are simplified for clarity):
(let [conn (make-db-connection :host .... :user ....)]
(read-from-db conn :user))
While using a library for a messaging framework (say, RabbitMQ) could look like this:
(let [conn (make-amqp-connection :host .... :port ...)]
(send-message conn :my-queue "hello world"))
In both situations, there is a single conn data structure that is used for all subsequent calls to the libraries' functions. In OO languages, you would have a global, stateful object holding the connection (a singleton perhaps in Java land). In Clojure, libraries typically handle this using a with-... macro, that binds a particular connection to a dynamic var which is used internally:
(with-db-connection (make-db-connection ....)
(read-from-db :user ....))
(with-rabbit-connection (make-rabbitmq-connection ....)
(send-message :my-queue "hello world"))
Here's a (fictional) example that implements this pattern. Assume that a connection is a Java object:
;; a var to hold the connection
(def ^:dynamic *current-connection* nil)
(defmacro with-connection [conn & body]
`(binding [*current-connection* ~conn]
~#body))
;; send-msg is using the connection object bound to
;; the *current-connetion* var
(defn send-msg [msg]
(.sendMessage *current-connection* msg))
;; usage:
(with-connection conn
(send-msg "hello world!"))
If you want to be fancy, you could support both patterns (accepting a connection as a parameter or using the bound connection) by defining the send-msg function like this:
(defn send-msg [msg & {:keys [connection]
:or {connection *current-connection*}}]
(.sendMessage connection msg))
;; usage with bound connetion:
(with-connection conn
(send-msg "Hello World!"))
;; usage with explicit connection:
(send-msg "Hello World!"
:connection conn)
This version of send-msg uses the supplied connection, or the bound connection if a connection wasn't specified.
You can pass symbol instead of function and resolve it in graph function:
(defn graph
[config]
(fn [func & args]
(apply (ns-resolve 'bulbs.neo4jserver.graph func) config args)))
And call it:
(ns bulbs.neo4jserver.junk
(:require [bulbs.neo4jserver.graph :as graph]))
(def g (graph/graph {:root-uri "http://localhost"}))
(g 'out1)
But g is not an high-order function any more. It takes symbol, not function. Personally I don't like this approach. Why don't you like specifying namespace? May be you can do what you need with macro too, but I don't know macros well.
EDIT
Don't do it. Use regular functions as explained by #Ankur and #Gert in comments.