Since aerospike-clj uses a future based model instead of a callback based model,
it is convenient to compose complex asynchronous logic using promesa.
By implementing the ClientEvents protocol 2 hooks are exposed that are called
for each API call: on-success and on-failure.
Those hooks are called with valuable information that can be used, for example
to configure automatic logging or metrics on your client. Here is an example of
such code that is reporting useful metrics to statsd.
So assuming you have some statsd namespace tha can connect and report to a statsd
server, and some metrics namespace that is used to properly format the metric names:
(ns af-common-rta-aerospike.core
(:require [aerospike-clj.protocols :as pt]
[statsd.metrics :as metrics]
[statsd.core :as statsd]
[promesa.core :as p]))
(defrecord DBMeter [cluster-name]
pt/ClientEvents
(on-success [_ op-name op-result _index op-start-time]
(statsd/send-timing (metrics/format-statsd-metric cluster-name op-name "latency")
(micros-from op-start-time)
STATSD-RATE)
(statsd/inc-metric (metrics/format-statsd-metric cluster-name op-name "success"))
(when (= "read" op-name)
(if (some? op-result)
(statsd/inc-metric (metrics/format-statsd-metric cluster-name "read" "hit"))
(statsd/inc-metric (metrics/format-statsd-metric cluster-name "read" "miss"))))
op-result)
(on-failure [_ op-name op-ex index op-start-time]
(statsd/send-timing (metrics/format-statsd-metric cluster-name op-name "latency")
(micros-from op-start-time)
STATSD-RATE)
(statsd/inc-metric (metrics/format-statsd-metric-fail-aerospike op-ex (:cluster-name client) op-name))
(p/rejected! op-ex)))
A few notes on the above code:
op-name, op-result and index are strings. They are partially used for
metrics generation in our case.op-start-time is (System/nanoTime), converted here to microseconds and
used to measure latency.on-success and on-failure return the results passed in. Although this
logic is the last logic that happens to the operations' results (e.g. after
transcoders are called), the returned result will be what the calling code gets
as a returned value.Finally, hook it to your client:
user=> (def c (aero/init-simple-aerospike-client ["localhost"] "test" {:client-events (->DBMeter "test-cluster")}))
Can you improve this documentation? These fine people already did:
asaf.chelouche, Ido Barkan & ItayKomEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |