Skip to content

Instantly share code, notes, and snippets.

@keisukefukuda
Created August 29, 2016 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keisukefukuda/85eef04f518aca498b929c80218bd260 to your computer and use it in GitHub Desktop.
Save keisukefukuda/85eef04f518aca498b929c80218bd260 to your computer and use it in GitHub Desktop.
(ns showreach.example
(:require [com.stuartsierra.component :as component]))
;; DB接続を管理するComponent
(defrecord DBComponent [conn host port]
component/Lifecycle
(start [this]
(println "Initializing DB component.")
;; DB接続の開始処理
;; ここでは仮に,"DB connection"という文字列を代入しておく
(assoc this :conn (format "<DB connection: %s:%d" host port)))
(stop [this]
(println "Stopping DB component.")
;; DB接続の終了処理
;; 注意: this自身からフィールドをnilに設定して返すが,dissocをしてしまうと
;; 戻り値が普通のmapになってしまう
(assoc this :conn nil)))
;; 外部API接続を管理するComponent
(defrecord APIComponent [session host]
component/Lifecycle
(start [this]
;; 外部API初期化処理
;; thisに必要なキーをassocして返す
(println "Starting API component")
(assoc this :session (format "<External API session host=%s>" host)))
(stop [this]
;; 外部APIの終了処理
(println "Stopping API component")
(assoc this :session nil)))
;; DBComponentとAPIComponentを使ってアプリケーションのロジックを実行する
(defrecord ComponentA [db api]
component/Lifecycle
(start [this]
(println "Initializing A: db-conn=" (-> this :db :conn) " api=" (-> this :api :session))
this)
(stop [this]
(println "Finalizing A")
this))
(defn app-system [config-options]
(let [{db-host :db-host
db-port :db-port
api-host :api-host} config-options]
(component/system-map
;; (B)
:db (map->DBComponent {:host db-host :port db-port})
:api (map->APIComponent {:host api-host})
:A (component/using
(map->ComponentA config-options)
{:db :db
:api :api}))))
;; =>
;; Initializing DB component.
;; Starting API component
;; Initializing A: db-conn= <DB connection: my-db-host:9999 api= <External API session host=my-api-host>
;; Finalizing A
;; Stopping API component
;; Stopping DB component.
;; #<SystemMap>
;; REPLでの使い方
;; systemを定義
(def system (app-system {:db-host "dbhost" :db-port 9999 :api-host "apihost"}))
(alter-var-root #'system component/start) ; systemを開始
;;Initializing DB component.
;;Starting API component
;;Initializing A: db-conn= <DB connection: dbhost:9999 api= <External API session host=apihost>
(alter-var-root #'system component/stop) ; systemを終了
;; Finalizing A
;; Stopping API component
;; Stopping DB component.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment