Liking cljdoc? Tell your friends :D

amalgam

Lint and test clojars badge cljdoc badge

Useful utilities and mixtures for com.stuartsierra/component.

There are two categories: functions for configuring and running a system (including stopping it with the JVM), and implementations that turn JVM objects (like a thread pool) into components.

Baseline versions

  • JVM: 21
  • Clojure: 1.12.0

Configure and run systems

It is pretty simple to configure and run a system. The configure-system function will recursively merge a configuration map into a system map. Any maps are recursively merged. Lists, sets, and vector are non-recursively concatenated. You can specify merge functions to modify this behavior.

Example:

user> (require '[com.stuartsierra.component :as component])
nil

user> (require '[systems.thoughtfull.amalgam :as amalgam])
nil

user> (defrecord Foo
  [actual default]
  component/Lifecycle
  (start [this] (println "value is:" (or actual default)) this)
  (stop [this] this))
user.Foo

user> (defn make-system []
  (component/system-map :foo (map->Foo {:default 5})))
#'user/make-system

user> (component/start (amalgam/configure-system (make-system) {:foo {:actual 10}}))
value is: 10
{:foo {:actual 10, :default 5}}

user> (component/start (amalgam/configure-system (make-system) {}))
value is: 5
{:foo {:actual nil, :default 5}}

There is also run-system which starts the system, installs a JVM shutdown hook to stop the system, and blocks waiting for the system to stop.

Thread pool executors

There are defrecords that implement both component/Lifecycle and JVM executor interfaces. You can use the components in your system and when started they will start an execuctor and when stopped they will stop the executor, meanwhile they are executors because the implement the appropriate Java interfaces.

thread-pool will create a java.util.concurrent.ThreadPoolExecutor and scheduled-thread-pool will create a java.util.concurrent.ScheduledThreadPoolExecutor.

Data source

data-source will create a component that when started creates a javax.sql.DataSource that can be injected as a dependency and if the wrapped DataSource is AutoCloseable it is closed when the component stops.

Other fun stuff

Vector

vector creates a vector component that collects its dependencies into a vector.

Example:

user> (-> (component/system-map :v (amalgam/vector :a :b) :a 1 :b 2) component/start :v)
[1 2]

Function

function creates a component that collects its dependencies and when started gives them as the first argument to a function.

Example:

user> (def f (component/using (amalgam/function [deps c] (assoc deps :c c)) [:a :b]))
#'user/f
user> (def system (-> (component/system-map :f f :a 1 :b 2) component/start))
#'user/system
user> ((:f system) 3)
{:a 1, :b 2, :c 3}

function* does the same, but will wrap an existing function.

License

Copyright © technosophist

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close