Upload
flowa-oy
View
569
Download
0
Embed Size (px)
DESCRIPTION
Talk Held in Clojutre 2014 By Juha Heimonen and Tero Kadenius. Explains how Condensator, a library for asynchronous message passing through TCP works and what we learned during the making process. Includes some code samples. The actual talk used a infrastructure described in the slides to demonstrate the message passing between the nodes.
Citation preview
WRAPPING JAVA INAWESOMENESS
CONDENSATORREACTIVE COMMUNICATION
OVER TCP
TERO KADENIUS ( )@PISKETTIClojure enthusiast, recovering Java programmer
JUHA HEIMONEN ( )@EVILBUBUClojure N00b
We are part of Flowa ( )@FlowaWolf
FIRST THINGS FIRSTInfrastructure of what you currently see
WAIT...Let's see if we can attach another crucial part
Executed function:(defn attach-command-listener! [] (condensator/on c "command" (fn [{data :data}] (case data "right" (right-sound) "left" (left-sound) nil)) {:address address :port port}))
NOW IT IS LIKE THIS.New Infrastructure view
ONE MORE THING
WE CAN SEND MESSAGES OTHERWAY AROUND
WHAT?Condensator =
Spring Reactor (Java)
Meltdown (Awesome Clojure by Clojurewerkz)
CONDENSATOR CONTAINSTCP messaging capability on top of Spring Reactor and
Meltdown (by Clojurewerkz).
So in overall, you get a system that implements Reactorpattern with TCP transport.
REACTOR PATTERNEvent handling patternSynchronous dispatching of events (Executes when it'spossible to do so without blocking)Coarserly concurrent, doesn't use multiple threads
API(defn create "Creates condensator based on meltdown or tcp capable condensator" ([address port]) ([]))
(defn notify "Notifies condensator with payload based on selector" ([condensator selector payload]) ([selector payload {:keys [address port]}]))
(defn on "Attaches listener to condensator" ([condensator selector cb]) ([condensator selector cb {:keys [address port]}]))
(defn receive-event [condensator selector cb])
(defn send-event [condensator selector data cb])
WHY BUILD ON TOP OF A JAVALIBRARY?
NO NEED TO REINVENT THEWHEEL
THERE ARE A LOT OF STUFF WRITTEN IN JAVAALREADY
MATURITY - QUITE A BIT OF JAVA STUFF IS BATTLETESTED FOR YOU
USING A JAVA LIBRARY DIRECTLYCAN BE A BIT...
(let [calculator (FooCalculator.) inputBean (doto (InputBean.) (.setFoo (Integer. 1)) (.setBar (Integer. 2)) (.setBaz (Integer. 3)))] (.setInput calculator inputBean) (.performCalculation calculator)
(let [resultBean (.getCalculationResultBean calculator) subresultA (.getSubresultA resultBean) subresultB (.getSubresultB resultBean)]
;; Do something with the result
))
(let [{:keys [subresult-a subresult-b]} (calc {:foo 1 :bar 2 :baz 3})]
;; Do something with the result
)
RANDOM LEARNINGS...Shape of an API matters (Clojure ones tend to be simple. Big surprise!)
"Clojure is not for geniuses"
-Adam Bard
"idiot-friendly design"
-Adam Bard
RANDOM LEARNINGS CONTINUEDWrapping Java to Clojure is pretty much controlling mutabilityand restricting state
Restrict mutable java to one instance, pass it with immutabledata to clojure API
(def c (condensator/create))...(condensator/on c "command" (fn [{data :data}] ...)
RANDOM LEARNINGS CONTINUED#2
Testing asynchronous stuff is surprisingly simple withpromises
A daily dose of Clojure increases programmer happiness by63%
(it "remote notifies and locally executes listener" (let [datapromise (promise)] (condensator/on server "remote" (fn [data] (info datapromise) (deliver datapromise (:data data)))) (tcp/send-tcp-msg :port 3030, :operation :notify, :selector "remote", :data "from-remote") (let [result (deref datapromise 3000 nil)] (should= "from-remote" result))))
THANK YOU https://github.com/flowa/condensator