はじめに
クラウドワークスエンジニアの八木です。 先般の記事でも触れられていた通り、クラウドワークスではシステムのフレームワークとして採用している Ruby on Rails を 3 系から 4 系に移行しました。
残念ながら、「こことそことあそこを直して、さあリリース!!!」とはいかず、それなりの時間を投入して行いました。
今回は、Rails のバージョンアップをスムーズに行えないという技術的課題は一旦脇に置いておいて、フレームワークのバージョンアップという「事業の KPI に直接寄与できない開発課題」に対して、クラウドワークスの開発チームがどのように取り組んだか、組織体制の話を書いてみたいと思います。
チーム体制の変遷
まず、クラウドワークスで Rails4 対応するために組んだ組織構成について、時系列に沿って簡単にご紹介します。簡単にご紹介と言いつつ先に要約すると、最初は Rails4 対応に専任チームを設けていて、最終的にはテストを全エンジニアで分担して時期を調整しながらリリースを進めました、といったところです。
1. Rails4 対応黎明期
当時インフラを担当していたエンジニア1〜2名で、検索負荷の対策や開発環境の構築、いろんなインフラタスクの合間に Rails4 の対応を始めました。この間は、アップグレードガイドを参照して修正を行ったり、Rails4 に対応させるパッチを書いたり、テストの拡充をしていたりしました。
2. 休止時代
だんだんとエンジニアが増えていくにつれてプロジェクトも増えていき、サーバ構築の自動化と Rails4 対応が並行して行われている時期がありました。しかしそれでは中途半端ということで、一旦インフラのメンバーはサーバ構築の自動化に注力し、Rails4 対応は小休止する期間がありました。
3. チーム時代
インフラ自動化がひと段落したあと、 Rails4 対応する組織が、正式に「Rails4チーム」として発足しました(筆者もこのときからジョイン)。
まずは Rails4 で CI を動かしたりアプリケーションを立ち上げてひたすらバグ潰しを行い、ある程度目処が立ったところでテスト環境の構築*1や、機能ごとに Rails4 をリリースすることができる環境を作るためのインフラ構成変更を担当しました。
4. テスト分担時代
テスト環境の準備が整ったあと、クラウドワークス全体の機能を分割して全エンジニアに割り振りました。それぞれの機能はリリースする日がスケージューリングされていて*2、割り振られた各エンジニアがスケジュールから逆算したテスト期間でテストを行っていました。
Rails4チームはプロジェクト全体進行役として、テスト環境の更新やリリース、特急で作った新インフラ構成の運用を自動化する作業などを行っていました。
5. コード掃除・インフラ掃除週間
晴れて全機能を Rails4 化させたあと、Rails3/Rails4 を互換で動かすためのアプリケーションコードや、並行運用に使ったインフラリソースのコードを消すために、お掃除週間を設けました。全リリース終了後に、Rails4 チームだったメンバーが一週間集中して、残課題の解消に取り組みました。
組織課題に対して、どう解決していったか
どうやったらリリースできるか
Rails4 アップデートプロジェクトの目的はもちろんサービスを Rails4 で動かすことですが、暗黙的には「障害を可能な限り少なく」という前提があります。この「障害を可能な限り少なく」をどうすれば現実的に行えるかという点の認識が、最初はメンバー間で合わせることができていませんでした。
リリースの条件として、テストのカバレッジをどのくらいまであげたらリリースするとか、ランダムに選んだ一部のユーザーからリリースしていくとか、とにかくリリースするとか、いろいろな案がありました。
しかし、障害が起きた時に切り戻しを行うのは当然として、
- いち早く切り戻すためには他のリリースを止める必要があるのではないか
- バグがあった場合にそれが既存のものか Rails4 化に起因するものか、区別して切り戻し判断をすることは可能なのか
- Rails4 のリリースの試行錯誤をしている期間中の開発でまたバグが増えたらいつまでもリリースできないのではないか
などなど、全体を一気にリリースすることには不安が付きまといます。
Rails4チームのメンバーで「なぜリリースに踏み切れないのか」を考え直し、少し時間がかかっても確実に終わらせることのできる方法として、「機能ごと、URLごとにリリースしていく」ことを決めました。「とにかく全部同時にリリースして、問題があったら戻して、直してまた全部同時にリリース」を繰り返すことに比べると、遥かに見通しの立てやすい計画になり*3、障害も少なくリリースすることができました。
全員の手を借りるために
全エンジニアに機能を分割して割り振り、リリースのスケジュールに合わせてテストの実施、およびバグが出たら対応する、ということを行いました。
一口に「全員でやる」と言っても、「一旦サービスの機能開発や他のバグ修正などを控えて、Rails4 化されるまで全ての時間を Rails4 対応に費やす」というのでは大変です。まず終わりが見えないので事業の見通しが立たないですし、全員で取り組むといっても人によって得手不得手やサービスについて詳しい部分が違うので、トラブルが起きた時にタスクを均等に割り振れるとも限りません。
今回の Rails4 化プロジェクトでは機能ごとにテスト・リリースを行うことで、
- 責任範囲を分割すること
- スケジュールを予め明確にしておくこと
この二点の工夫をすることができました。結果的には全員体制ではありましたが、想定とは違った形の「ゆるい、計画的な全員体制」でやることができ、所属チームの機能開発を行いながらも Rails4 化のリリースを進めることができました。
不要なコードを消す時間を確保するには
みなさんはこんなコメントに見覚えはないでしょうか。
# このコードは xxxx が終わったら消す
Rails4 化の完了の目処が立つにつれて、完了後の予定が次々と埋まっていきます。このような一時的なコードや、 Rails3 でのみ(もしくは、 Rails3 と Rails4 の並行稼動でのみ)必要なコードを消す時間がうまく取れないのではないかという疑念が持ち上がってきました*4。
そこで、今回の Rails4 化プロジェクトでは、「お掃除週間」を設けることにしました。あらかじめ「6月第三週は、 Rails4チームだったメンバーは Rails4 の掃除をやる」と決めておく、といったものです。
この取り組みは非常にうまく働いたように思います。
チームが解散したあとの「前のチームの仕事」であり、かつ緊急ではなく、事業インパクトもない優先度の低いタスクばかり(しかし、今やっておかないと放置されて後で辛くなるもの)でした。そういったものに対して、一週間という期間を決めて集中して時間を割いたことで、確実な進捗が得ることができました。予め日程を宣言していたため、「前のチームの仕事」ではあっても現チームとの調整もスムーズに行うことができました。
より良い体制で臨むには
各エンジニアメンバーがチームで持っているタスクに割り込んで、月に何日か作業時間を確保してもらうのは、簡単なことではありません。何も考えず「さあみんな手伝って!!」といっても、「チームのタスクが忙しくなったため、進捗していません・・・」などと言われてしまう可能性もあります。
そういった問題なく進められたのは、
- 全員体制になる前に、チームとして一定期間取り組んでいたこと
- テスト環境の作り込みに時間を投資したこと
この二点が鍵になったと思います。チームとして一定期間取り組んでいたため、直し方の方針も固まっていましたし、同じ原因で別の箇所もバグっているといったいわゆる「同件調査」のフォローを行うこともできました。
以上、 Rails のバージョンアップに取り組んだ際の工夫、反省についてのお話でした。
この記事が、大きな開発課題に取り組む際の参考になれば幸いです。
We're Hiring !
クラウドソーシングのクラウドワークスでは、技術的な課題にチームで立ち向かうエンジニアを募集中です。