イベント: | 函数プログラミングの集い 2012 in Tokyo |
---|---|
バージョン: | 0.4.5 |
発表日時: | 2012-09-01 |
作者: | @voluntas |
- 自己紹介
- 概要
- 開発環境
- バージョニング
- テスト環境
- ビルド環境
- ドキュメント環境
- リリース環境
- 自動化
- 継続開発
- レビュー
- CM
- @voluntas
- 弱小パッケージメーカー在籍
- Erlang/OTP でプロダクト作ってます
- ネットワークサーバー系が専門
- 趣味ではあまりプログラムを書かないサラリーマンプログラマー
Erlang/OTP で書かれた製品をパッケージとしてリリース場合の環境作りの話をします。 Erlang の〜がスゴイとかは話しません。
Emacs を使うべきです。Erlang/OTP ではソースコードに erlang.el が同梱されています。常に最新版に追従され、テストされて使い込まれているのが公式からリリースされます。
ただし、自分は vimmer なので ... 。自前で erlang.vim 書いています。emacs への転職は厳しい状況です ... 。
GitHub private リポジトリを使用しています。GitHub Enterprise を検討したが社内でメンテナンスする事を考えるとコストが高いと考えています。今は月 $100 のコースで事足りています。
Erlang/OTP 自体や、それ以外のライブラリがほとんど GitHub で公開されているので GitHub 自体と相性が良いです。
たまに落ちるのと、回線速度が遅い(海外にあるため)のが困る。ただ皆ローカルにコードがあるので、困るのは別の理由です。
ほぼ全てで git-flow を採用。ブランチ戦略がはっきりしているため議論しやすいです。ただ何にでも適用できるわけでは無いです。
release ブランチを切るタイミングや、feature ブランチを develop ブランチにマージするタイミングなどを良く検討する必要があります。
基本的には erlang.el に倣う。ただあとは個性の話になるので、そのたび開発者間で意見をぶつけ合い、納得できた方法を社内コーディング規約として記録する。
開発者は全員 Mac だが、Linux に移行すべきでは無いか?という話が出てきている。理由としてはリリース対象環境が RHEL なので Mac で開発するメリットがほとんど無い。
XenServer を使用している。Xen テンプレート機能を使いシンプルな環境と開発環境を 10 秒程度で用意できるようになっている。テストサーバは自由にリソースを好き勝手に使って良い、テスト環境なのでいつ消されてもいいような運用が必須。消されてはいけないインスタンスを上げる場合は事前申請が必要。
仮想用サーバのハードは 32 C / 64 G とか。お値段 50 万円未満、懐に優しい。
本格的に使い始めるとストレージやネットワークの問題も出てきたりします、この辺りはお金の話がほとんどになるので、以下に予算を取れるかという話になると思います。
Erlang の開発環境は rebar というビルドツールが出てきたことで激変しました。今までは Makefile をしっかり書いて、色々環境を作る必要がありました。
rebar ではライブラリの管理、コンパイルの設定、テスト、リリースなどほとんど全ての事をやってくれます。
rebar.config という設定ファイルに色々書いていきます。
依存ライブラリの設定:
{deps, [ {cowboy, ".*", {git, "git://github.com/extend/cowboy.git", {branch, "master"}}}, {meck, ".*", {git, "git://github.com/eproxus/meck.git", {branch, "master"}}}, {proper, ".*", {git, "git://github.com/manopapad/proper.git", {branch, "master"}}} ]}.
依存ライブラリの取得:
./rebar get-deps
依存ライブラリのアップデート:
./rebar update-deps
コンパイルの実行:
./rebar compile
テストの実行:
./rebar eunit
パッケージのリリース:
./rebar generate
rebar を導入する事が Erlang でのプロダクト開発における最重要ポイントな事は間違いありません。
ソースコードのバージョンの付け方がとても大事です。リリースのスタイルが決まっているというのはスムーズなリリースが行えるようになります。バージョニングというのはその中でも一番「決めておくべき」事です。
良くあるタイプですが以下のように定義しています
<メジャー>.<マイナー>.<リビジョン>
- メジャー
- 下位互換を考えない変更
- マイナー
- 下位互換がある大幅な変更
- リビジョン
- バグフィックスや下位互換のある小幅な変更
バージョンの繰り上がりは行われません。たとえば 1.1.1000 もありえます。下位互換の小幅な変更がいくら積み上がっても大幅な変更にはならないからです。
いくつか有用なテストライブラリやツールが存在し公開されています。
- EUnit
- 単体テストライブラリ
- cover
- カヴァレッジライブラリ
- Dialyzer
- 静的型解析ツール
- PropEr
- オープンソース QuickCheck ライブラリ
- meck
- mock/stub ライブラリ
これらの導入は前述の rebar を使えば特に困る事はありません。
EUnit を使って、よく言われる単体テストを書いています。単体テストは テスト とすら見なされていません。ただコード書いたらテスト書いてカヴァレッジは 80 % くらいまであげておけよ程度です。
テストというよりは、コード書いた人向けの自己満足用です。
テストで大切なのは外部インターフェースです。受け入れテストは単体のようにコードと密結合しているのではなく、外部から API 等を叩いてテストします。
仕様通りに動くかどうかを確認するテストです。これが本当の意味でのテストです。デグレもここで確認出来ます。
Python を使って書かれています。とても膨大な数になります。これをメンテナンスしていくコストも考える必要があります。
性能テストです。コミット単位で性能を確認し、グラフ化します。特定のコミットにおける性能の劣化を防げます。
Haskell が有名です。作者の一人である John Hughes は商用版を Erlang で提供しています。
なぜ Haskell ではなく Erlang にしたのかは、この辺の動画で。 http://www.infoq.com/interviews/Erlang-Haskell-John-Hughes/
ただ、今は OSS で似たようなツールが公開されているのでそちらを使用しています。
型から値をランダムにテストして戻り値をチェックするのが有名です。これは特にデコード/エンコード系に有効です。
プロトコルのライブラリのテストに使用しています。状態を持ちつつのプロパティテストもデータベース周りで使用しています。ただあまり突っ込んでは使えていません。
長時間シナリオに基づいてテストをかけ続けます。一度仕掛けたら落ちるまでは放置しておきます。最低限1ヶ月以上は続ける前提です。
サーバ構成、ネットワーク構成等、ほとんど本番環境と同様の環境を仮想環境上に構築します。
- covertool
- Cobertura XML 変換ツール
rebar は cover モジュールを有効にすることでカヴァレッジを HTML と XML で生成してくれます。開発中はそれを確認しています。また Jenkins でカヴァレッジをグラフ化するためのファイルに XML を変換する rebar プラグインがありそれも使用しています。
Erlang VM や依存しているライブラリやはできる限り早い段階で最新版にアップデートするようにします。
もちろんただ上げるのでは無く、何がどう変更されたのかを理解しておく必要があります。
この定期アップデートはあまり意識せずにやれている間はいいですが、かなり人に依存していることが多いです。その人が無意識に追いかけていたりする事があるからです。
このあたりは依存しているものを明示的にして、定期的に更新する作業をタスク化しておくことはとても大事なことだと思います。
定期アップデートを安全に行うためには受け入れテストがある必要があります。アップデートして単体テストが通ったとしても外部インターフェースから見た影響が出る可能性があったらアップデートするのは難しくなります。
- Jenkins
- CI ツール
ビルド環境は Erlang さえ入っていれば make と叩くだけで全てのビルドが出来る様にしています。ツール側に寄せるのでは無く Makefile に集約するという方針です。
Jenkins 自体は make コマンドを叩くだけです。毎回 git clone して make を叩いています。make を実行すれば単体テストまでは実行されます。その後パッケージングが行われます。
パッケージングも make 一つで出来る様になっています。
後は GitHub 側に新しい変更が出てきたらそのタイミングでビルドするような仕組みを作れば十分です。
個人環境
- watchdog
- ファイルシステムイベントモニタリングツール
手元で開発するとき、コードを書いたら裏で勝手にビルドしてテストして欲しいですよね。それを簡単に実現出来るツールを導入しています。
watchdog という Python のツールを使うことで簡単に継続ビルドが可能です。
コマンドサンプル:
watchmedo shell-command --patterns="*.erl;*.hrl" --recursive --wait --command="make test" include src test
ただ、ある程度リポジトリが膨らむとテストが遅くなったりしますのでその時は一部のテストに絞って実行するといいでしょう。
- Sphinx
- ドキュメント生成ツール
- seqdiag (blockdiag シリーズ)
- シーケンス図を生成する
プロダクトとしてリリースする際に必要になるのがドキュメントです。テストと同様のコストをかける部分です。クイックスタートから始まり、機能説明、エラー説明、Q and A などが必要になってきます。
読みやすい文章で綺麗な構成を考えるのはとても大変です。出力が PDF なのは 印刷して保存 が必須だからです。
バージョン管理が出来ないドキュメントは考えられません。図自体も seqdiag を使う事でバージョン管理可能なシーケンス図を生成する事が出来ます。
Sphinx から LaTex に変換して PDF を生成しています。
将来的にはフォントもフリーのものではなく商用フォントを採用する予定です。
今まで説明した環境は全て Jenkins を使って自動化されています。手動テストは存在しません。 何かしらでエラーが出た場合は、 XMPP を使用して Google Talk 経由で配信されてきます。
ビルド、パッケージング、リリース、受け入れテスト、キャパシティテストの順番です。全てグリーンであればいつでも出荷可能なバイナリとなります。
自動化がかなり難しく、自動化は PDF 生成までです。後は人的リソースがつぎ込まれています。ただ形態素解析を使った揺らぎ発見などはツールかが可能です。
今まで説明してきた仕組みを維持する事が、継続開発を可能にします。ただ、いつでも出荷可能な状態を保つ事はとてもコストがかかります。
残念ながら一度構築したら、あとは大丈夫というワケには行きません。状況は常に変化しますのでそれに常に追従する必要があります。
継続開発を維持し発展させる事が大切です。
継続開発を維持するために絶対に必要なのが徹底的なレビューです。我々はレビューに多大なコストをかけています。レビューツールは GitHub を使っているため、ツール的な意味でのコストはとても低いです。ただしレビューに対する人的リソースは削減できません。
むしろ削減するのでは無く、いかにレビューに時間がかけられるようにするかが重要です。
レビューをする時間を確保するために継続開発を維持し、継続開発を維持するためにレビューを行うのです。
レビューについては別途「レビューのススメ?」というのを書いてみました。
https://gist.github.com/73efe2f36ac1513c02a8
- Learn You Some Erlang for Great Good!
- http://learnyousomeerlang.com/
日本語翻訳版が出版予定です。ページ数なんと 600 ページ越え。 翻訳者はオライリーの Java開発者のための関数プログラミング を担当した @ymotongpoo です。
レビューワーとして参加中です。
- Erlang Study Meeting 2012.09
- http://connpass.com/event/937/
Erlang の軽量 Web サーバ cowboy の開発者が日本に遊びに来るので、せっかくなのでと思ってちょっとしたイベントでもやろうと思ったら Riak の開発者も参加しちゃったりと、濃い勉強会になってしまいました。
発表予定者
Loïc Hoguin: | cowboy developer |
---|---|
Scott Fritchie: | Riak developer |
Yosuke Hara: | LeoFS developer |
Kenji Rikitake: | sfmt-erlang developer |
Kota Uenishi: | MessagePack Erlang developer |
- Erlang/OTP
- https://github.com/erlang/otp/
- rebar
- https://github.com/basho/rebar/
- covertool
- https://github.com/idubrov/covertool/
- PropEr
- https://github.com/manopapad/proper/
- meck
- https://github.com/eproxus/meck/
- git-flow
- https://github.com/nvie/gitflow/
- blockdiag
- http://blockdiag.com/
- jenkins
- http://jenkins-ci.org/
- GitHub
- https://github.com/
- watchdog
- http://pypi.python.org/pypi/watchdog/
- A successful Git branching model
- http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html
- Semantic Versioning 2.0.0-rc.1
- http://semver.org/
- Semantic Versioning 2.0.0-rc.1 日本語版
- http://samidarehetima.blog9.fc2.com/blog-entry-182.html