Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
About Integrant
ayato
March 13, 2017
Programming
0
330
About Integrant
ayato
March 13, 2017
Tweet
Share
More Decks by ayato
See All by ayato
Clojureという言語が私逹にもたらしたもの
ayato0211
5
2.5k
3年間考え続けてきたWebアプリケーションにおけるテストの話
ayato0211
3
170
Re:REPL-Driven Development
ayato0211
3
930
Meta Template Engine
ayato0211
2
580
超変換! Hiccup data structure!!
ayato0211
2
390
Muscle Assert
ayato0211
0
130
Clojureを用いたWebアプリケーション開発
ayato0211
2
2.3k
翻訳にまつわるエトセトラ
ayato0211
6
890
Ring Middleware の基礎
ayato0211
2
170
Other Decks in Programming
See All in Programming
Android スキルセットをフル活用して始めるスマートテレビアプリ開発
satsukies
0
190
Jakarta EE 10 and Beyond
ivargrimstad
0
1.8k
インターン生・新卒向け、学校でもっと教えてほしいITエンジニア基本スキル
nearme_tech
0
120
Java アプリとAWS の良い関係 - AWS でJava アプリを実行する一番簡単な方法教えます / AWS for Javarista
kanamasa
2
1.2k
Seleniumでイキってたらサーバを絞め落としかけてた話
kenfujita
0
360
Independently together: better developer experience & App performance
bcinarli
0
160
短納期でローンチした新サービスをJavaで開発した話/launched new service using Java
eichisanden
6
1.9k
EFFICIENT CREATION OF AN EMPTY COLLECTION IN .NET
abt
0
150
Node-RED 3.0 新機能紹介
utaani
0
130
How we run a Realtime Puzzle Fighting Game on AWS Serverless
falken
0
240
Node.jsデザインパターンを読んで
mmmommm
0
1.9k
GitHubのユーザー名を変更した後のあれこれ
tahia910
0
120
Featured
See All Featured
Designing for Performance
lara
597
63k
Mobile First: as difficult as doing things right
swwweet
213
7.5k
Debugging Ruby Performance
tmm1
65
10k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
37
3.2k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
What's in a price? How to price your products and services
michaelherold
229
9.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
224
49k
How New CSS Is Changing Everything About Graphic Design on the Web
jensimmons
213
11k
Done Done
chrislema
174
14k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
315
19k
Teambox: Starting and Learning
jrom
123
7.7k
Why Our Code Smells
bkeepers
PRO
324
55k
Transcript
*OUFHSBOU ʹ͍ͭͯ !@BZBUP@Q$ZCP[V4UBSUVQT JOD
自己紹介 •あやぴー •朝ジムを倒しまくってる •普段はComponentベースでシステム開発
Integrant概要
Integrantとは •Jamesオジサンが作った新しいデータ駆動 アーキテクチャなマイクロフレームワーク •つまり、ライフサイクルを管理するライブラリ •Componentで指摘された課題を解決しようとしたもの •システムがデータから組み立てられる •各コンポーネントは必ずしもマップやレコードである 必要はない
データによるシステム定義 •ednでシステムを定義できる {:adapter/jetty {:port 8080, :handler #ref :handler/greet} :handler/greet {:name
"Alice"}}
Multimethodによるコンポーネント定義 •レコードやマップに限らず関数やただの数値などもコン ポーネントにすることが可能 (require '[ring.jetty.adapter :as jetty] '[ring.util.response :as resp])
(defmethod ig/init-key :adapter/jetty [_ {:keys [handler] :as opts}] (jetty/run-jetty handler (-> opts (dissoc :handler) (assoc :join? false)))) (defmethod ig/init-key :handler/greet [_ {:keys [name]}] (fn [_] (resp/response (str "Hello " name))))
一時停止と再開のサポート •再起動が遅くなるのを回避できる •suspend-key!とresume-keyがポイント •初期化処理にも多少影響がある
一時停止と再開のサポート (defmethod ig/init-key :adapter/jetty [_ opts] (let [handler (atom (delay
(:handler opts))) options (-> opts (dissoc :handler) (assoc :join? false))] {:handler handler :server (jetty/run-jetty (fn [req] (@@handler req)) options)})) (defmethod ig/halt-key! :adapter/jetty [_ {:keys [server]}] (.stop server)) (defmethod ig/suspend-key! :adapter/jetty [_ {:keys [handler]}] (reset! handler (promise))) (defmethod ig/resume-key :adapter/jetty [key opts old-opts old-impl] (if (= (dissoc opts :handler) (dissoc old-opts :handler)) (do (deliver @(:handler old-impl) (:handler opts)) old-impl) (do (ig/halt-key! key old-impl) (ig/init-key key opts))))
Componentと比較して⚔
良いところ •データでシステムを記述できる •どんなモノでもコンポーネントにできる •心理的な負担が減る
悪いところ •明示的にコンポーネントの名前空間を読み込む必要性
変わらなかったこと •あるコンポーネントに依存したいならば それ自身をコンポーネントとして定義する必要がある
Integrantはこう使う (と良いかも)
独自のns loaderを作る •デフォルトでついてくるのは使い勝手が悪い •完全修飾されたキーワードは設定ファイルに書き難い •開発時にシステムからコンポーネントを取り出すのも苦 •例えばbultitudeを利用して任意のprefix付きnsを ロードするようなbootstrap機能を実装する
同じコンポーネントを複数作る •マルチメソッドを大量に用意する? •No •任意の親を持つ子のキーワードを複数deriveしておく •注意点 •複数の子で設定を書く場合は親のキーワードを 設定ファイルに書けない •refに対して子のキーワードを明示
同じコンポーネントを複数作る (derive :demo/master-db :demo/db) (derive :demo/read-db-1 :demo/db) (derive :demo/read-db-2 :demo/db)
(defmethod ig/init-key :demo/db [_ opts] ...) (ig/init {:demo/read-db-1 {...} :demo/read-db-2 {...} :demo/master-db {...} :demo/get-user-handler {:db (ig/ref :demo/read-db-1)} :demo/get-company-handler {:db (ig/ref :demo/read-db-2)} :demo/update-user-handler {:db (ig/ref :demo/master-db)}}
テストでコンポーネントを差し替える •deriveでok
baumと組み合わせる •baumは設定ファイルを素敵にする拡張可能な DSLライブラリ •環境変数などを取得できる •baumのカスタムリーダーとして integrant.core/refをラップする
baumと組み合わせる {$override* "dev-resources/config-local.edn" :demo/server {:port 3000 :handler #igref :demo/endpoint} :demo/database
{:dbtype "postgresql" :dbname "my_blog" :user #env :db-user :password #env :db-password} :demo/endpoint {:db #igref :demo/database}}
まとめ •Componentにあった心理的な負担が減った •これが1番いいかと言われると疑問 •Arachne的なアプローチにも期待したい