みんなのコンピュータサイエンス読書会

こんにちは、Misoca開発チームの黒曜(@kokuyouwind)です。

最近はVTuberのシャニマス実況を見て無限に時間を溶かしています。だいたい委員長のせいです。

📕 みんなのコンピュータサイエンス読書会

Misocaでは有志で集まりみんなのコンピュータサイエンスの読書会を開催しています。

みんなのコンピュータサイエンス

みんなのコンピュータサイエンス

読書会を始めたのは「単に自分が読みたかったから」という理由が大きいのですが、コンピュータサイエンス(以下CS)の知識のベースラインを揃える取り組みをしたかったという面もあります。

チームメンバーの来歴はCSの専門課程を経た人から独学でプログラミングを学んだ人まで様々です。

例えば「MySQLのクエリはインデックスが効かないと遅くなる」という知識ひとつをとっても、CSの知識があれば「インデックスが探索木になっているから、Ο(log N) と Ο(N) の差があるんだな」とイメージを持てるのに対して、計算量や探索木の知識がない場合は「とにかくインデックスが効かないとだめなのかな」という理解になってしまいかねません。このように理解の齟齬がある状況では、「どの程度のサイズのテーブルで、どのカラムにインデックスを足すべきか」といった議論がまともに成り立たなくなってしまうでしょう。

こういった問題を防ぐために、CSの基礎知識をチームで揃えるのは重要だと個人的に考えています。その点で、CSの基礎を広く平易に扱ったこの本はちょうどよい題材になったと思います。*1

🏃‍♂️ 進め方

読書会では、節ごとに誰かが音読してから掘り下げて議論する流れを取っています。これは読む速度で取り残される人が出ないようにするとともに、内容をしっかり掘り下げられるようにするためです。

掘り下げ議論では、詳細を追って参加者全員の理解を確認することに加えて、現実での応用例や自社サービスで使える箇所がないかなどもよく話しています。例えば貪欲法の節では並列テストのグループ振り分けに利用している話や、探索木の節ではMySQL InnoDBのインデックスがB+木である話などをしていました。

掘り下げの際にMiroを使ってグラフや図を描くこともあります。以下は動的計画法のボトムアップについて、グラフを描いて確認したものです。

f:id:kokuyouwind:20200526173251p:plain:w480

ツールをろくに使わずフリーハンドで描いているため汚いですが、こういった図を描きながら話すことでより理解しやすくなりました。もう少し使いこなせるようになりたいですね。

📈 進捗

年初から始めて、現在5.3節までを読み終わったところです。本全体の半分ちょっとくらいでしょうか。

かなりゆっくりしたペースですが、これはかなり掘り下げて理解を確認しながら進めていることと、参加者の都合が合わず中止になる日も多いためです。

特に基礎となる論理・確率や計算量などは理解しないまま進めてしまうと後で困りそうだったので、1章で大きく時間を割いていました。

残りもこのペースでじっくり読み進められればと思います。

📢 宣伝

MisocaではCSの基礎を固めて業務に活かしたいエンジニアを募集しています!

*1:ベースラインを揃える目的で、基本情報技術者試験などの取得を推奨する企業も多いと思います。そちらも有効な手段だと思いますがやや堅苦しくなってしまうため、個人的には読書会くらいのライトさが好みです。

IaC を意識しつつ、Redash を ECS に移行する

先日、弊社内で利用する Redash のインフラ構成を docker-compose on EC2 な環境から ECS, RDS, ElastiCache に移行し、さらに Redash を v7 から v8 にバージョンアップしました。今回はどのように移行を進めたのか、どのようにバージョンアップ作業を行ったのかを紹介します。

これまでのRedash

Redash サーバは開発合宿の成果物として社内に導入されました。当時は動作することを優先させるために、公式が提供するEC2 AMI から docker-compose を使ってコンテナ群を立ち上げるようにしていました。DBやインメモリストアといったミドルウェアも docker-compose でコンテナとして起動している状態でした。

tech.misoca.jp

その後、社内の KGI/KPI や Misoca の SLO の可視化など、利用シーンが広がり社内の重要度が高まってきていました。

tech.misoca.jp

tech.misoca.jp

そうなると、不安となるのがシステムのレガシー化です。1台の EC2 インスタンス上で全部動かしていたのでコンピューティングリソースの不足が気になりますし、Redash のバージョンアップの際も懸念材料となっていました。

というわけで、レガシーになってしまう前に Redash サーバのインフラを見直し、強く柔軟な構成に移行することにしました。

Redash の新インフラ構成

最初に触れたように、新しいインフラ構成は ECS, RDS, ElastiCache を使ったマネージドサービス中心の構成にしています。

f:id:mizukmb:20200518103208p:plain
Redash 新インフラ構成

Server サービスには Redash の画面を提供する Docker コンテナを起動するタスク定義を指定いており、このサービスにのみ ALB を経由した外部アクセスができるようにしています。Workers サービスにはクエリを実行等を行う複数のDocker コンテナを集約させたタスク定義を指定しています。

Workers サービスが起動する Docker コンテナの種類は公式のdocker-compose.ymlと同じにしています。こういう構成にしようというこだわりが無かったので公式に合わせました。後々変えていくことはありうると思います。

インフラ構成のコード化

インフラ構成のコード化 (IaC) は、今では当たり前のようになってきましたが、ここで今一度 Redash のインフラ構成のコード化によって得られる恩恵は何であるかを列挙します。

  • コードがドキュメント代わりになる
  • コードレビュー、CI/CDといったソフトウェア開発で用いられる手法がインフラでも使える

その他にも様々な恩恵・利点は確かにありますが、今回は上記2点に絞りコード化の作業を進めました。

インフラ管理には Terraform を利用しました。社内でも既に AWS リソース管理に使われており、ほぼこれ一択という感じで決定しました。もっと様々な観点から他のツールも検討するべきとは思いますが、社内向けのアプリケーションであることと、自分以外の作業者でも問題無くコードが読めること (ドキュメント代わりになる) を重視した結果、社内で広く使われているツールを採用することにしました。

Terraform のファイル構成は以下の通りです。AWS のリソース毎にファイルを切り、 provider や Terraform 自身の設定は main.tf に集約させています。

.
├── README.md
├── ecs.tf
├── elasticache.tf
├── lb.tf
├── main.tf
├── rds.tf
├── task-definitions
│   ├── redash-server.yaml.tpl
│   └── redash-workers.yaml.tpl
└── vpc.tf

ちなみに、 task-definitions の yaml ファイル群はこちらの Issue コメントを参考にして、一度 yamldecode したオブジェクトを jsonencode して読み込むといった一手間を加えています。

GitHub Actions を使ったテスト、apply の自動化

プルリクエスト時の terraform plan や master ブランチ更新時の terraform apply といった事を自動で行うために GitHub Actions を使ってこれらを実現します。HashiCorp 社の公式テンプレートがあるので、今回はこちらを利用しました。

github.com

プルリクエスト単位では fmt -> init -> validate -> plan の順番で実行し、 plan を除いた全て成功すればグリーンとしています。また、 plan の結果についてはプルリクエストのコメントに残すようにもしています。この辺の設定も tf_actions_comment: true とするだけで良いのでとっても簡単です。 master ブランチ更新時 (= PR マージ時) には上記サイクルに加えて最後に apply を実行して、実際に Terraform の定義と AWS リソースの状態を合わせるようにしています。こうすることで、 master ブランチ == AWS リソースの状態となり、常に最新の状態を確認できるドキュメントとしても十分に機能してくれます。

……と、ここまで hashicorp/terraform-github-actions の使い方等を紹介しましたが、どうやら記事執筆時点ではこのリポジトリはアーカイブ状態になっていて、今後は積極的な開発やメンテナンスが行われないようです。今後は hashicorp/setup-terraform の使用が推奨されますので、皆様もこちらを使う方が良いかと思われます。私自身使ったことは無いので紹介だけ。

github.com

作業時点では hashicorp/terraform-github-actions リポジトリもアーカイブになっていなかったので、コミット履歴等を見るに最近決まったみたいですね。設定したばかりなのにまた書き直さないといけないのか (とほほ)。

Redash v7 → v8 へのバージョンアップ

Terraform による IaC と、GitHub Actions による CI/CD のセットアップが完了し、残すは Redash アプリケーションのバージョンアップ作業のみとなりました。ここまでくれば、バージョンアップ作業は Terraform のコードをいじって PR をマージするだけで作業は完了してしまいます。

f:id:mizukmb:20200519104255p:plain
GitHub のプルリクエストを使って Redash のバージョンを上げている様子

resource aws_ecs_task_definition が持つ container_definitions で設定する image の値を変更します。 Redash の公式 Docker イメージは Docker Hub で管理されているので、そこから v8 系のタグを探して Terraform 側で設定してあげましょう。

hub.docker.com

バージョンアップのPRをマージすることで GitHub Actions から terraform apply が実行され、 AWS ECS のタスク定義とサービスを更新します。サービスは自らのタスクを入れ替えてデプロイが完了します。

NOTE: Terraform を使った AWS ECS リソースの更新について

今回、AWS ECS 周りのコード化〜自動デプロイまで全て Terraform で行いましたが、実際にやってみるといくつか気になる点が出てきました。

まずは、タスク定義のリビジョンが更新されず、最新のリビジョン番号の内容を上書きしてしまう点です。例えば前回のデプロイ内容をリビジョン番号から辿れなくなってしまう問題があります。リビジョン番号が更新されないのは resouce aws_ecs_task_definition の仕様であり、私も事前に知ってはいましたが、コード自体は Git でバージョン管理できているしロールバックするのも git revert 等やり方は色々思い付くので大丈夫だろうと思っていました。しかし、やはり AWS 上でもリビジョンは更新されてほしいという気持ちもあります。

次に、 ECS へのデプロイ戦略についてです。社内向けアプリケーションということもあり、デプロイは ECS タスク総入れ替えという結構豪快なやり方を取っていますが、ダウンタイムやロールバック方法についてよりシビアに考えるのであれば、ローリングアップデートや blue-green デプロイといった方法でデプロイができるのが好ましいでしょう。 terraform apply ではこの辺りの融通が効かず、難しい印象を受けました。 Terraform で工夫するよりも、コード管理は Terraform, デプロイは他のツールを使うといった併用の形を取っても良いと思います。

今回はデプロイについても Terraform で行うようにしましたが、こちらについては他のデプロイツールの使用も検討して良いかもしれないという個人的な学びがありました。

まとめ

弊社内で利用している Redash のインフラを ECS やその他マネージドサービスへの移行と IaC 化、そして自動デプロイを使った v8 へのバージョンアップについて紹介しました。

まだまだ詰めきれていない部分も多いですが、こちらについては少しずつ磨いていければと考えています。ひとまずは移行が完了してホッとしています。

採用

今回の作業は SRE 業務の一環として行われたものです。 SRE 職種では IaC でいい感じにやっていくことが好きな方々を募集しています。

recruit.misoca.jp

開発メンバー id:mizukmb でした。

突撃!! 隣のリモート飯 🥄

こんにちは。@kawamataRyoです。
いつもは技術に関する話題を投稿している本開発ブログですが、今回は番外編としてMisocaのリモートワーカーのお昼事情の紹介します!

Misocaのリモートワークベテラン勢はどんなリモート飯を取っているのか?
急にリモートワークが始まり毎日のお昼ご飯に悩んでる皆さんの参考になれば嬉しいです。

@torimizuno

角煮ラーメン

f:id:ba068082:20200422083526p:plain

こだわりポイント

  • 夜に炭水化物を抜くので、お昼は炭水化物メイン
  • フルリモートになり、炊飯器でつくる角煮と味玉を仕込んだので、ラーメンにトッピング
  • 有名ラーメン店の器で食べるとそれだけで美味さマシマシです (器はお土産に友人から貰いました)

@k0matatsu

焼肉(円盤状無煙カセットコンロ)

f:id:ba068082:20200422083548j:plain

こだわりポイント

イワ◯ニを信じて肉を捧げろ

@rktm

パン(完全栄養食)

f:id:ba068082:20200422083616j:plain

こだわりポイント

  • 手で半分に割ってスライスチーズとハムを盛ってレンジで1分半というスピード調理
  • なんと、洗う食器はお皿一枚!
  • 糖質少なめながら一食に必要な栄養を賄える
  • 作り始めから食べ終えて食器を洗うまで15分で終わるので昼休憩の残り時間を有意義に使える

id: eitoball

サプリメント or プロテイン

走ったら、サプリメント

f:id:ba068082:20200422083643p:plain

走っていない時は、ソイプロテイン

f:id:ba068082:20200422083711p:plain

こだわりポイント

  • 走ったら、回復が早くなる(らしい)サプリメント を飲むようにしています。ちょっと癖のある味だけど、慣れるとやみつきになります。

id: sunflat

カレーライス(自炊)

f:id:ba068082:20200422083731j:plain

こだわりポイント

  • 圧力鍋で野菜と肉を煮込んで柔らかくしている
  • 食物繊維が不足しがちなので、胚芽押麦を混ぜた麦ごはんを使っている
  • 野菜が不足しがちなので、野菜を多めにしている
  • 隠し味に、カットトマト缶とレーズンととんかつソースを入れている
  • 多めに作って冷凍したいので、じゃがいもは入れてない

@mizukmb

ホットサンド

(ホットサンドの写真が無かったので先日作ったダルゴナコーヒーの写真を代わりに載せておきます。)

f:id:ba068082:20200422083752p:plain

こだわりポイント

  • 春に行われる有名なパンの祭りでシールを集めるために買った食パンを消費するため
  • 具材は適当ですが、スライスチーズは万能選手なのでたくさんあると良いです

@kanizmb

宅配すし 🍣

f:id:ba068082:20200422084757j:plain

こだわりポイント

  • 普段は冷凍食品・コンビニ・残り物で適当にすませるのですが、元気がない時やリリース終わりのめでたい時などには宅配すしを利用します
  • 午後の眠気対策に、お昼を食べずに1時間昼寝することもわりとあります

id:ryotaway

低糖質

f:id:ba068082:20200422084821p:plain

こだわりポイント

  • 1日1食、お昼だけとってます
  • 基本的に卵・肉・チーズしか食べないのですが、たまに味噌汁が飲みたくなるのでその時は味噌汁を作ります
  • これだけだとタンパク質が足りてないので、お昼以外の時間帯にプロテインを飲みます
  • 写真はないですが、チーズをおやつとしてちょこちょこ食べます
  • 食後はコーヒーで締めます

id:yoshoku

納豆

f:id:ba068082:20200422084909j:plain

こだわりポイント

  • カラシを足してます。

@Tooka_91

冷凍パスタ + 白米 + プロテイン(牛乳割り)

f:id:ba068082:20200422084940j:plain

こだわりポイント

  • 痩せやすい体質なので、とにかく何でもいいから食べる。
  • 冷凍パスタは200円でコスパ◎。(オフィスの近くで食べたら、1000円はする。)
  • タバスコが好きなので、いっぱいかける。
  • プロテインを飲めば、野菜を摂取しなくても健康になれるらしい。

@mugi_uno

\\\ 冷 凍 食 品 ///

f:id:ba068082:20200422085001j:plain

こだわりポイント

  • 昼なんて空腹を満たせればなんでも良いんですよ!!

@nezurika

炒めもの+味付け卵+サラダ

f:id:ba068082:20200422085019j:plain

こだわりポイント

  • 下味冷凍していた鶏肉(これはマヨしょうゆにんにく)と冷凍していた切ったねぎと冷凍していたしめじを炒めたものです
  • 味付け卵は週末のリモート飲み会用に作って余ったものです
  • 基本的に、何かしらの炒めものがおかずにあれば良い
  • ご飯はいつもは解凍してラップのままお茶碗に乗せています
  • 映えなんてなく日常なんてこんなもんですよ

id: mallowlabs

スパイスカレー (自炊)

f:id:ba068082:20200422085037j:plain

こだわりポイント

  • 調理時間があまりかからない料理を作っています
  • スパイスカレーは最近ハマっていて、煮込まずに作れるのと、スパイスがあれば作れるので気に入っています
  • しかも結構おいしく作れます
  • 難点があるとすれば、常に部屋がインドの香りになることくらいです

@kosappi_

近所の肉屋のお弁当

これは日替弁当が唐揚げだったときの唐揚げです。

f:id:ba068082:20200422085112j:plain

こだわりポイント

  • お昼は基本的に完成したものを調達するスタイルです
  • 昼休みになると、妻と娘の3人でお弁当屋まで散歩します
  • 密にならないように気をつけています
  • お弁当は日替わりですが事前に電話すれば好きなメニューを作っておいてくれます(すごい!)
  • 金曜日はかならずカレーです

@kawamataRyo

プロテイン(波動拳風味) + 完全栄養食 + EAA

f:id:ba068082:20200422083209p:plain

こだわりポイント

  • 美味しい粉です。
  • 昼休みは、懸垂・腕立て・ランニング・仮眠と色々やりたいので効率よくエネルギーが取れることに注力してます
  • 元袋のジップはちゃちいので、粉を移し変えておくと毎回の開け締めのUXが向上するのでオススメ。

終わりに

いかがでしたでしょうか?お昼ごはんの参考になりましたか?
「インスタ映えの連発だわい」と思って集めたお昼ごはん画像ですが、思いの外クセが強かったです。
美味しいお昼ごはんでパワーアップして午後の業務に備えましょう!!!

採用

Misocaでは、お昼ごはんにも開発にもこだわりを持つエンジニアを募集しています。

組織構造で余力を生み出す!「遊軍」チームを作ったらこぼれタスクをどんどん消化できるようになった

はじめに

こんにちは、 @rktm です。

Misocaではプロジェクトを開発プロセスの基本としています。

recruit.misoca.jp

ですがプロジェクトの枠からこぼれるタスクが増えてきました。 それらタスクをこなすべく、1年ほど前に「遊軍」というチームを作りました。

遊軍チームは当初はお試し運用でしたが価値を継続的に出せており、今は定着しています。 その遊軍チームについて、創設の背景、運用結果について書きます。

前回のブログ記事「フロントエンドチームはじめてました」と合わせて、Misocaでの、問題を個々人の努力だけではなく、組織構造の変化によって解決する事例としてお読みいただければ幸いです。 tech.misoca.jp

遊軍創設の背景:個々人の「余裕」「余力」に頼っていてはこなせないタスクが積み上がってきた

Misocaでは、2018年末ぐらいから大規模な機能追加・改修プロジェクトが複数走り、余裕のない状態が続いていました。

サービスを運営していると、日々お客様からの要望や、マーケティング担当からのリクエスト、不具合・障害の対応、分析作業、リファクタリングなど「 重要度も大きさも緊急度も様々」なタスクが発生します。

大規模プロジェクトに追われていた結果、気づけば以下のようなタスクが山積みになっていました。

  • 重要度: 非常に高いわけではないが、無視できるほどは低くない
  • 大きさ: プロジェクト化するほどは大きくないが、一人がプロジェクトの片手間でやるには手に余るボリューム

この記事ではこれらを「こぼれタスク」と呼んでおきます。

余裕のない時に起こること1: 「このタスク誰かお願いできますか?」「…(誰も手を挙げない)」

余裕がない状態では、プロジェクトメンバーはプロジェクトの目標やゴール達成に注力するため、プロジェクト外の作業にリソースを割くことに躊躇しがちです。突発的な問い合わせや障害の対応に取り組みづらくなりました。(この時の「誰かやってくれ〜 🙏 」という無言の空気は、なかなかつらいものがあります)

ということで、個々人の余裕に頼るとこぼれタスクの消化は安定しませんでした。

余裕のない時に起こること2:「余裕ができたらやる(やらない)」

「このプロジェクトが終わって余裕ができたらやる」というタスクは、プロジェクトの終了が延びがちであり、その結果次のプロジェクトがすぐに始まるため、結果的に後回しになりがちでした。

ということで、期間で余裕を作ろうとしてもなかなかうまく回らないものです。

解決策としての遊軍チーム: 組織構造として「余力」を作る

上記を踏まえ、Misocaでは個々人に頼ることなく定常的に「余力」を生むべく、遊軍チームを創設しました。

遊軍(ゆうぐん)とは - 遊軍の読み方 Weblio辞書

①  待機していて、時機を見計らって出動し、味方を助ける部隊。遊撃隊。
②  特定の所属や任務がなく、忙しい仕事やむずかしい仕事を状況に応じてする者。 「 -記者」

遊軍が対象とするスコープは以下の通りに定義しました。

  • 不具合対応等、突発的なタスク
  • お客様サポート部門・マーケティング部門などから上がってきた要望の対応
  • プロジェクト化するほど大きくないタスク
  • タスクのボリュームは、最大でも2週間ほどで終わるもの。

遊軍とプロジェクトの対比は以下の通りです。

f:id:RKTM:20200414174057p:plain
プロジェクトと遊軍の差

遊軍を運用してどうだったか

チームの規模としては、最低2人、新メンバーの受け入れやプロジェクトの狭間のメンバーの参加などで平均すると3人程度でした。

遊軍がやってきたこと

直近でブログに公開したタスクは以下の通りです。

その他にも、

  • お客様の要望:文書の件名の最大文字数を40文字から70文字にする(簡単なように見えて、いくつかのPDFテンプレートを変更するなど意外に大変でした)
  • 軽微な修正:日付系の入力フィールドにてautocompleteをオフにする
  • CIでしばしば失敗するテストを安定させる
  • 社内メモの文字数についての調査
  • デザイナーチームのビュー変更によりテストが失敗するようになったときも、ヘルプに入って迅速にマージまで持っていけた

などを行ってきました。

(ここに書ききれないような、小さな改善、リファクタリング、他プロジェクトのレビューによる支援など、多くの「こぼれタスク」をこなしています)

遊軍チームを作って、どうだったの?

遊軍内の評価

  • 溜まっていたお客様からの要望に対応できるようになり、よりお客様によりそえるようになった
  • CIの安定化に貢献することで開発チーム全体のスピードを落とさずに済んだ
  • 後回しになりがちな仕様書のアップデートにも時間を割けるようになった(斧を研ぐ時間を確保できている)
  • 新しくジョインしたメンバーの受け入れ先として機能している

外からの遊軍の評価

プロダクトマネージャーより

「プロジェクトにするほどでもない大きさの価値を、継続的に提供できるのがとても助かっています。

遊軍はある意味「余力」と捉えられがちで、最初の頃は廃止してプロジェクトにリソースを回した方がよいのでは?という声もありましたが、守ってよかったです」

デザイナーチームより

「長期間をかけて生み出すチームとは別軸で、短期間で価値を提供できるチームが発足し、実際に価値提供の頻度もあがっていると感じています。(リリースのお知らせ数が過去最高になりました)

いつでも相談できる窓口が仕組み化されたことで、細かなデザイン改善でやりたいことが発生した時も迷うこともなく相談でき、とても助かっています。」

マーティング担当より

「未来に向けた大きな取り組みを進めつつも、日々生じる改善や新規要望への対応も止めるわけにいかない。Misocaがその両輪を回すために無くてはならない、『縁の下のスピードスター』みたいなチームです。

こちらからの要望対応だけでなく、「え、そんな改善を進めてくれていたの?」というサプライズもちょくちょくあって、『縁の下のファンタジスタ』みたいなチームでもあります。」

お客様対応(カスタマーセンター)担当より

「これまで製品ロードマップに沿った計画的なリリースが中心とならざるを得ない状況でした。

そのため日々、お客さまからいただく改善要望などがなかなか反映できない(後回し)になる状況でした。遊軍チームが出来たおかげて、順次、機能改善を中心とした要望がリリースされています。

その結果、お客さまからも感謝のコメントをいただいたり、これまであった問合せがなくなったり(問題点が解消)する効果が出ています。カスタマーセンターとしても感謝していますし、何より、お客さまにとっても目に見えて実感できる改善が継続して提供できるような体制ができたことが嬉しいです!」

おわりに

遊軍チーム創設当初の目論見通り、

  • 組織構造として余力を作ることで、
  • 余力の中で「こぼれタスク」をスムーズに処理する

ということができていると評価しています。


Misocaでは、問題を解決するにあたり、個人の意識や頑張りだけでなく、仕組みや組織の変更で対応したいと思う人を募集しています。

www.wantedly.com

フロントエンドチームはじめてました

こんにちは @mugi_uno です。 某ウイルスで不安な日々が続きますが、ひとまずうがい・手洗いをちゃんとやっています。

フロントエンドチームができてました

f:id:mugi1:20200403115327j:plain:w600
最近買ったiPadProが嬉しくて書いてしまった謎のロゴ

Misocaでは半年ほど前にフロントエンドチームを新たに立ち上げました。 自分たちなりの形でひっそりと活動を続けてきて、幾つか成果も出てきています。

なぜチームを作ったのか / 何をやってるのか といった点をご紹介したいと思います。

徐々に表面化してきたフロントエンドの課題

Misocaでは個々人が「バックエンドエンジニア」「フロントエンドエンジニア」といった肩書を持っておらず、必要に応じてバックエンドもフロントエンドも触ります。

しかし、全体的にはフロントエンド側に比重を置くのは一部のメンバーに限られており、それに伴うさまざまな課題が表面化してきました。

個々人による改善活動が厳しくなってきた

フロントエンド全般に関わるような改善作業は、気になった人が隙間時間を見つけて対応していました。

それはそれで良いことですが、ボリュームの大きいタスクでは「途中で他の作業が忙しくなって続けられなくなる」「永遠に終わる気がしない」といった状態が危惧され、なかなか手をつけづらい状態が続いていました。

誰に頼めば良いのかわからない問題

フロントエンドに注力した作業は、プロダクト・デザインなどさまざまな方面から発生しますが、受け口が存在せずに「これは一体誰に相談すれば...??」となることがありました。

属人化とスキル・知識の偏り

適宜難しい技術要素については勉強会やペアプロ・モブプロを実施していましたが、気軽に相談する口も無いため、一部のメンバーに作業が偏ることも多く、スキル・知識の共有が上手くいかない部分が出てきていました。

→「チームが必要なのでは?」

問題について色々考えてみましたが、「個々人でバラバラに対応可能なフェーズを過ぎてしまったのだろう」と予想し、何らかのチームとして対応する体制を試してみても良さそうだな、という結論に至りました。

チームを作るにあたってやったこと

小さくはじめる

そもそも「チームを作って課題を解決できる」が既に予想でしかなく、空振りに終わる可能性も考えられます。 いきなり大体的にドカンとスタートするにはリスクがあるため、まずは活動時間短め&少人数で立ち上げることにしました。

具体的には次のような形です。

  • 興味のあるメンバーを数人募る
  • プロダクトチームに所属したまま、一部の時間をチームの活動に充てる

万が一「チーム意味なかったな」となっても、スパッとやめられるのが理想と考えました。

フロントエンドチームって一体何?を定義した

チームで集まって最初にやったのは、

  • 自分たちが一体何を目的として集まっているのか
  • 何をする(しない)べきか
  • 誰のために活動するのか

といった点を話し合い、「フロントエンドチームって何?」の認識を揃えました。 (この場はチームメンバーのみではなく、PdMやデザイナーにも参加してもらいました。)

「こんなフロントエンドチームはいやだ」

場の中で、チームのアンチパターンを話し合ってみました。 結果、次のようなものが出てきました。

  • ビジネスの成長に繋がらないことばかりをやってる
  • 全体の生産性向上に繋げられていない
  • 「それはバックエンドの仕事ですから」とか言い出す
  • 「面白そうだし流行ってるから良くわからないけど○○入れようぜ!!」とか言い出す

チームとして不穏な方向に走り出してしまわないよう、あらかじめガードレールを敷設しておくようなイメージです。

ミッションは何か

そしてチームが取り組むべき課題は何なのかを定義します。

最終的には、Misoca全体が望む方向に進むためにベストな支援をしていくのが理想の形だろう、という結論に至り

Web版Misocaにおいて、皆が思い描く理想のユーザ体験を実現するための技術領域での障壁を取り払う

をミッションに定めています。

f:id:mugi1:20200403112433p:plain
esaのREADMEでいつでも読める

チーム稼働から、今までにやったこと

実際にチームが走り出して実際に達成したこととして、わかりやすいタスクとしては

  • TypeScript型定義の強化
    • 皆がコードを書いた時に、無意識に負債を生まないためにコードを堅牢化
    • noImplictAny の無効化
  • Boostrap依存の撤廃
    • Bootstrap(驚異の2.x系)へのJS依存の完全撤廃
    • ユーザー体験統一プロジェクトの支援*1

などが挙げられ、直近ではAPIのGraphQL化などが計画されています。

また、日常的にフロントエンドチームのSlack上で技術相談を受けてペアプロ・モブプロを実施することで、開発チーム全体の支援を行ったり、今までは個人で対応していたような細かい依頼もチームとしてカバーしながら消化しています。

結局チームを作ってどうだったのか

現在もまだ試行錯誤を続けていますが、ひとまず順調に回るようになっており、概ね良い効果が出てきているかなと感じています。

  • 困ったときに気軽に相談できる受け口ができた
  • 長期的な改善計画を立てて、個々人が忙しくなってもカバーできる体制ができた
  • メンバー間でスキルや知見の共有ができるようになった

従来目立っていた明らかな課題は徐々に解消されつつあります。

とはいえチームだからこそ見えてきた課題もまだまだありますので、少しずつより良い形になるように見直していければな〜と思っています。

採用

Misocaではフロントエンドエンジニアを募集しています!

はじめまして、リモートワーク

2月からMisocaの松江オフィスに勤務している原田です。
入社して2ヶ月程立ちましたので、入社してからのことを書こうと思います。


自分は、前職ではオフィスワークをしていたのですがMisoca入社をきっかけにしてリモートワークを始めました。*1
今回は、恥ずかしい話ですがオフィスワークをやってきた人間がリモートワークを始めた時の失敗話を書いていきます。


Misocaのリモートワーク事情は下記の記事に詳細がまとめてあるので、こちらではさらっと書きます。

tech.misoca.jp

MisocaではZoomを利用して常時接続のミーティングをしており、コミュニケーションツールはSlackを利用しています。
常時接続のミーティングには、入社した際に支給されるZoom接続用のiPadを使っています。


仕事風景です。
仕事風景です。

失敗話: ミーティング遅刻

オフィスワーク時代だと、開発作業に集中している時でも他のメンバーが会議室に移動し始めることで気づいたり、早く気づいた際には事前に会議室の前で待機したりしていました。
ただ、リモートワークになると開発作業に集中しているとそういったことも無くなるので、時間が過ぎてSlackで呼び出されてからミーティングに向かうことがありました。


一緒の空間にいる時には、その人が単純に忘れていただけなのか重大な問題が発生していてミーティングに出られないのかデスクに向かえばすぐに聞けます。
リモートワークの場合は、応答が無い限り自分がどうしているか待っている相手は分からないので不安にさせてしまいます。*2


今は、カレンダーの通知時刻をミーティングの2分前にセットするようにして通知が来たら手を止めるように意識しています。

失敗話: 何をやっているか分からない

オフィスワークでは同じ空間にいるので、集中していてそっと話しかけた方が良いのか逆に何があったのか聞いた方が良いのかといった雰囲気は大体分かりますが、リモートワーク上だと詰まっているのか順調なのか状況が中々分かりづらいという所があります。


ありがたいことにMisocaでは分報の文化が整っていたことやタスク管理に利用しているTrelloのコメントがプロジェクトメンバーのいるSlackのチャンネルに流れるようになっていました。


この辺りを利用して、自分がこれからやろうとしていることを分報に投稿しつつ、タスクの分からない点や触ってて気づいた点をTrelloのカードにコメントするようにして、自分が何をやっていてどういう理解をしているのかというのをなるべく周りにアウトプットするようにしています。


分報
分報(一部)

まとめ

以上 2 点が、リモートワークを始めた自分の失敗話でした。


振り返ってみると当たり前の話だなと感じつつ、働く環境が変わることで今まで出来ていたことが出来なくなっていたのだなと思いました。
リモートワークでは物理的な距離が無いので、いかに周りのメンバーのことを意識できるかが大事なのかなと考えています。
周りの人のアウトプットを拾ってサポートしつつ、自分自身もアウトプットを出して周りの人がサポートしやすくする。そういった所をこれからも意識していこうと思います。


拙い話でしたが、新年度になってこれからリモートワークを始める方々の参考になれば幸いです。


Misocaではこれからリモートワークを始めてみようかなと考えているエンジニアを募集しています!

*1:気分転換を兼ねて週1程度松江オフィスに出勤しています

*2:ミーティングに限った話では無いですが…

さようならrrrspec、いままで速度をありがとう

Misoca開発チームの黒曜(@kokuyouwind)です。

今回の記事タイトルは銀河ヒッチハイクガイドからの引用です。*1

その水棲動物を見よ。

🤖 MisocaのCIとrrrspec

MisocaではCIが短時間で終わるよう、rrrspecを利用してRSpecを分散実行していました。関連記事もいくつか書いています。

tech.misoca.jp

tech.misoca.jp

自分の入社時に20分ほどかかっていたビルドが5分ほどで収まるようになり、またメンバーが増えても並列性を担保できたのはrrrspecの力による部分が大きいといえるでしょう。

…が、残念ながら昨年2月にrrrspecのActive Maintenanceが終了してしまいました

その後もMisoca社内でforkしたリポジトリを保守しながら運用していたのですが、次第に以下のような問題が顕在化してきました。

  • RubyやGemのバージョンアップにどこまで追従できるかわからない
  • 問題が発生したときに、関与するミドルウェアが多く調査に時間がかかる
  • rrrspecの仕組みに詳しいメンバーが少なく、保守や問題対応でそのメンバーに負荷が集中する

上記にはActive Maintenance終了と直接関係ないものもありますが、いずれにせよこのままrrrspecを使い続けるのは厳しいだろうと判断し、仕組みを載せ替えることになりました。

🧭 載せ替え先の検討

結構な力技でrspecを回していたため、載せ替え先でもある程度並列実行できるものにしないと現実的な時間で終わらないということはわかっていました。

このため以下のようにいくつかの案を作り、それぞれの速度や運用コストを見積もった上でどれにするかを判断しました。

  • 並列実行をサポートしているCircleCIに載せ替える
  • knapsackを使ってテストスイートを分割し、Jenkinsfileのparallelでノード分散実行する
  • parallel_testsを使い、スペックの高いJenkins Slaveノード1台の内部で並列実行する

それぞれを試験実装してみたところ、CircleCIは運用費用が現状から大きく跳ね上がってしまうこと、knapsackでの分散はparallel_testsに比べてノードの性能を引き出しづらいことがわかりました。

またCircleCIに載せ替える場合は現状のJenkins + parallel_testsから一本化する必要があり乖離が大きいこと、他のJenkins Jobが残っているためJenkins自体は止められずCI環境が複数になること、などの懸念もありました。

これらの調査結果を踏まえて、実行速度と運用コストのいずれも許容範囲内であったparallel_testsへ載せ替える方針としました。

🏎 parallel_testsへの載せ替え

rrrspecからparallel_testsに載せ替えるにあたり、もともと使っているJenkins Slaveではspec実行環境が整っていないという問題がありました。

頑張ってMySQLなどの依存ミドルウェアを立ち上げ、Rubyもバージョンアップに追従させて… というのはしんどそうだったため、Dockerを使ってspecを実行することにしました。

細かいところを端折ったJenkinsfileは以下のようなものです。

node('parallel_worker) {
  withEnv([
    "COMPOSE_FILE=docker-compose.test.yml"
  ]) {
    stage('checkout') {
      checkout(scm)
    }
    stage('build') {
      sh 'docker-compose build'
    }
    stage('test') {
      sh 'docker-compose run --rm app rake parallel:rake[db:reset,18] parallel:spec[18]'
    }
  }
}

Pipeline組み込みのDocker文法を使う方法もありましたがサイドカーコンテナの扱いがややこしそうだったため、単純にdocker-composeを使うだけにとどめています。

また18並列という数字は並列数を変えながら検証して得られた数字で、これ以上に並列数を上げてもほとんど実行時間が変化しませんでした。

spec実行にはc5.12xlargeインスタンスを利用しています。このレベルのインスタンスだと1台でも結構なコストなので、JenkinsのAmazon EC2 Pluginを利用して必要なときだけspotインスタンスが立ち上がるようにしました。

🏁 結果

さすがにDocker立ち上げやRails起動などのオーバーヘッドが大きく5分には収まりませんでしたが、6分ほどでrspecの実行が終わるようになりました。

f:id:kokuyouwind:20200317190135p:plain

🛠工夫が必要だったところ

作業中にいろいろと罠を踏んだり工夫したことがあるのですが、それぞれ細かく書くと長くなるのでざっくり箇条書きしておきます。

  • parallel_testsのparallel_runtime_rspec.logはJenkins Artifactに格納して、次以降のジョブでcopyArtifactを使って引っ張ってくるようにしました
  • Docker内で出力するファイルのオーナーがホストとずれてしまい消せなくなってしまったため、user namespaceを使って揃えるようにしました
  • EC2 Pluginremoting.jarに実行権限が付与されておらずslave立ち上げに失敗していたため、Slave command prefixchmod a+rx /tmp/remoting.jarを挟んでいます
  • 同じくEC2 Pluginで、Ubuntuを使う場合はRemote userubuntuの指定が必要でした。Usageに書いてありますが、ちょろっとしか書いてないので見落としやすいです

💬 感想

今回の置き換えでCIにかかる時間は少し長くなってしまいましたが、以下のように得られたメリットも多くありました。

  • rrrspecクラスタがなくなったことで管理する対象が格段に減った
  • Jenkinsローカルでテストを実行することで、失敗時スクリーンショットなどの収集を簡単に行えるようになった
  • Dockerベースにしたことで環境の切り替えが楽になり、レイヤーキャッシュが効くため複雑な自前キャッシュを減らせた

rspec実行に時間がかかるのも、テストが多すぎる・重すぎるという問題の比重のほうが多いため、ここからは仕組みの改善ではなく既存テストの棚卸しといったことが必要になってくるのではないかと思っています。

最後に、rrrspecには導入してからの3年半ほど、MisocaのCIを支えていただきました。コミッターの皆様、これまでありがとうございました。

📢 宣伝

Misocaでは「生命、宇宙、そして万物についての究極の疑問の答え」を探求するエンジニアを募集しています。

あとCIの仕組みを改善したいエンジニアも募集しています。

*1:前回タイトルはRe:ゼロ引用でしたが1ミリも伝わらなかったので、今回は自ら言っていくことにしました