Knife-Zero を使った時につまづいた点とその解決策

こんにちは、sunflatです。 今期のアニメは、とんかつDJアゲ太郎と宇宙パトロールルル子が好きです。

今回は、リモートのサーバーを設定するためのツールである Knife-Zero を使った時に、つまづいた点とその解決策をまとめてみました。

Knife-Zero とは

Misocaでは、サーバーの設定の自動化にChefを使っています。

f:id:sunflat:20160525130948p:plain

Chefのレシピ(設定手順をコードで書いたもの)をリモートのノードに適用するためのツールとして、Misocaでは以前から knife-solo を使っていました。しかし、knife-soloが使っているChefの機能であるChef Soloが非推奨となったことなどから、代わりにKnife-Zeroを使うことを計画しています。 *1

Knife-Zero を使った時につまづいた点とその解決策

その1. ノードファイルに色々書き込まれる

knife-solo では、ノードオブジェクトの json ファイル(nodesディレクトリにあるもの。以下ノードファイルと呼ぶ)は、以下のように、ノード固有の属性(例: set_fqdn)とrun_listのみを書いておく感じでした。レシピを適用(knife-solo cook)しても、ノードファイルは変化しません。

{
  "set_fqdn": "hoge.example.com",
  "run_list": [ 〜 ]
}

一方 Knife-Zero では、レシピを適応(knife-zero converge)した時に、ノードの全ての属性がノードファイルに保存されます。*2

しかし、自動取得された動的なシステム情報などの属性も(かなり大量に)書き込まれてしまうため、ノードファイルをGit等でバージョン管理したい場合には不都合です。

解決策

.chef/knife.rbホワイトリストを設定しておけば、指定した属性のみが保存されるようになります(参考)。knife[:automatic_attribute_whitelist] の場合、自動収集された属性(automatic属性)がホワイトリストの対象となります。

以下は、automatic属性のうち fqdn, hostname, chef_package.chef.version のみをノードファイルの保存する場合の、.chef/knife.rb の設定例です。

local_mode true
cookbook_path ['berks-cookbooks', 'site-cookbooks']

# ホワイトリストの設定
knife[:automatic_attribute_whitelist] = %w(
  fqdn/
  hostname/
  chef_packages/chef/version/
)

なお、ノードファイルに保存された defaultautomatic 以下の属性は、次回のレシピ適用時には破棄されて使われません(ただし、automaticfqdn属性のみ、Knife-Zero がレシピ適用時のsshの接続先として使う)。

ノード固有の属性を設定したい場合は、以下のようにノードファイルの normal 以下に書けば、レシピ適用時に使用されます。(About Attributes の Attributes Type を参考)

{
  "normal": {
    "set_fqdn": "hoge.example.com"
  },
  "run_list": [ 〜 ],
}

また、ノードファイルを編集する時には、直接jsonファイルを編集するのではなく、以下のようにknifeコマンドで編集すれば、永続的な属性のみが表示されますし、保存時にバリデーションもしてくれます。 *3

knife node edit -z hoge.example.com

その2. ホワイトリストが有効にならない

その1の解決策でホワイトリストを設定する方法を紹介しましたが、最初はホワイトリストを定義してもそれが反映されず、原因究明に時間がかかりました。

結局、設定先のノードに古いバージョンのChefが入っていて、それがそのまま使われていたのが原因でした。動作確認にVagrantを使ったのですが、Ubuntu14.04のVagrant用イメージには古いバージョンのChefがプレインストールされています。

設定先のノードにChefをインストールするために knife zero bootstrap コマンドを利用できますが、設定先のノードにChefが既にインストールされている場合は、(古いバージョンだったとしても)Chefのインストールは行われません。

解決策

knife zero bootstrap を実行する前に古いバージョンのChefを予めアンインストールしておきましょう。VagrantのイメージにはChefが入っていることが多いので、自分で入れた覚えがなくても要注意です。

その3. FQDNがノード名として使われる

デフォルトでは、設定先ノードのFQDNドメイン名込みのホスト名)が、ノード名(ノードファイルのファイル名)やレシピ適用時のsshの接続先として使われます。このため、ノードのFQDNやその名前解決を設定する前の状態だと、ノードファイルのファイル名が意図しないものとなったり、レシピ適用時にsshで接続できなかったりして困ります。

解決策

knife zero bootstrap を使って設定先にChefをインストールする時に、以下のように -N オプションをつければ、設定先ノードのFQDNとは別の名前をノード名として使うことができます。*4

knife zero bootstrap [sshの接続先(IPアドレスなど)] -N [ノード名]
※必要に応じて、-x(sshのユーザ名)や、 --sudo(sudo権限で実行)などのオプションも付加

また、knife zero converge を使ってレシピを適用する時には、-a オプションをつけると、sshの接続先として使う属性(ノードファイルに保存された属性の名前)を変更できます。デフォルトでは fqdn (ノードのFQDN)が使われますが、これを knife_zero.hostknife zero bootstrap 実行時に使った接続先。ノードファイルにnormal属性として保存されている)に変更すれば、ノードのFQDNやその名前解決を設定する前の状態でも、レシピ適用時にsshで接続できるようになります。

knife zero converge -a knife_zero.host -x [sshのユーザ名] "name:[ノード名]"
※必要に応じて、-x(sshのユーザ名)などのオプションも付加

その4. デバッグ実行したい

Rubyでレシピを書いていると、pry-byebug などを使ってデバック実行をしたくなることがあります。レシピの中で

require 'pry'
binding.pry

などと書けば停止はするのですが、 Knife-Zeroだとキー入力が伝わらないようなので、デバック実行中の操作ができなくて困りました。

解決策

(もはや Knife-Zeroを使っていないですが)設定先のノードにレシピを転送して、Chef Client Local Mode を使ってローカル環境にレシピを適用すればデバッグ実行できました。

.chef/knife.rb では、cookbook_path をフルパスで指定する必要があるようです(参考)。*5

chef_repo = File.join(File.dirname(__FILE__), "..")
cookbook_path ["#{chef_repo}/berks-cookbooks", "#{chef_repo}/site-cookbooks"]

rsync などで chef-repo(レシピが含まれているリポジトリ)を設定先のノードへ転送し、設定先ノードのchef-repoのディレクトリ上で、以下のように Chef Client を Local Mode で起動します。

sudo chef-client -z

これで、普通にpry-byebugを使ったデバック実行が出来ました。

まとめ

今回は、Knife-Zero を使った時に、つまづいた点とその解決策を紹介しました。 Knife-Zero はまだ色々と試している段階ですが、今後のMisocaのサーバ運用に活用していきたいと思います。

*1:公式blog記事 https://www.chef.io/blog/2014/06/24/from-solo-to-zero-migrating-to-chef-client-local-mode/ などで、Chef Solo の代わりに Chef Client Local Mode(Chef Zero)を使うようにアナウンスされています。 そこで、Chef Client Local Mode を使ってレシピをリモートのノードに適用するためのツールであるKnife-Zeroを、knife-soloの代わりに使うことにしました。

*2:Chefは、ノードの設定だけでなく、ノードの状態を管理するツールでもあり、特定の状態を持ったノードを検索(サーチ機能)したりする時にこれらの保存した属性を使うことができます。

*3: .chef/knife.rb に local_mode true を書いておけば、-z オプションは省略できます

*4:ノード名には、将来割りあてる予定のFQDNを指定しておくと良いです。

*5:追記: chef_client用のホワイトリストを設定する場合は knife[:automatic_attribute_whitelist] ではなく automatic_attribute_whitelist というDSLで書きます。

西日暮里.rb 開催レポート

こんにちは。Misoca開発部のtaiki-tです。

普段は名古屋に住んでいますが、東京で西日暮里.rbというRubyコミュニティを個人的に運営しています。先日、西日暮里.rbでLT大会をしたので、今日はそのときのことについて書こうと思います。

西日暮里.rbとは

まず西日暮里.rbの紹介を少ししたいと思います。 西日暮里.rbの始まりは、僕とミヒャエル(イベント管理サービスDoorkeeperの運営者)が西日暮里に住んでいたところから始まりました。最初に開催したのが2014年6月ですから、もうすこしで2年になります。 ここまでやってこれたのも強力な運営メンバーのおかげです。普段は @mtsmfm@joe_re がメインで運営を行っています。

普段はもくもくしたり、わいわいしたりしながら各自色々なことをやってます。

西日暮里.rb ゴールデンだよLT大会 @ 秋葉原UDX!!

西日暮里.rb ゴールデンだよLT大会 @ 秋葉原UDX!! - 西日暮里.rb | Doorkeeper

これが先日開催された西日暮里.rbのイベントです。この日は弥生株式会社の会議室を借りれることになったので、急遽LT大会を開催することにしました。2周年はまたLT大会をしようね、と話していたのですが、前倒しで行った感じです。(しかし2周年でもLT大会をやる予定です。)

会場は、秋葉原UDX、21階にて行いました。普段見上げてるだけの周辺のビルを上から観れたのでよかったです。

あいにくの雨でしたが、それでも多くの方に集まっていただけたので良かったです。雨の中来てくださった参加者の方へ、この場を借りてお礼を申し上げます。

LT大会

イベントのメインはLT大会です。事前申し込みしてくださった方に加え、その場で飛び込みでLTをしてくださった方もいました。

公開されていたスライドをいくつか紹介します。

GraphQL on Ruby by joe_re

GraphQLは、Facebookが開発しているクエリ言語です。詳しくはjoe_reさんのスライドをご参照ください。次回のLTでさらに色々紹介してくれるようです。

joe-re.hatenablog.com

どう書くで学ぶ Ruby by Fumiaki MATSUSHIMA

「どう書く」でRubyを学ぶことについて話してもらえました。「オフラインリアルタイムどう書く」に僕もいつか参加したい

mtsmfm blog - ESM オフラインリアルタイムどう書くを開催しました

横浜へなちょこプログラミング勉強会 | Doorkeeper

Introduction to poloxy - proxy for alerting by YASUTAKE Kiyoshi

@key_ambさんは"poloxy" というアラートシステムの話をしてくださいました。 また、西日暮里.rbについてもブログにて言及してもらえており、大変嬉しいです。

keyamb.hatenablog.com

poloxyのv0.2もその後リリースされたようです  🎉

アラートをまとめるシステム "poloxy" の v0.2 をリリースしました - weblog of key_amb

るびまのはなしと原稿を書いたはなし by Yuta Kurotaki

下のスライドで、ドラム叩いてるスティックは@kurotakyさんのだという話がLT本編に負けず劣らず印象的でした。

るびまでは記事も編集者も募集しているようなので、ご興味のある方はぜひ!

デザイナさんにGithubでPR投げてもらうまで by Hideharu Okuma

デザイナとエンジニアが協力し合っていてチームの良さがにじみ出ているLTでした。もっと聞いてみたい方は、@halhideさんが西日暮里.rbに来ている時などに聞いてみると良いと思います。僕も今度もっと聞いてみたい。

グラフDB Neo4jのご紹介 by Kunihiko ITO

@kunitooさんには飛び込みでLTをしていただきました。mtsmfmさんのLTにもあった、「オフラインリアルタイムどう書く」のESM社内イベントにて取り組んだことについての発表でした。グラフデータベースへの興味が沸きました。

第2回 ESMオフラインどう書く · GitHub

uuidはどこまでuuidか試してみた by Yu Yamada

uuidが本当に衝突するか試していておもしろかったです。「Aurora使ってみた」というところの流れが個人的に好きです。特に会場でも盛り上がっていたような。

開発時の探し物を楽にする習慣作り by Koichi ITO

@koicさんには「ゴールデンな環境を求めて」ということでLTをしていただきました。僕も堕落するためにちょっと頑張っていきたいなと思います。また、このほかにも2本目のLTもしていただいたのでした。

上記の他にも、紹介しきれていない良いLTがたくさんありました。スライドを新たに公開したり、ここにあるよーという方はご一報くださればと思います。

まとめ

急遽LT大会をすることにして、告知する期間もあまりなかったので人に来てもらえるかなーと心配だったのですが、おかげさまで参加者もLTも集まったのでよかったです。終盤は飛び込みLTがさらに飛び込みLTを呼ぶという感じで、結局LT予定枠を30分オーバーし、会場の時間ギリギリまでLTが続くという活気にあふれた会でした。 ご参加いただいた皆様ありがとうございました。

なお、また6月の2周年記念でLT大会をします。ですので、ご興味もっていただけた方は、ふるってご参加くださいね。また、夏・秋ぐらいに名古屋でも西日暮里.rbができたらいいなーと思っています。

西日暮里.rb | Doorkeeper

CIでの確認項目

こんにちは、Misoca開発チームのmzpです。 GWは日光に遊びにいっていました。

MisocaではJenkinsを利用してCIによる自動テストを行なっています。最初はrspecを実行するだけのシンプルなものでしたが、都度設定を追加し、様々な項目をCIで確認するようになっていきました。

今日はそのCIで確認している項目について紹介したいと思います。

f:id:mzp:20160512140254p:plain

確認している項目

静的解析

コーディングスタイルのぶれや脆弱なコードを書かないようにするために、各種静的解析ツール(RubocopHAML-LintBrakeman)を導入し、警告がでないことを確認しています。

導入した直後は違反箇所の一覧を作成するのみで、ジョブの成否とは無関係でした。しかし、だんだんと違反箇所の修正をしなくなってしまったので、今は違反箇所がある場合はジョブが失敗する設定にしています。

rspec

全specの実行はrspec-queueで並列化した上で、実行します。

以前は失敗したspecがある場合でも全specを完走させていました。

しかし、開発メンバーの増加にともないビルドキューがつまり気味になってしまいました。そこで、 --fail-fast オプションをつけ、失敗したspecがある場合は以降のspecを実施しないようにしました。

また並列度は何度か調整をおこない、ほどよい数に制限しています。

デプロイできるかの確認(masterブランチのみ)

masterブランチのみですが、開発環境では実行することがほぼないデプロイ用のコマンドの確認を行なっています。

具体的には以下のコマンドが失敗しないことを確認しています。

  • RAILS_ENV=production bundle exec rake db:create db:migrate db:seed
  • RAILS_ENV=production bundle exec rake assets:precompile

何度かCIは通ったがデプロイしようとしたら失敗したということが発生したので、このようにしています。

その他: 夜間ビルド

CI で稀に失敗してしまうテストへの対処方法 - クックパッド開発者ブログにあるallnightジョブを参考に、夜間にmasterブランチにあるspecを繰り替えし実行しています。

これは「たまに失敗するspecがあるが、ビルドボタンを連打したらCIを通った」ということがしばらく続いたので、失敗するspecを洗いだすために実施しています。

洗いだしたspecは、適宜失敗する原因を突き止めて修正しています。ただ、外部サービスと通信するspec等があるため、なかなか全部成功にはできていません。

結果は毎朝Slackに通知されるようになっています。

f:id:mzp:20160512122705p:plain

Thinreports を支える技術 ~ Google Closure Tools 他 ~

こんにちは、開発チームの日高 @hidakatsuya です。「PDF」と言うキーワードに脊髄反射してしまう今日この頃です。

さて、今回は私が開発に携わっている Thinreports という OSS で、どのような技術・ライブラリが使われているかをご紹介したいと思います。

Thinreports

Thinreports は、いわゆる帳票を作るための Ruby 向けのオープンソースソフトウェアです。Misoca の一部の PDF 生成機能にも Thinreports が使われています。

Thinreports では、帳票レイアウトを作成する Thinreports Editor と、そのレイアウトから PDF を生成する Ruby ライブラリ Thinreports Generator を使って帳票を作成します。

もう少し詳しい説明は、弊社豊吉の記事がわかりやすいのでこちらをご覧ください。

toyoshi.hatenablog.com

誰が使っているか

本題とは全く関係ないのですが、この Thinreports が誰に使われているかをちょっとだけご紹介します。「帳票」と聞くと、国内だけで使われていると思われるかもしれませんが、実際はそうでもありません。

f:id:hidakatsuya:20160421005514p:plain

これは、公式サイト http://www.thinreports.org の 2011年12月から現在までの国別のアクセス数(セッション数)です。40% が海外からのアクセスで、当初はこんなに海外ユーザが増えるとは思いもしませんでした。もちろん、この結果と実際の利用者が一致するとは限りませんが、実際に海外ユーザからの問い合わせはとても多いです。英語大事。

Thinreports Editor

さて、本題です。今回は Thinreports の中でも、Thinreports Editor で使われている技術・ライブラリを紹介します。

f:id:hidakatsuya:20160421011618p:plain

Thinreports Editor は、マウス操作でけい線や図形、テキストなどを描画して帳票レイアウトを作成するデザインツールです。その中身は、以下のような構成になっています。

f:id:hidakatsuya:20160421040242p:plain

Chrome Apps を除けば、一般的な Web アプリのフロントエンドで使われる技術で構成されており、図形描画や UI の制御、処理の全てが JavaScript で書かれています。そのため、Chrome Apps の API に依存したファイル I/O といった機能以外は、そのままブラウザで動作させることができます。

ファイル構成

locales/
assets/
  |- fonts/
  |- icons/
  `- images/
app.html
app.js
background.js
manifest.json

background.jsmanifest.jsonChrome Apps のためのファイルなので、画像などのアセットを除けば、一つの JavaScriipt ファイルと一つの HTML ファイルだけで構成されていることになります。

Chrome Apps

What Are Chrome Apps? - Google Chrome

Chrome ブラウザをエンジンとしたデスクトップアプリを HTML5JavaScript/CSS 使って作ることができるプラットフォームです。Electron をイメージしていただくと良いですが、Chrome Apps の場合、OS ごとのパッケージは不要で、Chrome がサポートする OS *1 であれば、基本的にはそのまま動作させることができます。

作り方は非常に簡単ですが、GitHub で公開されているサンプルが参考になります。

github.com

Chrome Apps 以前は、Qt というライブラリでシンプルなブラウザを作り、その上で Editor を動作させるという構成でしたが、各 OS ごとのパッケージを用意することが面倒で、また OS に依存する問題なども多く発生したため、バージョン 0.8 より Chrome Apps を採用しています。

Google Closure Library

github.com

Closure Library is a powerful, low-level JavaScript library designed for building complex and scalable web applications. It is used by many Google web applications, such as Google Search, Gmail, Google Docs, Google+, Google Maps, and others.

GmailGoogle Docs といった、Google の主要プロダクトで実際に使われている JavaScript ライブラリです。arrayjson などの基本的なものから i18nsvg (graphics)、FileAPI といった HTML5、UI コンポーネント、テストフレームワークなど、実に多くのモジュールが含まれています。また、依存性の管理もサポートしています。

GitHub で開発が行われるようになってから特に開発スピードが速く、いつの間にか npm package も利用できるようです。

この Closure Library は、Thinreports Editor のほぼ全てを担っていると言っても良いほど、Editor にとって重要なライブラリです。Editor の図形描画は SVG によって実現していますが、Closure Library はリリース当時から SVG をサポートしており、これが採用する際の決め手となりました。

Google Closure Compiler

github.com

JavaScript 最適化ツールです。JsDoc ベースの静的型付が可能で、その名前の通りの最適化・圧縮を実現することができます。ES6 への対応など、Closure Library 同様、GitHub 上で活発に開発が進められています。

最適化の例として、例えば以下のコード。

/**
 * @param {string} name
 */
function hello(name) {
  alert('Hello ' + name);
}
hello('New User');

これを Closure Compiler (ADVANCED_OPTIMIZATION) でコンパイルすると、以下のように最適化されます。すごい。

alert('Hello New User');

その他、最近の状況は下記スライドが参考になります。 http://www.slideshare.net/teppeis/closure-compiler-updates-for-es6

Thinreports Editor では、Compiler の静的型付など、最適化のための機能をフルに活用して、数万行の JavaScript コードを 350KB 程度の一つの JavaScript ファイルへ最適化しています。この最適化のおかげで、図形描画といった重い処理のパフォーマンスを維持することができています。

Google Closure Stylesheets / Templates

その他、スタイルシートの圧縮には Closure Stylesheets を、一部の HTML 出力に Closure Templates といったライブラリも使っています。これらはいずれも、Closure Library や Compiler と同じく、Google Closure Tools の一部のライブラリです。

まとめ

今回、Thinreports の中でも Thinreports Editor についてご紹介しましたが、また別の機会に Generator の方も紹介したいと思います。ご紹介した Closure Compiler は、babel などの陰に隠れて若干存在感が薄い印象ですが、開発も活発で ES6 への対応も着々と進められていますし、最適化・圧縮を一度体験してみてはいかがでしょうか。

f:id:hidakatsuya:20160421033424p:plain

ECMAScript 6 compatibility table sas

*1:モバイル版 Chrome は除く

Misocaの朝会

はじめに

こんにちは、Misocaチーム from ファントムタイプのこくぼ @ です。 桜が散る頃ですね。フックブックローとポコポッテイトが終わって、たくみお姉さんも卒業していまいました。

f:id:yusuke-k:20160407103752j:plain

先週末に家族で東山動植物園に行ってきました。この植物園では色んな種類の桜が咲いていて色とりどりの桜を楽しめます。

f:id:yusuke-k:20160407103116j:plain

パッと咲いて雨とともに散ってゆく桜の花びらを見ていると、他の花にはない情緒を感じますよね。不思議です。

一日の計は朝にあり

皆さんのチームでは朝会してますか?おそらく多くのチームがやっているでしょう。 それでは、その朝会、意味ありますか?有意義な時間になっていますか?

毎日が小さなスプリントです。その日一日のスタートダッシュを決めるのが朝会です。 それに毎日やることだから最小限で最大の効果を求めたいですよね。 スプリントのゴールに向けた軌道修正を早めにするためにも朝会は大事です。

本記事ではMisocaチームで行われている朝会を紹介したいと思います。

Misocaの昔の朝会

ざっくりまとめると、昔の朝会には次のような問題がありました。

  1. 作業の見える化をしていないため、朝会時に何を確認したらよいのかわからない
  2. タスクボードや日報を書くことで見える化はしたが、人数が増えてきて全員分の報告をするのにやたら時間がかかるようになってきた
  3. 開発の話とマーケティングやその他の話題をすべてごった煮にしていたため効率が悪い

最初は2人から始まったMisocaも、資金調達をして人が増えていく過程で様々な問題が出てきました。簡単に言うとチームとしてのまとまりに欠いていました。

最初はスタンドアップで口頭だけの報告をして2,3分で終わっていました。それをやり方を変えて1人1人の共有時間を増やした結果、人数が増えてきてものすごい時間がかかるようになってしまっていました。

さらに開発チームもマーケティングチームも一同に集まる場であったため、テクニカルな相談をするのにも効率が悪い状態でした。

これらを改善するために知恵を出していった結果、今はこうなっています。

今の朝会

f:id:yusuke-k:20160407154216p:plain

3つの朝会

今のMisocaでは次の3つの朝会を順番に進めて行きます。

f:id:yusuke-k:20160407163304p:plain

順番に説明していきます。

全体朝会

所要時間: 約5分

Misocaチーム全員が集まって朝会が始まります。 Googleカレンダーを見て、来客の予定や出張やミーティングの予定を全員で確認します。Misocaのオフィスには会議室が一つしかないため、もしもミーティングや打ち合わせの予定がバッティングしてしまった場合はここで調整します。

後は、Trelloのボードを見て、全体への連絡、相談が行われます。 マーケティングチームから開発チームへの相談や、開発チームからの相談などが行われます。

開発チーム朝会

所要時間:約10分

マーケティングやその他のチームとはここで分かれて開発チームだけ集まって朝会をします。

開発チーム用のTrelloボードを見て、タスクの進捗状況を共有します。スプリントの計画と照らしあわせて重点的にレビューが必要なものや、設計・実装についての相談が行われます。

  • 「開発ブログ書いたのでレビューお願いします」
  • 「◯日にミーティングやりますんで頼みます」

といった話や

  • 「◯◯の設計で意見ください」
  • 「来月から新しいプロジェクトが始まるから体制について話をしましょう」
  • 「◯◯だけど、予定通りに終わらないかも、どうしよう?」

といった相談ごとについて話をします。 個別の話が長くなりそうだったら別途朝会の後に時間を設けます。

開発サブチーム朝会

所要時間:5分〜

さらに開発のプロジェクトごとのチームに分かれて話をします。 だいたい2人〜4人くらいの人数になります。

各自が抱えているタスクの突っ込んだ話をここでします。 その場でコードを見て簡易的なレビューをしたりすることもあります。

さらにスプリントの終了が近づいてくると、サブチーム内で次スプリントでやることの相談もします。

以上で朝会は終了です。3つもやってると長くなるイメージがあるかもしれませんが、だいたいの場合は20分くらいですべて終わります。

昔は45分くらいかかっていたことを考えると雲泥の差ですね。

ポイント

Misocaの朝会では全体から細部へと細分化して流れていきます。 最初に全体への共有事項の話をしてから、よりハイコンテクストな話へとシフトしていきます。 こうすることで、必要なタイミングで必要な人だけが集まって話をできるようになり、非効率な時間が少なくなりました。

細部から全体へ、じゃダメなの?

試してないのでわかりませんが、細部から全体へいくよりも全体から細部へいく方がよいと思います。理由としては開発サブチーム朝会まで進むと、その後の流れでその日の仕事に入れるからです。

朝会で相談したことを一緒になって考えたり、作業を進めたりと、自然な流れで仕事に入れます。 開発サブチームで朝会をした後に全体朝会をすると、コンテキストのスイッチが入ってしまうのでよくないんじゃないかなあ、という気がしています。

声を大にして言いたいこと

開発プロセスは生き物です。 Misocaの朝会も常に変わり続けてきました。

  • 常に変わり続ける努力をする
  • なぜ朝会をやる必要があるのか?について自問する
  • 問題だと思ったときに問題だと言える空気を普段からつくる

といった態度を持って仕事することがプロフェッショナルな社会人のあるべき姿だと考えます。

ツール

本記事で関係するMisocaで使っているツールを簡単に紹介します。

  • Trello
    • 連絡事項・相談
    • Product Backlog
    • Sprint Backlog
      • プロジェクトごとにラベルを付ける
    • その他いろいろ
  • Google カレンダー
    • 来客予定の共有
    • 出張予定の共有
    • ミーティング時間の共有
    • 早退するときとか
  • Googleハングアウト
    • リモートと音声や画面を共有
  • esa.io
    • 日報
    • ドキュメント管理

関連記事:

tech.misoca.jp

まとめ

Misocaの朝会、如何でしたでしょうか。 Misocaでは常によりよいやり方を目指しています。 今回紹介した朝会をいつまで続けるかもわかりません。

いつか、今よりもっと賢いやり方をご紹介できる日を楽しみにしています。

f:id:yusuke-k:20160407103252j:plain f:id:yusuke-k:20160407103952j:plain

開発ブログ1周年&弥生×Misoca

こんにちは、@dominion525 こと マツモトです。

好きな少将はノイエン・ビッターです。

1周年の件

Misoca開発ブログも昨年4月1日の開始からちょうど1年を迎えることになりました。

参考:Misoca 開発ブログを始めます - Misoca開発ブログ

1年間で49エントリの投稿なので、概ね1件/週のペースで記事が書かれていることになります。

イベントなどでお会いしたひとに「ブログ読んでますよ」的なことを言われることも多くなったので、開発チーム一同大変嬉しく思ってます。

2年目を迎えるMisoca開発ブログを今後ともよろしくお願いします。

ちなみに1年間の人気記事は次のとおりでした。

tech.misoca.jp tech.misoca.jp tech.misoca.jp

弥生×Misoca

さて既報の通り、Misocaは2016年2月26日付で弥生会計を擁する弥生株式会社にジョインすることとなりました。

参考: 弥生株式会社による株式会社Misocaの全株式取得について

単にプロダクトやユーザベースのみではなく開発チームやそのカルチャーも含めての評価であると認識しており、自分たちの行ってきたことが外部からみても意義があることだったのだと大変に嬉しく思っています。

先方の弥生社は100名を超える開発チームとなっており、いままでのぼくら基準からすれば大変に大きな組織です。 また長い歴史をもつデスクトップ製品に由来していることから、堅牢で厳密な仕様を重視されています。 Misocaはクラウドネイティブなサービスであり、俊敏で変化への耐性を大切にしています。

このブログでも何度か言及されているように、Misocaの開発チームは「軽量、俊敏であること」「試行してみて失敗したら速やかに改める」「人を責めない」などいくつかの基本動作を持っています。 ぼくらが考える「理想的な開発チーム」に向けてこれからも改善し、より磨き上げていかなければならないのですが、その成果を弥生社側にもフィードバックしポジティブな影響を与えられるようになればいいなと考えています。 弥生側は、ぼくらが持っていなかった大きなリソースをすでに所有していたりもしますので、それらの活用も今後の課題かと思います。

両社は開発手法や様々なポリシーも異なるところが多くあり、当初はギャップも大きいかと思います。 その中でお互いの良い所を吸収し、目指すビジョンのために相互に頑張っていきます。*1

Misoca の名前の由来

2011年10月頃、郵送できることを軸にオンラインで請求書を便利に管理できるサービスを作ってみたはいいものの、なかなか良いサービス名が決まらない感じでペンディングされていたのですが、2週間くらいして流石にそろそろ決めないとまずい感じになってきました。

いろいろ考えた結果、「月末処理を楽にするサービスに」*2という気持ちを込めて「みそか」と名付け、ローマ字綴りにして「Misoca」となったのでした。 これは、かつて日本でも採用されていた太陰太陽暦では一月は30日であり、各月の末日のことを「三十日(みそか)」と呼ばれていた *3 ことにちなみます。

名前を考えるにあたっては「弥生会計は会計年度が3月決算なので弥生(3月の旧称)というらしい」というのを意識していたところもあり、幾つか候補があった中でも「むこうは決算で弥生(3月)ならば、ぼくらは月末で行こう」みたいに決めたような記憶があるのでいろいろ感慨深い感じです。*4

ですので、今日3月31日は「弥生の晦日」ということで、両社には意義深い日ということになりますね。

ご案内

ということで3月31日を日本記念日協会認定の「経理の日」として登録しました。

それを記念して、先着331名様にオリジナルTシャツをプレゼントするキャンペーンも行っています! お世話になっているデザイナさんに作っていただいた素敵Tシャツですのでぜひお願いします(3色あります)。

www.misoca.jp

メンバー紹介

開発ブログ2年目に向けて、改めて開発チームメンバ(≒ブログ執筆陣)の紹介を行います。*5

関数型言語方面を中心としていろんな背景のメンバーがいるのですが、基本的にはRuby on Rails によるサービス開発を行っています。

普段の活動についてはこちらのエントリなどをご参照ください。

参考:DevLOVE現場甲子園2015『西日本大会』でMisocaチームの話をしてきました - Misoca開発ブログ

まとめ

  • Misocaとその開発チームは今後もビジョンの実現に向けて頑張っていきますので応援よろしくお願いします。
  • 弊社や各メンバーはコミュニティ、勉強会、イベント、SNSなど各種の活動を積極的に行っています。見かけた際にはぜひ仲良くしてください。
  • 一緒により良いチームを作っていきたい人は是非いちど会社見学に来てください。ランチご馳走いたします♪ (遠方のかたはリモートでも対応します)

*1:「まあ、結婚みたいなものですね」と言ったら、「お前独身だろ!」と総ツッコミ受けましたが><

*2:なお「月末処理を」といいながら、実際には月初〜5日くらいが一番稼働率が高かったりするのはご愛嬌です。

*3:「三十日」は「晦日(みそか)」とも書き、現代でも12月31日を「おおみそか(大晦日)」と呼ぶのはその名残ですね。「晦日」は「つごもり」とも読むのですが、そちらは概ね廃れた感じです。

*4:なので「名古屋だから味噌」」とか「みそカツ」とかは全く関係がないし、関東方面の人に訊かれるまで考えたこともありませんでした

*5:文責は筆者にあります。

Feature Specで複数ユーザーのやりとり(マルチセッション)をテストする

はじめに

インターンのhmryuです。今週、Misocaのインターンを卒業しました。僕は、昨年のお盆明けから約7ヶ月間Misocaでエンジニアとして働いていました。とくに後半の4ヶ月は、発注機能の開発に関わっていました。

現在の発注機能では、複数のユーザーがコメントのやりとりやファイル共有を経て、発注できるしくみになっています。

もともと、発注機能のFeature Specでは、コメントや発注などを別々のsenarioで書いていましたが、それだと不必要に冗長な部分が増えてしまいコードの修正が難しくなっていました。そこで、1つのscenarioで発注機能全体をテストできるように大幅な修正を行いました。

(Controller Specについては、ミニマムリリースを意識していたらコードが肥大化していた話にまとめてあります。)

f:id:hmryu:20160323131237p:plain

マルチセッションのFeature Spec

そこで問題になったのは、セッションの切り替えを行う必要があるという点です。例えば「あるユーザーがコメントした後に、その通知メールを受け取った別のユーザーがリンクを開いてコメントする」という動作では、ユーザー間でセッションが引き継がれてしまっていると、うまくテストができません。

そこで、Using multiple Capybara sessions in RSpec request specsを参考にして以下のようなメソッドを定義しました。

def in_browser(name)
  old_session = Capybara.session_name
  Capybara.session_name = name
  yield
  Capybara.session_name = old_session
end

in_browser メソッドに、ユーザーごとの処理をブロックとして渡すことで、セッションを切り替えながらテストすることができます。実際のFeature Specは以下のようになりました。

scenario 'コメントでやりとりをし、発注者が発注できる' do
  # 発注者がファイルをアップロードする
  in_browser(:buyer) do
    # ... logic ...
    expect_to_show_download_button
    expect_to_upload_file(file)
    # ... logic ...
  end

  # 受注者がファイルを受け取ってコメントする
  in_browser(:seller) do
    # ... logic ...
    click_document_url_in_mail

    expect_to_show_uploaded_file(file)
    expect_to_submit_comment('ファイル受け取りました')
    # ... logic ...
  end
end

補足

Capybara.current_session は以下のように実装されているため、Capybara.session_name を変えることで異なるセッションを参照するようにできます。

https://github.com/jnicklas/capybara/blob/master/lib/capybara.rb#L319

module Capybara
  class << self
    def current_session
      session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
    end

    def session_name
      @session_name ||= :default
    end
  end
end

まとめ

実際にユーザーが使う流れをそのままscenarioに書くことで、テストがわかりやすくなり、変更も加えやすくなりました。

7ヶ月と短い期間でしたが、Misocaのインターンでは、エンジニアとして様々な経験ができました。名古屋近辺の学生で、エンジニアのインターンに興味がある方はぜひMisocaにジョインしてください!

おまけ:重複した処理をメソッドに切り出す

各ユーザーに複数のメールが届くので、下記のようなメソッドを作っておくと便利でした。

def inbox(email)
  ActionMailer::Base.deliveries.select { |m| m.to.include?(email) }
end

実際に使うときは、下記のようになります。

in_browser(:buyer) do
  mail = inbox(email).last
  # ... logic ...
end