世界線航跡蔵

Mad web programmerのYuguiが技術ネタや日々のあれこれをお送りします。

2016年07月30日

Jsonnetでwebアプリケーションの設定ファイルをテスト可能に

最近、Jsonnetを用いてwebアプリケーションをデプロイする際に適用する設定群をテストしようとしている。

今やInfrastructure as a Codeと言われて久しく、アプリケーション配備の基盤構成もその上で走るwebアプリケーションをどうやって設定するのかもコードとして書かれるのが一般的になった。 それらはコードとして書かれているのでバージョン管理可能であり、テストも可能である。だから何かが間違っていれば実際に配備する前に気づくし、それでも間違えていれば差し戻せる。

「どうやって設定するか」はコードになった。では「何が設定されるか」はコードになっているだろうか。やっている人もいるだろうけれども、そんなに簡単な話でもない。 実際Chefで設定ファイルを扱う際はtemplatesなりfilesなりが第一の選択であるとは思うが、これらはよほどヘルパーメソッドを充実でもさせない限りそこまでモジュール性を提供してくれない。

そこでJsonnetなのである。詳細は別記事に譲るが、JsonnetはJSONやINI形式の設定ファイルを生成するための純粋関数型言語である。これを用いれば、たとえば運用環境ではログローテーションを合わせて設定するが開発環境ではしない、といった差異を抽象化しておいて複数のアプリケーションに一貫して適用することができる。最近試みているケースでは、あるアプリケーションの設定configが与えられたとき、次のように書くと開発環境の設定を出力する

util.environment.dev(config)

これを運用環境用に差し替えるには次のようにする。

util.environment.live(config)

開発環境と運用環境の設定は同じconfigから派生しているので、ユーティリティ関数が生成する差異を除いて両者が一貫していることが保証される。 また、util.environment.devutil.environment.liveがしっかり書かれてテストされている限りにおいて、特定のアプリケーション用設定でうっかり運用環境用の何かを設定し忘れるということもない。

さて、ここでユーティリティ関数群をしっかりテストしなければならないという問題が発生する。そこでJsonnet用のunit testライブラリJsonnetUnitを書いた。

アプリケーションの実装をテストするのは当たり前だ。どうやって設定を適用するかをテストするのも当たり前だ。今後は、どんな設定が書かれるか、運用環境と開発環境で何が違っていて良いのかをテストしていきたい。

トラックバック

http://yugui.jp/articles/898/ping

現在のところトラックバックはありません

コメント閲覧/投稿

2016年07月17日

情報技術による変革の道のりを思う

祖父母と話していて、ちょっと調べて本を読んで考えれば分かることに対してなぜいつまでも堂々巡りの思考を巡らしているのだろうと思うことが良くあった。 学生時代に工場生産や農業にかり出されてあまり教育を受けられなかったというのはあるが、それにしても祖父は戦後に大学を出ている。時代的な教育の問題だけとも考えづらい。

しかし、よくよく考えてみるとちょっと調べるために私が使うのはインターネットの情報だ。書籍は書籍の価値があるので同様に情報源とする(今は過渡期で境界が曖昧とは言え、やはり書籍の形に手間暇掛けてまとめ上げた有料情報ならではの価値というのはある)が、それにしたって書籍に到達するのはweb上の書評経由であることも多い。入手経路も半数はAmazonからだ。これらを通じて学んだ情報や考え方、情報の取捨選択の方法に基づいて私は考えている。

これらはどれも祖父母が持っていない物だった。自分が何を知らないのか俯瞰しようとすれば、いくつもの紙の書籍を図書館で読むしかない。しかしこれらはちょっとした話題についての検索効率ではwebに満たない。司書に検索支援を頼もうにも我々がwebで検索するほど気軽にできることではないし、地方の図書館員に占める司書資格者は多くないし、そもそも足が悪くてはそうそう図書館にも行けない。webがなくては、webのみならず書籍や雑誌にすらろくにアクセスできない。情報を得るための情報や情報を抽出するための情報からも隔絶されていく。

ほんの二十数年ほど前まで、インターネット技術は一般的ではなく、社会の殆どはこんな状況だった。知らない間に我々はずいぶん遠くまで来たようだ。

トラックバック

http://yugui.jp/articles/897/ping

現在のところトラックバックはありません

コメント閲覧/投稿

2016年01月06日

APIデザインケーススタディ —— Rubyライブラリを移植する前に読む本

APIデザインケーススタディ』という本を頂戴したので読んでみた。

ライブラリ作者に向けて

この本はRuby標準ライブラリを題材にして、分かりやすく、多様な機能をサポートして、互換性を保つAPIの設計をするにはどのように考えるべきかを教えてくれる。

ここでAPIと言っているのは、一般的なRubyのクラスとオブジェクトとメソッドから成るライブラリをどうデザインするか、という話である。 別にChef RecipeやRSpec DSLのようなちょっと変わったDSLを設計するとかそういう話ではない。確かにその種の言語内DSLのデザインには固有のセンスが必要とされるし、Ruby DSL Handbookなんて本が書かれているように実装にあたってもある種のテクニックが必要なのも確かだ。でも、それ以外の「ふつう」のライブラリのデザインは果たして簡単だろうか。 適切な粒度のクラスを定義する。必要な機能に合わせてメソッドを定義する。メソッドの引数は何であるべきか。引数の順序は? 引数が多すぎて使うのが大変になっていないか。そのメソッド名は他の似た機能から類推可能だろうか。機能を追加するとき、どうやって後方互換性を保てば良いのか。互換性を破ってでも改善すべきと判断するにあたっては何を考慮すれば良いのか。 本書が扱うのはそうした話題だ。

ちなみに、著者のakr(田中哲)さんはRubyライブラリ設計の第一人者と言っても良いだろう。 長くに渡ってRubyコアおよび標準添付ライブラリの開発を幅広く手がけており、今のRubyコミュニティにあるライブラリ設計の慣習を基礎づけた人々の1人だ。 中でも本書で題材に上がっているIOクラスやTimeクラス、およびsocketライブラリの設計において、いくつもの困難な課題を解決してきた。

本書を読むことで題材になっているRubyの標準ライブラリへの理解は深まるだろうし、自分でRubyライブラリを書くときの考え方の参考にもなるだろう。 もっと一般に任意の言語でライブラリのAPIをデザインするときの助けにもなるだろう。

ライブラリ移植者に向けて

本書はまた、ライブラリを移植する物語として読むこともできる。

Rubyの標準ライブラリ、ことにIOsocketはC標準ライブラリやUNIXシステムコールを意識してデザインされている。 よってこれらのライブラリをCからRubyへの移植と捉えることもできるだろう。

このようなライブラリの移植に当たっては、幾つものデザインの選択肢がある。一番単純なのは、元のライブラリのAPIを引き写すことだろう。 利点としては元のライブラリを知っていれば移植先の学習が容易なことが挙げられる。それにデザインにあまり頭を使わなくて済む。 一方で、これは一般にあまり使いやすいAPIにはならない。 言語ごとに望ましいエラーの返し方も関数の命名慣習も異なるし、そもそも慣習を支える言語の特性自体が静的型付けの有り無しから真偽値の定義から何もかも違うのだ。

その対極に当たるアプローチは、ほぼ同じ機能を提供するライブラリをゼロからデザインすることだ—— もはや「移植」とは言いがたいかもしれないが。 利点としては、もし適切にデザインできれば移植先の言語のプログラマにとって理解しやすく使いやすいAPIが得られる。 一方で、移植元のライブラリデザインからの類推が働かないので学習コストがかえって高く付く可能性もある。

ではRubyは、akrさんは、この両極の間でどのような選択をしてきただろうか。本書はその歴史を語っている。

よりよい移植をめぐって

話は変わるが、私はこの数年というもの、業務ではRuby以外の言語で開発をすることが多い。 もっぱらC++やPythonやGo, 時にはJavaを触り、やむを得ずPHPを触ることもある。

これらの言語で開発する過程でしばしばRubyのライブラリやフレームワーク、ツールから影響を受けたと思しきものを目にすることもあった。 ことに各所へのRailsやActiveRecordの影響は著しいものがある。昨今ではRailsが常にWebアプリケーション開発の第一選択肢とは限らなくなってきているのも、ひとえにRailsの良さが他のフレームワークに広く受け入れられてもはや現代webアプリケーションフレームワークでは当たり前の性質となっているからである。

このようにRubyコミュニティの成果が他から参考にされるのは誇らしくもあるが、一方でうんざりさせられることもある。 うんざりするのは、Rubyのライブラリやフレームワークの劣化コピーを目にするときだ。

たとえばRailsの劣化コピーである。 いまどきRailsに影響を受けたフレームワークは珍しくないが、さて、果たしてそのRailsの機能は本当にその言語に向いているだろうか。 そもそもRailsはフルスタックかつ密結合な極端なフレームワークとして登場した。Railsには(当時のwebアプリケーションの)すべてが揃っていて、その構成要素が密に結合している代わりに「Railに乗っている」限りにおいては極小のコード量であらゆることが簡単にできた。 普通に考えれば構成要素が密結合なのは悪だが、Railsは密結合由来の難点をうまく補うような機能を提供していて、またRuby自体の柔軟性をもって(いざとなればモンキーパッチしてでも)問題を解決することができる。 あんなにも密結合なフレームワークがまともに使い物になること自体が信じがたいけれども、うまいバランスとRubyの力で不思議と使いやすいのがRailsである。

だとすれば、Rubyよりも柔軟性に劣る大抵の言語にとってRailsの採った選択は適切でない。また、「Railsのサブセットを移植した使いやすいフレームワーク」というのも難しい。全体が揃ってうまくバランスが取れているのがRailsだからだ。 Rubyよりも実行時の柔軟性に欠けるその言語にはRubyよりもよい型安全性があるかもしれない。その言語では標準的なORマッパーがActiveRecordと異なるデザインかもしれない。それならば、おそらくRailsとは違うデザインが向いているはずだ。 それにも関わらず 「Railsをgoで書きました」「RailsをPHPで書きました」という類のデザインにはうんざりさせられる。

Rubyのactive_recordライブラリもまた多くのフォロワーを持つ。 しかし思い出して欲しいのは、そもそものPofEAAではActive Recordの適用領域は限定的だとされているし、active_recordライブラリはActive Recordパターンより遥かに多くのものを提供しているということだ。 active_recordライブラリやそれに依存するRailsが複雑なアプリケーションを書くのにも使えるのは、そうした拡張機能や様々な細かい配慮、定義済みのRakeタスクのお陰である。 これらなくして、ただactive_recordに影響を受けてActiveRecordパターンを複雑なアプリケーションに採用するのは無謀きわまる。

さて、ではどうすれば良かったのだろうか。そのヒントを本書に見ることができるだろう。 本書はRubyのライブラリは何を考えてデザインされているのかを解説している。またライブラリ移植の事例を豊富に提供している。 よって、何がRuby固有で、何かを移植するときは何を考慮しなければならないのかを学ぶのにうってつけである。

ああ、Goのあのライブラリの、PHPのあのフレームワークの、Pythonのあのツールの作者が安易にRubyのやり方を流用する前に本書を読んでいてくれたら、あれらもまともに使える代物であったろうにと思わずにはいられないのだ。

トラックバック

http://yugui.jp/articles/896/ping

現在のところトラックバックはありません

コメント閲覧/投稿

ご案内

最近の記事

タグ一覧

過去ログ

  1. 2016年07月
  2. 2016年01月
  3. 2015年09月
  4. 2015年08月
  5. 過去ログ一覧

フィード

フィードとは

その他

Powered by "rhianolethe" the blog system