Back
init-key (clj)
(source)multimethod
(init-key key value)
Turn a config value associated with a key into a concrete implementation.
For example, a database URL might be turned into a database connection.
Examples
integrant
(ns integrant.core-test
(:require #?(:clj [clojure.test :refer [are deftest is testing]]
:cljs [cljs.test :refer-macros [are deftest is testing]])
[integrant.core :as ig]
[weavejester.dependency :as dep]))
(defmethod ig/init-key :default [k v]
(swap! log conj [:init k v])
[v])
(defmethod ig/init-key ::x [k v]
(swap! log conj [:init k v])
:x)
(defmethod ig/init-key ::error-init [_ _]
(throw (ex-info "Testing" {:reason ::test})))
(defmethod ig/init-key ::k [_ v] v)
(defmethod ig/init-key ::n [_ v] (inc v))
(defmethod ig/assert-key ::n [_ v]
(assert (nat-int? v) "should be a natural number"))
(defmethod ig/init-key ::r [_ v] {:v v})
(defmethod ig/resolve-key ::r [_ {:keys [v]}] v)
(defmethod ig/resume-key ::r [k v _ _] (ig/init-key k v))
(deftest wrapped-exception-test
(testing "exception when building"
(let [ex (try (ig/init {::a 1, ::error-init (ig/ref ::a)}) nil
(catch #?(:clj Throwable :cljs :default) t t))]
(is (some? ex))
(is (= (#?(:clj .getMessage :cljs ex-message) ex)
(str "Error on key " ::error-init " when building system")))
(is (= (ex-data ex)
{:reason ::ig/build-threw-exception
:system {::a [1]}
:function ig/init-key
:key ::error-init
:value [1]}))
(let [cause (#?(:clj .getCause :cljs ex-cause) ex)]
(is (some? cause))
(is (= (#?(:clj .getMessage :cljs ex-message) cause) "Testing"))
(is (= (ex-data cause) {:reason ::test})))))
penpot/penpot
(ns app.tasks.tasks-gc
"A maintenance task that performs a cleanup of already executed tasks
from the database table."
(:require
[app.common.logging :as l]
[app.config :as cf]
[app.db :as db]
[clojure.spec.alpha :as s]
[integrant.core :as ig]))
(defmethod ig/init-key ::handler
[_ {:keys [::db/pool ::min-age] :as cfg}]
(fn [params]
(let [min-age (or (:min-age params) min-age)]
(db/with-atomic [conn pool]
(let [interval (db/interval min-age)
result (db/exec-one! conn [sql:delete-completed-tasks interval])
result (db/get-update-count result)]
TechEmpower/FrameworkBenchmarks
(ns hello.handler.plaintext
(:require [integrant.core :as ig]
[ataraxy.handler :as handler]
[ataraxy.response :as ataraxy-resp]
[ring.util.response :as resp]))
; Create a specific init-key extending ::ok, patching the Content-Type header
; so that it equals "text/plain" instead of "application/octet-stream"
(defmethod ig/init-key :duct.handler.static/okplain [_ response]
(let [val (ig/init-key :duct.handler.static/ok response)
patched (update-in (val response) [:headers "Content-Type"] (constantly "text/plain"))]
(constantly patched)))
clj-kondo/clj-kondo
(ns schema.defmethod
(:require
[integrant.core :as ig]
[schema.core :as sc]))
(sc/defmethod ig/init-key :config :- {:config/env sc/Keyword}
[_
{:keys [:config/env]} :- {:config/env sc/Keyword}]
{:config/env env})
;; When dispatch-val is vector
(sc/defmethod ig/init-key [:config1 :config2] :- {:config/env sc/Keyword}
[_
{:keys [:config/env]} :- {:config/env sc/Keyword}]
(let [a 1]
{:config/env env
:a a}))
;; Missing return schema
(sc/defmethod ig/init-key [:config1 :config2]
[_
{:keys [:config/env]} :- {:config/env sc/Keyword}]
(let [a 1]
{:config/env env
:a a}))
;; With multiple arities
(sc/defmethod ig/init-key [:config1 :config2] :- {:config/env sc/Keyword}
([_
{:keys [:config/env]} :- {:config/env sc/Keyword}]
{:config/env env})
([_ :- sc/Str
_ :- sc/Int
{:keys [:config/env]} :- {:config/env sc/Keyword}]
{:config/env env}))
duct-framework/duct
{{=<< >>=}}
(ns <<namespace>>.service.example
(:require [duct.logger :as log]
[integrant.core :as ig]))
(defmethod ig/init-key :<<namespace>>.service/example [_ {:keys [logger]}]
(log/log logger :report ::example-initiated))
cljdoc/cljdoc
Examples:
conco -> clj-concordion
ring -> ring
org.clojure -> org.clojure:clojure, org.clojure:clojurescript
nyam -> clj-nyam
re-frame -> re-frame with re-frame:re-frame first
frame -> licaltown/frame (because exact match weighs heavy) then later re-frame:re-frame
RiNg -> ring
RèWRïTÉ -> rewrite-clj
nervous ->io.nervous:* artifacts"
(:require
[cljdoc.server.search.search :as search]
[tea-time.core :as tt]
[clojure.tools.logging :as log]
[integrant.core :as ig])
(:import (java.util.concurrent TimeUnit)
(org.apache.lucene.store Directory)))
(defmethod ig/init-key :cljdoc/searcher [k {:keys [clojars-stats index-factory index-dir enable-indexer?] :or {enable-indexer? true}}]
(log/info "Starting" k)
(let [index (if index-factory ;; to support unit testing
(index-factory)
(search/disk-index index-dir))]
(map->Searcher {:index index
:clojars-stats clojars-stats
:artifact-indexer (when enable-indexer?
(log/info "Starting ArtifactIndexer")
(tt/every! (.toSeconds TimeUnit/HOURS 1)
#(search/download-and-index! clojars-stats index)))})))
(def sr (ig/init-key :cljdoc/searcher {:index-dir "data/index"}))
(ig/halt-key! :cljdoc/searcher sr)