2021/11/20 Introduce Clojerl for Alchemist
Introduce ClojerlClojerl.icon for AlchemistElixir.icon ne-sachirou.icon
.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)
Free from crush.
supervisor and gen_server is a natural model of heterogeneous parallel processes.
It's Lisp.
Program is data.
Data is immutable.
Data is explicit. It's a map or a sequence.
Writing tests is very easy.
Libraries (both standard & 3rd. party) are basically stable, because data is stable.
Funny features🌟 including core.async & clojure.spec.
Runs on stable runtimes.
code:interop.clj
(.exampleMethod (ExampleJavaClass. arg1 arg2) arg3 arg4)
.NET : Clojure.NET
code:interop.cljs
(.querySelectorAll js/document ".class")
code:interop.clje
(exam.ple/erl-fun arg1 arg2)
Easy to integrate with other language's environments.
Python : libpython-clj on JVM
code:libpython.clj
(np/array 1 2] [3 4)
ErlangErlang.icon interoperability Elixir.icon:module_name.f()
Clojerl.icon(module_name/f)
Functional programming.
threading (pipe operator)
Elixir.iconv |> f |> g
Clojerl.icon(-> v f g)
Data is basically immutable. Variable is reasignable.
code:diff
- Phoenix
- Nerves
+ Lisp
+ Data oriented
+ Clojure ecosystem
Example : Create a Web server
Create a new project
$ rebar3 new clojerl_app example
Add Cowboy
code:diff
diff --git a/rebar.config b/rebar.config
index a9410fa..95f5937 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,4 +1,5 @@
+{deps, [{clojerl, "0.9.0"},
+ {cowboy, "2.9.0"}]}.
diff --git a/src/example.app.src b/src/example.app.src
index 1b8fb83..ddfc3cc 100644
--- a/src/example.app.src
+++ b/src/example.app.src
@@ -6,6 +6,7 @@
, [ stdlib
, kernel
, clojerl
+ , cowboy
]
}
, {mod, {'example.app', []}}
Create a webserver module to start Cowboy
code:clojure
;; src/example/webserver.clje
(ns example.webserver
(:require
(erlang.core/behaviours gen_server)
(defn child-spec
[]
{:id :example.webserver
:restart :permanent
:shutdown :brutal_kill
:type :worker
:modules '(:example.webserver)})
(defn start-link
[]
:example.webserver
nil
(defn init
(let [dispatch (cowboy_router/compile (clj->erl '(:example.index-handler nil)))]
(erlang/link listener-pid)))
(defn handle_call
_ state
(defn handle_cast
state
code:clojure
;; src/example/index_handler.clje
(ns example.index-handler)
(defn init
(let [req (cowboy_req/reply 200
"Hello Clojerl"
req)]
Supervise it.
code:diff
diff --git a/src/example/sup.clje b/src/example/sup.clje
index 4c5f198..1e74a1f 100644
--- a/src/example/sup.clje
+++ b/src/example/sup.clje
@@ -1,10 +1,16 @@
-(ns example.sup)
+(ns example.sup
+ (:require
:intensity 1
:period 5})
+
+
(defn start-link []
Start the application
$ rebar3 clojerl repl --apps example
Check it.
Hello Clojerl
It's just a normal Cowboy application in ClojureClojure.icon world. Add opentelemetryOpenTelemetry.icon
code:diff
diff --git a/config/sys.config b/config/sys.config
new file mode 100644
index 0000000..18c775e
--- /dev/null
+++ b/config/sys.config
@@ -0,0 +1,7 @@
+[
+ {opentelemetry,
+ [{processors, [{otel_batch_processor,
+ }]
+ }]}
+].
diff --git a/rebar.config b/rebar.config
index 95f5937..922cfa0 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,5 +1,9 @@
{deps, [{clojerl, "0.9.0"},
- {cowboy, "2.9.0"}]}.
+ {cowboy, "2.9.0"},
+ {opentelemetry_api, "~> 1.0.0-rc.3"},
+ {opentelemetry, "~> 1.0.0-rc.3"}]}.
+
diff --git a/src/example.app.src b/src/example.app.src
index ac6c9a9..2441fb4 100644
--- a/src/example.app.src
+++ b/src/example.app.src
@@ -5,6 +5,8 @@
, { applications
, [ stdlib
, kernel
+ , opentelemetry_api
+ , opentelemetry
, clojerl
, cowboy
]
Trace requests
code:diff
diff --git a/src/example/index_handler.clje b/src/example/index_handler.clje
index 2b84853..ee49789 100644
--- a/src/example/index_handler.clje
+++ b/src/example/index_handler.clje
@@ -1,10 +1,45 @@
-(ns example.index-handler)
+(ns example.index-handler
+ (:require
+
+
+(defn now-microsecs
+ []
+ (->> mega-secs
+ (* 1000)
+ (+ (->> secs
+ (* 1000000)))
+ (+ microsecs))))
+
+
+(defn with-response-time-span
+ (let [module (-> *ns* ns-name name)
+ tracer (-> module erlang/binary_to_existing_atom opentelemetry/get_application_tracer)]
+ (otel_tracer/with_span tracer
+ module
+ (let* [now-1 (now-microsecs)
+ resp (callback)
+ now-2 (now-microsecs)
+ attributes (-> (merge {"response-time" (- now-2 now-1)} attributes)
+ clj->erl
+ maps/to_list)]
+ (otel_span/set_attributes (otel_tracer/current_span_ctx) attributes)
+ resp)))))
(defn init
- (let [req (cowboy_req/reply 200
- "Hello Clojerl"
- req)]
+ (with-response-time-span
+ (fn []
+ (let [req (cowboy_req/reply 200
+ "Hello Clojerl"
+ req)]
+ {"path" "/"}))
Start the application
$ rebar3 clojerl compile && rebar3 shell --apps example
Check it.
code:erlang
{span,206190385536417520207509724574528174945,12710625632486370212,[],
undefined,<<"clojure.core">>,internal,-576460738214198000,
-576460738204198000,
[],[],undefined,1,false,
{instrumentation_library,<<"clojerl">>,<<"0.9.0">>}}