タイミーのブログ - TECH PLAY

TECH PLAY

タイミー

タイミー の技術ブログ

308

こんにちは。バックエンドエンジニアの須貝( @sugaishun )です。 今回はタイミーが本番運用しているRailsアプリケーションに対してRuby3.3.0へのアップデートを行った(YJITは引き続き有効なまま)のでその結果をご紹介したいと思います。 昨年弊社の id:euglena1215 が書いたエントリーのRuby3.3.0版です。 tech.timee.co.jp 前提 タイミーのWebアプリケーションとしての特性は基本的には昨年と変わりありません。ですので、昨年の内容をそのまま引用させてもらいます。 タイミーを支えるバックエンドの Web API は多くのケースで Ruby の実行よりも DB がボトルネックの一般的な Rails アプリケーションです。JSON への serialize は  active_model_serializers  を利用しています。 今回の集計では API リクエストへのパフォーマンス影響のみを集計し、Sidekiq, Rake タスクといった非同期で実行される処理は集計の対象外としています。 今回はRuby3.2.2+YJITからRuby3.3.0+YJITへアップデートを行い、パフォーマンスの変化を確認しました。 結果 以下のグラフはAPIリクエスト全体のレスポンスタイムの50-percentileです。 グレーの点線がアップデート前の週で、青い線がアップデート後の週になります。集計した期間ではアップデート前後の平均でレスポンスタイムが 10%高速化 していました。 今回も前回にならってレスポンスが遅く、時間あたりのリクエスト数が多いエンドポイントに注目し、タイミーのWeb APIのうち3番目に合計の処理時間が長いエンドポイントへのパフォーマンス影響を確認しました。 以下のグラフは3番目に合計の処理時間が長いエンドポイントのレスポンスタイムの50-percentileです。こちらも同様にグレーの点線がアップデート前の週で、青い線がアップデート後の週になります。集計した期間ではアップデート前後の平均でレスポンスタイムが 約12%高速化 していました。 またECSの起動タスク数にも良い変化がありました。 タイミーではCPU使用率が一定の割合になるようにタスク配置する設定をしているのですが、リリース後は起動タスク数が減りました。リリース前後1週間の比較で下記のように変化しています。 平均で33.1 tasks → 30.36 tasks 最大値で58.6 tasks → 53.0 tasks このあたりはYJITの効果でリクエストに対するCPU負荷が下がった影響ではないかと推測しています。メモリ上に配置した機械語を実行するJITならでは、という感じがします。コスト的にどれだけインパクトがあるか具体的な数値は出せていませんが、パフォーマンス以外のメリットもありそうです。 と、ここまでは良かった点です。 以降では自分たちが遭遇した事象について述べたいと思います。 一部のAPIでメモリ使用率が増加 タイミーのRailsアプリケーションはモノリスですが、ECS上ではネイティブアプリ向けのAPIとクライアント様の管理画面向けのAPIはそれぞれ別のサービスとして稼働しています。前者のネイティブアプリ向けAPIでは特に問題なかったのですが、後者の管理画面向けAPIでは メモリ使用量の最大値が約3倍超(20%弱→65%程度)になりました。 以下のグラフの赤いラインがRuby3.3.0にアップデートしたタイミングになります。 さすがに3倍超は困ったなと思い、 YJITのREADME を読んだところ下記のようにありました。 Decreasing --yjit-exec-mem-size The  --yjit-exec-mem-size  option specifies the JIT code size, but YJIT also uses memory for its metadata, which often consumes more memory than JIT code. Generally, YJIT adds memory overhead by roughly 3-4x of  --yjit-exec-mem-size  in production as of Ruby 3.3. You should multiply that by the number of worker processes to estimate the worst case memory overhead. We use  --yjit-exec-mem-size=64  for Shopify's Rails monolith, which is Ruby 3.3's default, but smaller values like 32 MiB or 48 MiB might make sense for your application. While doing so, you may want to monitor  RubyVM::YJIT.runtime_stats[:ratio_in_yjit]  as explained above. メタデータ( yjit_alloc_size )の増え方が想定以上なのではと思いつつ、ddtrace *1 では yjit_alloc_size は送信していないようなので、 code_region_size を確認。実際、YJITの code_region_size (JITコードのサイズ)とメモリ使用率はほぼ同じ動きをしていました。以下のグラフの左が code_region_size で、右がメモリ使用率です。 というわけで --yjit-exec-mem-size をデフォルトの64MiBから32MiBに減らしたところ、メモリ使用量はアップデート前より少し増えた程度の水準まで抑えることができました。なお、この変更によるパフォーマンスへの影響は見られませんでした。 以下の右のグラフがメモリ使用率で、赤いラインが --yjit-exec-mem-size の変更をリリースしたタイミングになります。実際にメモリ使用率が下がっているのが見て取れます。 今回のメモリ使用量の大幅な増加は完全に予想外で、ステージング環境でもメモリ使用量の変化はウォッチしていましたが、特に大幅な増加は見られず本番環境で初めて発覚する事態になりました。すでにRuby3.2系でYJITを有効にしているプロダクトでも、Ruby3.3.0+YJITにアップデートされる際には --yjit-exec-mem-size の値には注意したほうが良さそうです。 まとめ Ruby3.2ですでにYJITを有効にしているプロダクトでもRuby3.3.0にアップデートしてパフォーマンスの改善が見られました(YJITの影響なのかそれ以外の最適化による恩恵なのかまでは検証しておりません)。 すでにYJITを有効にしていた場合でもRuby3.3.0へのアップデートでメモリの使用量が大幅に増加する可能性があるので注意しましょう。 調査の際には下記の(主にk0kubunさんの)ドキュメントに非常に助けられました。この場を借りてお礼を申し上げます。 github.com k0kubun.hatenablog.com gihyo.jp 本エントリーがこれからRuby3.3.0+YJITへアップデートされる方のお役に立てば幸いです。 *1 : タイミーはDatadogを使っています。ddtraceはDatadogにメトリクスを送信するgemです
イベント概要 2024年2月21日に「GENBA #2 〜Front-End Opsの現場〜」と題してタイミー、Sansan、ココナラ、X Mileの4社でFront-End Opsに関する合同勉強会を開催しました。 今回はそちらの勉強会からタイミーフロントエンドエンジニアの西浦太基さんの発表をイベントレポートでお伝えします。 こんにちは、西浦 太基です。家族で北海道札幌市で暮らす33歳です。 Javaでキャリアをスタートし、今はフロントエンドエンジニアとして3年目になります。趣味はカレー作りとゲームです。 本日は「いつか来たる大改修のために備えておくべきこと」について、実際に大きな改修を経験して学んだこと、泥臭い現場の話や反省点を、エピソードベースでシェアします。 1. どんな大改修だったか 店舗向けの管理画面をシングルページアプリケーション(SPA)へ移行する改修でした。もともとサーバーサイドレンダリング(SSR)で構築されていたシステムを、ReactとNext.jsを使用したSPAに段階的にリプレイスしていきました。改修した機能は大きく下記3つです。 求人機能(作成/編集) 求人ひな形機能(作成/編集) メッセージ機能(一覧表示/送信) 2. 泥臭かったこと 既存機能の仕様調査に苦労 既存のSSR画面の詳細なドキュメントが残っておらず、非常に苦労しました。これは、タイミー入社前のSler時代もよく経験したことで、 “あるある” なのですが、状況を打開するためには非常に泥臭い調査が必要です。もちろんドキュメントが全く残っていないわけではなく、Figma や Notion に部分的に残されてはいたのですが、完全にはカバーされていません。おまけにソースコードの情報が必ずしも正確でないこともあり、かなりの時間と労力をかけ、調査を行いました。 E2E自動化の仕組みがなく、431件のE2Eテスト項目に自動テストを実施した ユニットテストはコンポーネント単位で存在していましたが、E2E自動化の仕組みが存在しませんでした。VRT(Visual Regression Testing)は、Storybook を用いて行われていたのですが、今回のプロジェクトの規模や顧客への影響を考えると、軽い検証を行うだけではリスクが大きいと判断し、結果的に 431件の E2Eテストを手動で泥臭く実施する道を選びました。 レビュー体制がなく、レビューコストが大きくなった 当時のフロントエンドチームはレビュー体制の整備が不十分で、メンバーも限られており、レビューコストが高くなってしまいました。チームは僕を含めてわずか2人と、非常勤の業務委託1人。レビューに十分な時間を確保するのが難しく、プロジェクトの進行に影響が出ていました。そのため、レビューを効率的に進めるために、一人のエンジニアの時間をまとめて確保し、一気にレビューを完了させる方法を取りました。本来は、フルリモートでの非同期レビューを行える体制が理想的だと思います。 3. 備えておくべきと感じたこと 機能の仕様は背景込みで残しておく 詳細なソースコードコメントや定義書があれば、将来の改善に役立ちます。特に複雑な機能や多くの入力項目を持つ場合、実装の背景を理解することで、後々の改善が容易になり、属人化を避けることができます。最近は、Figma や Notion に仕様と背景を含めて記録するよう心がけています。 自動化テストの仕組みを導入する これまでUTやVRTが充実していれば、そこまでE2Eは重要ではないと考えていました。しかし、今回のリプレイスを経て、自動化テストの重要性を再認識しています。E2Eによって、UTで検知できない問題をリリース前に特定できることがあり、改めてE2Eの重要性と自動化の利点を実感しました。 レビュー時の観点を整備 レビューの文化を根付かせておく 同時にレビュー時の観点や視点に関してチーム内で明文化 ドキュメント化することで普段からレビューコストを下げておく レビュー文化をしっかり根付かせつつ、レビューのポイントをチーム内でしっかりドキュメント化しておくことが大事です。ドキュメント化してないと、都度のすり合わせで時間を取られ、レビューコストが増えます。その結果、リリースサイクルも遅れたりするわけです。現在はフロントエンドチームの拡大もあり、レビュールールを明文化する作業を進めています。 まとめ 私がSler時代に直面した、「ソースコードを見なければ仕様が理解できない」といった “あるある” な内容も含め、日頃から大きなリプレイスに向けた心構えや備えが必要性を共有できたら嬉しいです。泥臭い作業を発見したら、悲観的になるのではなく「これは考え直すタイミングだな」というマインドを持つことも大切かと思います。 n個と言いつつそこまで数は挙げられなかった 日頃から大規模リプレイスに備えた心構えをしておくことは大事 (何が起こるかもわからないので)かもしれない運転 あるあるな内容になったと感じている Timee以外のプロジェクト(SES就業時代)でも直面した事が多かった 泥臭いこと゠備えておくべきこと、に繋げるマインドが大事に感じた その他の方の発表も気になる方はこちら! www.youtube.com 少しでも興味を持っていただいた方は是非こちらからカジュアルにお話しましょう! product-recruit.timee.co.jp
はじめに こんにちは、株式会社タイミーの貝出と申します。データサイエンティストとして働いており、直近はカスタマーサポートの業務改善に向けたPoCやシステム開発など行っております。 さて、今回は2024年3月11日(月)~3月15日(金)に開催された「言語処理学会第30回年次大会(NLP2024)」にオンラインで参加してきましたので、参加レポートを執筆させていただきます。 言語処理学会年次大会について www.anlp.jp 言語処理学会年次大会は 言語処理学会 が主催する学術会議であり、国内の言語処理の研究成果発表の場として、また国際的な研究交流の場としての国内最大規模のイベントとなっています。 今回の年次大会は第30回を迎え、発表件数が599件、参加者数(当日参加者は除く)が2045人と大会の規模も過去最大となっており、年々大会が盛り上がっていることが伺えます。 ※ 下のグラフは大会のオープニングで共有されたものです。 言語処理学会第30回年次大会に参加できなかった方でも、 こちら から発表論文が閲覧できます。 興味深かった研究 初日のチュートリアルから最終日のワークショップまで興味深い発表がたくさんありましたが、個人的に気になった発表をいくつかピックアップします。 [C3-4] InstructDoc: 自然言語指示に基づく視覚的文書理解 概要 こちらの研究では、自然言語指示に基づいて文書を視覚的に理解するための基盤データセット「InstructDoc」が提案されています。InstructDocは、12種類の視覚的文書理解(VDU)タスクから構成され、多様な自然言語指示を提供する最大規模のデータセットとなっています。 研究チームでは、大規模言語モデル(LLM)の推論能力を活用し、文書のレイアウトや視覚要素を同時に理解することが可能な新しいモデル「Instruction-based Document reading and understanding model(InstructDr)」を提案し、実験を通じてその性能を検証しています。InstructDrは、自然言語指示を基に未知のVDUタスクに適応し、従来のマルチモーダルLLMの性能を超えることが確認されました。また、指示チューニング済みのモデルの重みを初期値としてFine-Tuningすることで、複数のVDUタスクで世界最高性能を達成しました。 感想 こちらの研究では視覚的文書理解の汎化性能の向上に貢献されています。自然言語指示を用いて文書画像からタスクを汎用的に実行できる技術は、社内オペレーションの様々なタスクを容易にする可能性を秘めており、今後の研究にも期待です。 NTT人間情報研究所の方による以下の過去発表資料と今回の研究はリンクする内容だと感じており、合わせて読むことで全体像がイメージしやすかったです。 Collaborative AI: 視覚・言語・行動の融合 - Speaker Deck [A6-1] Swallowコーパス: 日本語大規模ウェブコーパス 概要 オープンな日本語言語大規模モデルの学習には、CC-100、mC4、OSCARなどのコーパスの日本語部分が用いられてきました。しかし、これらはあくまで海外で開発されたものであり、日本語テキストの品質を重視して作られたわけではありません。 そこで、研究チームは商用利用可能な日本語コーパスとしては最大のウェブコーパスを構築しました。Common Crawl のアーカイブ(2020 年から 2023 年にかけて収集された 21スナップショット分、約 634 億ページ)から、日本語のテキストを独自に抽出・精錬し、最終的には約3,121 億文字(約 1.73 億ページ)からなる日本語ウェブコーパス( Swallowコーパス )を構築しています。 Swallowコーパスは、「(1) Common Crawl の WARC ファイルから日本語テキストを抽出する。(2) 品質フィルタリングおよび重複除去で日本語テキストを厳選する。(3) テキスト内の正規化を行う。」の手順により構築されました。 Swallowコーパスを用いて Llama 2 13B の継続事前学習を行ったところ、既存のコーパスを用いた場合と比べて同等かそれを上回る性能の LLM を構築できたと報告されています。 感想 業務上LLMの日本語大規模コーパスを作ることはありませんが、自然言語処理のデータセットを作成するうえでのTipsとして大変勉強になりました。例えば、日本語判定をするためにサポートベクターマシンを学習させ fastText より高速化させた話や、MinHash による文書の重複判定など。 また、 [A8-5] では Swallow コーパスを利用した継続学習について詳しい内容が発表されており、そちらも面白かったです。 [ A7-6 ] AmbiNLG: 自然言語生成のための指示テキストの曖昧性解消 概要 大規模言語モデル(LLM)の登場により自然言語の指示を用いた指示によって様々な言語処理タスクが実行可能になりました。しかし、これらの指示の曖昧性によりユーザの意図と異なるテキストが生成されることが問題となっています。 こちらの研究は、自然言語生成(NLG)タスクでの指示テキストの曖昧性を解消するためのベンチマークデータセットとして「AmbiNLG」が提案されました。AmbiNLG でのデータセットの作成に LLM を用いてアノテーションを行い、幅広い29のNLGタスク2000事例からなるデータセットを構築されています。また、実験により曖昧性補完の手法については、実験により複数の曖昧性カテゴリを明示的かつ組み合わせで与えることが重要であると示唆されました。 感想 LLMを使いこなすためにはプロンプトを適切に調整することが重要だと言われていますが、指示テキストの曖昧性を能動的に指摘 or 修正できるような仕組みがあれば、よりユーザーフレンドリーなLLMを構築することが可能かと思われます。個人的にも欲しい機能です! 今後の展望では、曖昧性認識・追加指示の生成・推論をend-to-end で行う対話システムの構築について言及されていたので、実際にユーザの意図をどのようにシステム側で汲み取っていくかが気になります。 おわりに NLP2024では、他にも多数の魅力的な研究が発表され、5日間という期間が非常に充実したものとなりました。特に、大規模言語モデル(LLM)に関連する研究が目立ちましたが、その範囲はデータの構築から事実性や安全性の検証に至るまで広がっており、多様な角度からの研究成果を見ることができたのが印象的でした。 現在、タイミーでは、データサイエンスやエンジニアリングの分野で、共に成長し、革新を推し進めてくれる新たなチームメンバーを積極的に探しています! また、気軽な雰囲気での カジュアル面談 も随時行っておりますので、ぜひお気軽にエントリーしてください。↓ hrmos.co hrmos.co
こんにちは、iOSエンジニアの前田( @naoya_maeda ) 、早川( @hykwtmyk )、三好、岐部( @beryu )、Androidエンジニアのみかみ( @mono33 )です。 2024年3月22-24日に渋谷で開催されたtry! Swift Tokyoに、タイミーもGOLDスポンサーとして協賛させて頂きました。 私達もイベントに参加したので、メンバーそれぞれが気になったセッションを紹介します。 特に気になったセッション(前田編) 僕が特に気になったセッションは、リルオッサさんによる「SF Symbolsの芸術的世界:限りない可能性を解き放つ」です。 リルオッサさんは、iOSDC Japan 2022でも SF Symbolsアートの可能性 についてお話されており、今回のセッションでは、アニメーションを交えたダイナミックなSF Symbolsアートを紹介されていました。 SF Symbolsとは SF Symbolsは、Appleが提供するアイコンおよびシンボルのセットです。 WWDC 2019で初めて開発者に公開され、iOS 、macOS、watchOSで使用可能になりました。 SF Symbolsは、定期的にアップデートが行われ、新しいアイコンやシンボルの追加、パフォーマンスの改善が行われています。 SF Symbols 5とは SF Symbols 5では、5000を超えるアイコンおよびシンボルが提供されています。さらに、わずか数行のコードでアニメーションエフェクトを実現することができるようになりました。 「SF Symbolsの芸術的世界:限りない可能性を解き放つ」では、さまざまなアイコンやシンボル、そしてSF Symbols 5で追加されたアニメーション機能をフルに活用し、ダイナミックなSF Symbolsアート作品が紹介されています。 www.youtube.com 普段何気なく使用しているSF Symbols達が組み合わされていき、一つのSF Symbolsアート作品になる様は圧巻でした! また、SF Symbols 5には、様々なアニメーションエフェクトが用意されていると知ることができ、タイミーアプリ内でもSF Symbolsを活用していきたいと感じました。 今回ご紹介しきれなかった作品はGitHubで公開されているので、ぜひ一度ご覧ください! github.com ご登壇資料 www.docswell.com 特に気になったセッション(早川編) 今回、自分が気になったセッションは「 コード署名を楽しく乗り切る方法 」です。 このセッションではCertificate、Provisioning Profile、Application Identifierなど、アプリをリリースする上で必要なコード署名の要素を分かりやすくパズルに見立てて解説していました。 また、パズルに見立てることによってどこにエラーが起きているのかが分かりやすくなり解決するための要素の推測も容易になったかなと思います。 下の図で言うとProvisioning ProfileはCertificateとは問題なく結びついていますが、Application Identifierと正しく結びついていないためエラーが起きています。 解決するには「Provisioning Profileに結びついているApplication Identifierと一致するようにアプリ側のApplication Identifieを設定しなおす」か、「Provisioning Profileをアプリ側に設定されているApplication Identifierに合わせて作成しなおす」かになります。 各要素をパズルのピースに見立てることで、相互の結びつきが視覚的に解像度高く理解できました。 登壇者の Josh Holtz さんの発表内容も相まってコード署名を楽しく感じることができました笑 特に気になったセッション(みかみ編) 特に印象に残ったセッションは「マクロをテストする」です。今回のtry! Swiftでも注目を集めていた TCA を開発する、 Point-Free のStephenさんとBrandonさんによる発表です。 github.com 発表ざっくりまとめ マクロはSwift 5.9から導入されたコンパイル時にソースコードの一部を生成する機能です。主にボイラープレートを減らすことを目的に利用されます。iOSアプリ開発の世界ではSwiftUIのプレビューを簡潔に行う「#Preview」や新しいデータ永続化のフレームワークであるSwiftDataのモデル定義を簡略化する「@Modelマクロ」などの標準のマクロが数多く用意されています。 マクロは有益ではあるもののマクロによって生成されるコードが多ければ多いほどエラーが発生する可能性は高まります。特にマクロを実装する場合は生成されるコードも対象に、Swiftの文法のあらゆるエッジケースを考慮して多くのテストを行うことが望ましいです。 しかし、マクロのテストも多くの課題があります。例えばマクロで生成されたコードのエラーや警告がXcode上からわかりにくく、 Apple標準のマクロのテストヘルパーの文字比較の判定がシビアでフォーマットなどの本質的ではない部分でテストが落ちてしまうという問題があります。また、マクロの実装が変わった場合はテストを修正する必要がありメンテナンスも大変です。 そこでPoint-Freeが swift-macro-testing というテストライブラリを公開しています。swift-macro-testingは検証したいマクロのソースコードを assertMacro() に書き込むだけでどのように展開されるかを自動でテストコードに反映します。 感想 途中でライブデモがあったり、黒魔術的に生成されるテストコードを披露されたりとなんとなく会場も賑わっていた気がします。Androidにおいて自動生成を行うコードはたまに書くのですが、自動生成のコードをテストするというのは個人的に盲点で面白いなと思いました。 特に気になったセッション(三好編) 今回気になったセッションは、 平和に大規模なコードベースを移行する方法 です。 数あるセッションの中では、割と実用的ですぐに活用できるような内容でした。 セッション資料はこちら drive.google.com 破壊的変更を避ける方法 デフォルトパラメータを利用 メソッドを拡張するときに、パラメータを増やすとそれを利用する側すべての修正が必要になる デフォルトパラメータを利用することで、利用する側の変更なく機能拡張することができる protocol extensionを利用 プロトコルのメソッドを増やすと、それに準拠したclassやstructではそのメソッドを必ず実装する必要がある protocol extensionを利用し、デフォルトの実装を定義することで、利用する側は変更なく機能拡張することができる @availableの利用 命名変更も破壊的変更になるため Diagnosticのwarningを利用 enumの利用 caseが増えると、利用側でdefault実装がない場合変更が必要になる non-frozen enumだと、@unknown defaultの定義が必要なので、破壊的変更は避けられる しかし、non-frozen enumは開発者に提供されておらず利用できない enumのcaseそれぞれをstatic letで利用できるようにする Disfavoured Overload @_disfavoredOverloadを使う デフォルトパラメータを減らすなど 機能削減での破壊的変更を避ける目的で使えそう Finding Problem swift package diagnose-api-breaking-changes [ブランチ名] 上記コマンドで、指定したブランチの間で破壊的変更があるか教えてくれる いつ破壊的変更を行うのか 技術的負債とユーザーのイライラを天秤にかけた際に大きな偏りが生まれたとき @_disfavoredOverload等存在自体知らなかったので、とても勉強になりました。 来年の開催すると思うので、ぜひ皆さんも参加してみてください。 特に気になったセッション(岐部編) try! Swiftは4回目(2016,2018,2019,2024)の参加でした(2017年の記憶が曖昧なので、5回目かもしれない…)。 どのセッションも有意義でしたが、私は特に「Accessibility APIを使ってアプリケーションを拡張する」のセッションが非常に興味深く、サンプルアプリまで作りました。 1分にまとめたショート動画を用意したのでご覧ください。 時間の関係で動画中では詳細に触れていませんが、Accessibility APIを通して取得できる AXUIElement インスタンスには大きな可能性を感じました。このクラスのインスタンスには起動中の全アプリについての以下のようなウィンドウ情報が詰まっています。 アプリ名 ウィンドウのXY座標 ウィンドウサイズ 他のアプリのUIに自分のアプリが直接的に作用できるこの考え方は、Sandboxのcapabilityを取り除けるmacOSならではでとても面白いと感じました。 実際にユーティリティアプリ作る際は、以下のような手順で行いました。 Xcodeプロジェクト新規作成、macOSアプリを選択 まずはスライドにある設定を実施 capabilityからSandbox設定削除 ContentViewを開いて雑に実装 他ウィンドウの情報を埋める構造体と配列 他ウィンドウの情報を集めるメソッド 指定したウィンドウをアクティブにするメソッド ウィンドウの背景を透明にするView ホットキーを監視するメソッド これらを組み合わせて完成 以下のGitHubリポジトリで公開してあるので、ぜひ触ってみてください。 (あくまで検証用で作ったので粗は多いと思います…。PRもお待ちしております) github.com 最後に try!Swiftは世界中からiOSエンジニアが集まるイベントなので久しい友人に会えるのはもちろん、タイミーのエンジニアはフルリモートで働いているので普段WEBカメラ越しにしか話していない同僚とも対面で会話できて非常に楽しい期間でした。 この場を用意してくださった運営チームの皆さん、および会場でお話ししてくださった皆さんに心から感謝します。 上記で紹介したセッション以外にも非常に興味深いセッションが多くありました。 記事にある内容や、その他の内容についても、もしタイミーのエンジニアと話したいという方がいらっしゃればぜひお気軽にお話ししましょう! product-recruit.timee.co.jp
タイミーの矢尻、須貝、razです。 ソフトウェアテストに関する国内最大級のカンファレンス「JaSST (Japan Symposium on Software Testing) ‘24 Tokyo」が2024/03/14、15の2日間にわたって開催されました。 jasst.jp 登壇時の様子 今回は我らがGo AkazawaとYorimitsu Kobayashiも登壇!その応援も兼ねてQAコーチ、エンジニア、スクラムマスターの3名が参加。世界中で開催されるすべての技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度を利用しました。 productpr.timee.co.jp 本レポートでは、印象に残ったセッションの内容を中心に、2日間の会の様子をお伝えします。 噛みしめるほどに味わい深い「Making Quality Tangible」 今年の1月に入社したばかりの駆け出しQAコーチの矢尻です。 毎年楽しみにしているJaSST Tokyoに今年もオンライン視聴で参加しました。 視聴したすべてのセッションが示唆に富んだ学び多きものでしたが、中でもインパクトの大きかった Gojko Adzic 氏による基調講演「Tangible software quality」 の感想をお話します。 「Tangible software quality」を直訳すると、「具体的なソフトウェア品質」となります。 このセッションでは直接的にテストできないソフトウェア”品質”をプロダクトに”作り込む”ためのマインドセットやモデルが紹介されました。 セッションの最後に紹介された5つの「Making Quality Tangible(品質を具体化するためのガイドライン)」は、哲学的で難解ですが、噛みしめるほどに味わい深いものでしたので私なりに意訳して感想に代えさせていただきます。 MEASURE PRESENCE, not absence(意訳:不在ではなく存在を測定せよ) 欠陥や問題点ではなく、実現された価値に焦点を当てることの重要性を強調されました。ポジティブな側面や魅力を評価することが、価値や魅力を感じるための鍵であると感じました。 Describe multiple QUALITIES(意訳:複数の質を記述せよ) 内容に忠実な感想ではありませんが、例えば生活の質(QOL)のように健康・経済的安定・教育・職業・家族関係・文化的充足感など様々な指標で構成され、どれか一つが満たされていれば幸福というわけではないということに似ていると感じました。 ソフトウェアも同様に、使うひとが幸せであるための多様な構成要素を要求される水準で満たすことが重要と受け取りました。 Trade-offs are a PRODUCT DECISION(意訳:トレードオフは製品の意思決定の一環である) 誰もがt_wada氏の「質とスピード」を想起したのではと思っています。 もちろん「質とスピード」の間のトレードオフは解決可能と私も思っていますが、ここでは網羅的なテストでリスクをゼロに近づけることではなく、どの品質特性がどの程度重要なのか重み付けをして、重要なものからバランス良くリソースを配分するのが重要と受け取りました。(「要はバランス」ですね) Shape priorities with a MODEL(意訳:モデルを用いて優先度を形成せよ) 製品の意思決定の一環として生じるトレードオフを判断する基準として勘は通用しません。ここでシンプルで有用なモデルとして「有用性」「差別化」「飽和点」から成るQUPER Modelと「マズローの5段階欲求モデル」が紹介されていました。 QUPER model for better requirements Redefining software quality VISUALISE and ACT(視覚化して行動せよ) もうこれは字面通り「収集したメトリクスを根拠に行動せよ」ということかと思います。 (そういえば最近「見える化」って聞かなくなりましたね) まさにタイミーでも価値あるソフトウェアを最速でデリバリーするためにチームトポロジー型の組織戦略を採用しています。価値に着目している点で同じ方向性のセッションだと感じましたので、今回紹介されたモデルやメトリクスは折に触れてチームで紹介し試していけたらと考えています。 異業種の品質保証から得られた学び 自動テストが好きなバックエンドエンジニアの 須貝 です。 JaSSTは初参加(オンライン視聴)でして、弊社の赤澤と小林の登壇を応援しようというのがきっかけでした。 全体を通して一番印象に残ったのはトヨタ自動車の長尾洋平氏による「 自動車のソフトウェア品質に関する現場の試行錯誤 」です。 自動車を制御するソフトウェアは数千万から数億行のコードからなっており、まずその規模と複雑さに驚きました。また、テストコードの品質にも規格があり、その質を担保するためにミューテーション分析などを活用しているそうです。 一方で実機テストの制約の多さに苦労されているとのことでこれは自動車ならではの悩みだなと思いました。テストのアプローチとしてQAが要件定義段階から関与するいわゆるシフトレフトを実践されている点も非常に興味深かったです。 また他のセッションですと「 音楽の世界から学ぶ、ソフトウェア品質 」は、プロ演奏者を招いて音楽とソフトウェアという無形のプロダクトの質について探る野心的な試みでした。 私はソフトウェアエンジニアという立場ですが、日々の開発では自身でもテストを行っているため、大変学びの多いイベントでした。 「アジャイル」「スクラム」が多く出てきたことに驚き QAやテスト界隈がどんな感じなのか気になったので参加しましたスクラムマスターの raz です。 私もJaSSTに初参加(オンライン)でした。正直なところ、社内で参加希望者を募るまで、存在も知らなかったのですが、参加できてよかったです。 私も印象に残ったのは、トヨタ自動車の長尾洋平氏による「 自動車のソフトウェア品質に関する現場の試行錯誤 」なのですが、須貝さんが感想を書いてくださってるので割愛しておきます笑。 色々な発表を見させていただきましたが、全体的な感想として「アジャイル」や「スクラム」といったキーワードがたくさん出ていたのが驚きでした。ソフトウェアエンジニアがアジャイルなプロダクト開発に変化していった中で、QA組織やQAエンジニアがその変化へ適応していこうとしているように感じました。 その中でも「品質」について「 誰のなんのための品質なのか 」を考えているのが、とても良かったです。発表の中には「本当にその考えでいいのか?」という議論の余地はあったかもしれませんが、顧客中心に品質を議論する活動、それを継続するのは素晴らしいことだと思います。 弊社でも「顧客のための品質」について、もっと考えていければと思います。 おわりに 弊社は今回ゴールドスポンサーとして初めてJaSST Tokyoに協賛させていただきました。次回以降もなんらかの形で貢献して一緒にコミュニティを盛り上げていければと思います。 タイミーのQA、ソフトウェアテストについてもっと知りたいという方はぜひカジュアル面談でお話しましょう。 product-recruit.timee.co.jp
はじめに 課題感・背景 使用しているBIツールについて BIツールの使用ボリューム感について やったこと:概要 やったこと:詳細 referenced tableにテーブル名ではなくdbtモデル名が入るようにしたことについて 各種アウトプットの公開設定をmeta情報として付与する方針としたことについて tagを追加してexposureの検索性を向上させたこと exposureのnameにシートとダッシュボードのタイトルを反映する方針にしたこと 今後の発展 保守運用の設計 カラムレベルリネージュ ✖️ exposure おわりに We're Hiring!! はじめに こんにちは。okodooonです!! データ基盤を参照したアウトプットが社内に溢れかえっていませんか? 弊社は追いきれていないLookerStudioやConnectedSheetがめちゃくちゃ溢れかえっていました。 そんな折、yoshidaさんの以下の記事を拝読いたしまして、今回の実装に至った次第でございます。 LookerStudioの記事 ConnectedSheetの記事 www.yasuhisay.info www.yasuhisay.info 面識ないですがこの場を以て感謝の意を表させていただきます!ありがとうございます! 課題感・背景 使用しているBIツールについて 弊社ではBIツールを数種類利用して、BigQueryデータ基盤上のデータを活用しています。 以下がその一覧とざっくりとした役割です。 Looker : 社内の主要な分析プロセスをカバーするセマンティックレイヤーを提供 LookerStudio : アドホックなレポーティング、Lookerでカバーしきれていない指標を用いたダッシュボード構築 GoogleスプレッドシートのConnectedSheet : スプレッドシート上でビジネスメンバーが作業する際のデータソースとしての使われ方 Redash : 元々LookerStudio同様の使われ方をしていた。ガバナンス向上とSSoT実現のために廃止作業中 Looker経由のアウトプットであれば、ソースデータに変更が発生したり社内の指標出力ロジックに修正が発生した場合に、ディメンショナルモデリング層で吸収したりLookerのContentValidator機能などでガバナンスを効かせることができます。 しかしBIツール側に直接クエリを書く形となるLookerStudioとConnectedSheetを用いたアウトプットの保守とガバナンスが問題となっていました。 BIツールの使用ボリューム感について こんな感じのクエリで調査しています。 SELECT DISTINCT JSON_VALUE(protopayload_auditlog.metadataJson, " $.firstPartyAppMetadata.sheetsMetadata.docId " ) AS sheet_id, FROM `example-project.bq_usage_logs.cloudaudit_googleapis_com_data_access_*` WHERE protopayload_auditlog.serviceName = " bigquery.googleapis.com " AND JSON_VALUE(protopayload_auditlog.metadataJson, " $.firstPartyAppMetadata.sheetsMetadata.docId " ) IS NOT NULL SELECT DISTINCT label.value AS report_id, FROM `example-project`.`region-xx`.`INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION`, UNNEST(labels) AS label, WHERE label.key = " looker_studio_report_id " 過去半年にクエリが走ったConnectedSheetの数: 600個強 過去半年にクエリが走ったLookerStudioの数: 400個強 前述したロジックやソースシステム側の破壊的な変更への対応工数の観点以外にも、もう使われていないConnectedSheetに配信し続けている可能性などが考えられるため、まずはアウトプットを管理できる体制が必要であると考えました。 やったこと:概要 以下のような処理の流れを構築しました。 exposure登録情報を出力するviewをdbtで構成 以下の処理をweeklyで実行 viewの結果を取得してexposureのyaml形式に変換 アウトプット単位でexposureのyamlファイルを作成 未登録と変更があったexposureを登録するpull requestを作成 参考にしたブログから、弊社の運用に合わせて変更した点は以下です。 exposure単位でyamlファイルを作成する方針に変更しました referenced tableにテーブル名ではなくdbtモデル名が入るようにしました 各種アウトプットの公開設定をmeta情報として付与する方針としました tagを追加してexposureの検索性を向上させました exposureのnameにシートとダッシュボードのタイトルを反映する方針にしました 今回の実装によって以下のような形式のexposure用のyamlファイルが自動生成されます。 version : 2 exposures : - name : {{ ConnectedSheetタイトル }} _{{ConnectedSheetId}} label : {{ ConnectedSheetId }} type : dashboard tags : - shared_externally - spreadsheet url : https://docs.google.com/spreadsheets/d/{{ConnectedSheetId}} owner : name : test@example.com email : test@example.com depends_on : - ref('hogehoge_model') - ref('foo_bar_model') - ref('chomechome_model') meta : visibility : shared_externally やったこと:詳細 説明があるとわかりやすそうな部分の詳細を記載していきたいと思います。 referenced tableにテーブル名ではなくdbtモデル名が入るようにしたことについて 弊社はdbtモデル名とBigQuery上のテーブル名が一致しないため、INFORMATION_SCHEMAやaudit_logから取得したテーブル名をref関数化してもリネージュを作成できません。 そのため、dbtモデル名とBigQuery上の対応関係を取得するためにdbt-elementary実行時に生成される dbt_models テーブルを活用しました。 このテーブルは カラム名 内容 dbt_models.name dbtモデル名 dbt_models.alias BQテーブル名 dbt_models.schema_name BQデータセット名 dbt_models.database_name BQプロジェクト名 このような情報を持つカラム群を保持しています。 このテーブルを活用することでINFORMATION_SCHEMAが保持するBQテーブル名をdbtモデル名に変換してref指定することができています。 各種アウトプットの公開設定をmeta情報として付与する方針としたことについて https://support.google.com/a/answer/9079364?hl=ja google workspaceのactivityログを使うことで、LookerStudio,SpreadSheetの公開設定とタイトルを取得することができるので、それらを取得しています。 SELECT data_studio.asset_id AS report_id, data_studio.asset_name AS report_name, data_studio.visibility AS visibility FROM example-project.google_workspace.activity WHERE activity.data_studio.asset_type = 'REPORT' AND activity.event_name = 'VIEW' SELECT drive.doc_title AS sheet_title, drive.doc_id AS sheet_id, drive.visibility FROM `example-project.google_workspace.activity` WHERE drive.doc_type = 'spreadsheet' tagを追加してexposureの検索性を向上させたこと dbt exposureはmeta, owner, typeなどの情報を使って、dbt lsコマンドなどでアウトプットを一覧することができません dbt ls --resource-type exposure --type dashboard --owner example@example.com みたいなことがしたいのですができないです。 そのため、exposureに対して適切なtagを付与することで絞り込みができるようにしました! 今回は公開設定,アウトプット種別の二つをtagとして持たせました。 これによって 「xxx_modelを参照しているshared_externally設定にしているスプレッドシート一覧を出したい」という要望に対して dbt ls --select xxx_model+,tag:shared_externally,tag:spreadsheet --resource-type exposure このようなコマンドで出力ができるようになります exposureのnameにシートとダッシュボードのタイトルを反映する方針にしたこと Add Exposures to your DAG | dbt Developer Hub こちら公式Docにexposureのnameに指定するのはスネークケースにしてくださいという記載がありますが、なんとスネークケースにしなくても日本語名でも通ります!(名前をユニークにする必要はあります) そしてexposure.nameがリネージュ上で表示される名前なので、データリネージュの可視性を高めるためにLookerStudioとコネクテッドシートのタイトルをnameに含む形で設定している状態です。 LookerStudioID, SpreadSheetIDだけをnameにすると、このようにデータリネージュ上でどのアウトプットのexposureかぱっと見判断がつかないのですが {{タイトル}}_{{ID}} の形式にすることでデータリネージュ上の可視性を確保した形です。 今後の発展 保守運用の設計 アウトプットが全件自動で管理されるようにはなったことで、「ソースシステムに影響が起きた場合」や「算出ロジックに変更が生じた場合」の影響範囲は迅速に把握できるようになりました。 しかし使われていないことがわかったアウトプットに対してどのようにアクションしていくのか、フローが組めていない状態です。 管理ができるようになった上でどのように運用改善に繋げるのか。どのように削除やdeprecatedにしていくのか。あたりのフローはしっかりと組んで、ユーザーの目に触れるアウトプットの品質の最大化に努めていきたいです。 カラムレベルリネージュ ✖️ exposure dbt cloud enterpriseではカラムレベルのリネージュがexplore上で確認できるようになりました。 docs.getdbt.com 重要なアウトプットはBIツール側にクエリを書くのでなく、dbt側にそのアウトプット専用のマートを作成することで、カラムレベルでの影響範囲調査が可能となるのではと考えています。 before after この図でいうbeforeからafterの構成に変えることでマートまではdbtで管理されるようになるため、dbt exploreのcolumn level lineageで可視化することで、カラムレベルでのアウトプットへの影響範囲を確認可能です。 こうすることで、「このテーブルに何かしら変更を加えたら最大でどのくらいの数のアウトプットに影響があるんだろう」から「このテーブルのこのカラムを消したらどのアウトプットに影響があるんだろう」まで影響調査の解像度を上げることができます。 こういった理由から、アウトプット専用マート作成の取り組みを始められたらなと思っております。 (column level lineageは現状dbt exploreで見ることができるだけですが、もうちょっと使いやすくなって欲しいです) おわりに yoshidaさんの記事を参考に少しだけカスタマイズしただけで、課題となっていたアウトプット管理の問題を解決することができました! 運用面などまだまだ磨き込んでいきたい部分は多分にありますが、この実装を通して社内ユーザーのデータ活用体験の最大化に繋げていきたいです! アウトプットがいっぱい登録されました。(オレンジ色がexposure) We're Hiring!! タイミーではデータ基盤を一緒に開発してくれる仲間を募集しています! お力をお貸しいただける方いらっしゃいましたらご応募お待ちしております! product-recruit.timee.co.jp
こんにちは!タイミーのデータアナリストの@ yuya です。 2020年に スマホ ゲームを運用する企業へ新卒入社をし、イベントプランナー兼データアナリストとして活動。2社目に ECサイト を運用する企業でデータアナリストとして従事した後、2023年3月に3社目となるタイミーへ入社しました。入社からちょうど1年が経ったので、タイミーでのデータアナリストとしての働き方をこれまで自分が所属した企業と比較して、どうだったかについて振り返りたいと思います。 タイミーでの役割 まずは、私がタイミーでどのような役割を担っているデータアナリストなのかを記載したいと思います。 タイミーのデータアナリストチームは、大きく以下の3つの役割に分かれております。 プロダクトアナリティクス:プロダクトの機能開発に関わる分析 マーケティング アナリティクス: マーケティング に関わる分析 ビジネスアナリティクス:経営・事業活動に関わる分析 私は、ビジネスアナリティクスに所属しており、営業周りのデータ分析や店舗周りのデータ分析を主に行っております。 タイミーでの1年を振り返る オンボーディング期 入社直後のオンボーディング期は、社内のデータ構造を理解しながら、データ抽出を行う依頼をこなしておりました。 タイミーでは、前述した3領域に関わらず、全社的にデータ抽出や簡単な分析をデータアナリストに依頼できるフローが存在しており、そこの依頼を担当することで、アプリ関連のデータ、 マーケティング 関連のデータ、営業関連のデータなど、タイミー内に存在する様々なデータ構造を理解し、使いこなせるようになるよう努めていました。 個人的に、これまで営業が存在する企業に所属したことがなかったため、営業関連のデータに触れることが新鮮で、分析領域としても1つ広がっていく感覚があり、非常に面白みを感じていました。 また、多くのデータが分析しやすいように整備されており、クエリを書くのが楽だったのも印象的でした。 ビジネスアナリティクス領域に配属 オンボーディング期が終わると、ビジネスアナリティクス領域に配属となりました。 私が配属された直後は、すでに社内での連携部署が定まっており、連携部署との間で分析テーマを決めて分析に取り組んでおりました。 当初取り組んでいたテーマとしては、「店舗の 流入 経路別のLTVの分析」や「新規導入に至るまでのファネル分析」、「CPの効果検証」などのように、課題の特定や戦略に関わる部分の分析から施策の効果検証まで幅広く様々な分析を行っておりました。 初めて営業関連の分析に着手する中で一番苦戦したのが、「どのデータが使えるのか?」を明確にするところでした。 前職と前々職では、アプリや マーケティング のデータを分析しており、基本的に自動でデータ収集されている状況でした。しかし、営業関連のデータは、営業の方が手動でデータを入力しないといけないため、たとえデータとしてカラムが存在していたとしても、データを入力している人としていない人が存在していたり、チームによって若干運用方法が違っていたりしていたため、現場への確認が必要でした。 今あるデータからどんな インパク トが出せそうかを考えるのも大事ですが、そもそもどのようなデータをきちんと収集していくと良さそうなのか、それをどうやったらきちんと収集できるようになるのかを考えていくのも重要そうだなという気づきを得ました。 営業組織が変革し、連携部署を再検討する ビジネスアナリティクス配属から約半年後、営業組織が変革されるイベントが発生しました。 これを機に、改めて「データアナリストとして、どのような動き方をすると価値を最大限発揮できるのか?」を考えていくことになります。 こちらについて、まだ明確な結論は出ていないものの、現状の営業組織の解像度を上げる(どこでどのような人が関わり、どのように意思決定が行われ、どのように影響していくのかなどを明確にする)ことで、データアナリストとして インパク トを与えていける動きができそうかの仮説を一定立てられるところまでは来たかなと思っております。 これまで所属していた企業(チーム)が、20名程度と100名程度であったため、特に意識しなくてもどこで誰が何をしているか理解できていたのですが、タイミーのように組織も急成長を遂げ、規模も1,000人を超えてくるような大きな組織になってくると、きちんと現場の状況をキャッチアップしにいく動きをすることが重要なのだなと改めて気付かされました。 最後に これまで、時系列的にどのようなことを行っていたのかを簡単に紹介してきました。 タイミーは、現在サービスも組織も急成長中であり、環境が目まぐるしく変わっていっており、都度都度その変化に適応していく必要があります。そのため、チームとしても明確な型のようなものが存在しているわけではなく、常に「どのように動くことが一番 インパク トが出せるのか?」を考え、状況に合わせて柔軟に動き方を変えていく必要があるなと感じています。 これまで所属した企業では、良くも悪くも、データアナリストとしての動き方がすでに固まっており、教えられた動き方をするだけで、自然と インパク トも出せるような環境でした。そのため、組織として自分がどのように振る舞うことが一番 インパク トが出せるのかを考える機会があまりありませんでしたが、タイミーでは、日々そのようなことを考えるため、視野を広げる良い機会になったかなと思っております。 組織が急拡大する中で、カオスなことも多いですが、これまでにない経験から得られる学びや気付きが多く、タイミーに転職して良かったなと感じております。 We’re Hiring! 私たちは、ともに働くメンバーを募集しています!! データアナリストのポジション カジュアル面談 も行っていますので、少しでも興味がありましたら、気軽にご連絡ください。
イベント概要 2023年12月5日に「Next Year Con for SRE〜来年の登壇を応援する勉強会〜」と題してSREに関するトピックでタイミー、ココナラ、ビットキー、マジックモーメントの4社合同で勉強会を開催しました。 その中でタイミーバックエンドエンジニアの岡野さん( @Juju_62q )の講演をイベントレポートにまとめてお届けします。 チーム分割においていかれたアラートをチームで責任を持てる形に再設計した 自己紹介&想定聴衆 2020年にタイミーに入社し、現在では3年半ほどエンジニアをしている岡野と申します。 主にストリームアラインドチームの機能開発を担当しており、その一方でサイトリライアビリティエンジニアリングも行っています。 想定聴衆 「よくあるアラート」に困っているエンジニア 組織分割を考えているEMやCTO EnablingをやっていきたいSREs 今日お話しないこと どのようなアラートを設定すべきなのか アラートから繋がるオンコール対応周辺の話 アラートとFBサイクルとチーム 私が最も優れていると考えるアラート(右の図)は、問題が発生したら、エンジニアが問題を解決すると宣言し、リカバーするアラートです。理想的には、問題が自動的に解決することが望ましいですが、今回の話の範囲では、アラートの責務を超えていると捉え、理想的なアラートの形をこのように考えています。 次によくあるアラート(左の図)は、CPU使用率がN%を超えると、エンジニアが介入せずとも時間と共に回復したり、500エラーがy回を超えると何もせずとも回復するようなアラートです。このようなアラートは、時間が経過すると自然に解決し、次第に無視されがちです。 本来アラートはアクションを要求するための通知であるべきであり、アクションなしにアラートが鳴ることは無意味です。実際にタイミーにも、このような無駄なアラートが長期間存在していました。 現状、完全な解決には至っていませんが、タイミーがアラートを少しずつ改善した話を共有していきます。 タイミーではどのようにして「よくあるアラート」ができたのか 前提条件 1. 開発と運用を同じチームでやっていること タイミーでは、CTOが開発と運用を一つのチームで行うことを重視しています。CTOが好んでいるチームトポロジーの書籍では、「運用は開発への最大のフィードバック源である」と述べられており、私たちの組織でもこれを大切にしています。 2. エンジニアはアラートがなっていることを好ましく思っていないこと エンジニアはアラートが鳴る状況を好ましく思っていません。行動を起こすかどうかは別として、アラートが鳴っていること自体は好まれていませんでした。 3. エンジニアは機能開発以外にある程度の時間が使えること タイミーのエンジニアは、10%から20%の時間を技術改善に充てることができます。実際には、少なくとも10%の時間をこれに割り当てることが求められています。 2〜3年前、我々のチームは以下のような横割りの構造でした。 バックエンドチーム Webフロントエンドチーム モバイルチーム これらのチーム間では、バックエンドチームがアラートの設定を行い、障害経験を基にアラートシステムが構築されました。この時期には、ユーザー数も少なく、アラート対応の難易度も低めでした。赤く表示されるアラートに対しては、チーム文化として積極的に対応していました。 しかし、この横割り組織では、一つのチームだけで機能を完全に提供することが難しく、これが課題となりました。そのため、職能を横断する縦割りの組織構造への移行を進めました。この新しい形では、モバイルやWebフロントエンドなど、異なる専門分野のメンバーが同一チームに所属するようになりました。 ただし、この組織変更の際に、アラートシステムの見直しは行われず、バックエンドエンジニアが引き続きアラートの責任を担うことになりました。 アラートが鳴った際の反応はどうだったかというと、以下のような反応が一般的でした。 Aチーム「アラート鳴ってるけど、よくわからんな」 Bチーム「アラート鳴ってるけど、うちのチームとは関係無さそう」 チーム間で分断されていると、特定の機能についてどのチームが対応すべきかの判断が難しくなります。特に、人員が増加するにつれて、過去の経緯も失われ、このような問題は増えていきます。 いつも鳴ってるし今日も大丈夫だろう 『いつも鳴ってるし、今日も大丈夫だろう』という感覚が常態化すると、アラートが頻繁に鳴るようになります。アラートが放置され、対応が行われないため、アラートの数は増加の一途をたどります。 改善したいけどハードルが高そう 仮に意欲的なエンジニアが現れても、「何とかしたいが、どう変えればいいかわからない」という状況に陥りがちです。Aチームの同僚は協力的ですが、Bチームは相対的に距離があるため、意見を述べるのが難しいと感じることがあります。同じ会社に属していても、日常的に顔を合わせていない人に対し、合意を得る必要があるかもしれないという懸念が生じます。 なぜこのようなことが起こるのか なぜこのような状況が発生したのか、その原因を考察します。 アラートの作成は元々、バックエンドチームが責任を持って設定していました。当初、アラートに対するフィードバックはバックエンドチームに集中しており、このチームだけでアラートの削除や修正が行われていました。しかし縦割り組織への移行後、アラートに関するフィードバックは複数のチームに分散し、単一のチームだけでの削除や修正が難しくなりました。アラートに対する対応が不明確になり、長期間勤務している経験豊富なメンバーに相談することや、アラートに関する変更の承認を得るまでのプロセスが必要になることもありました。このように、フィードバックが機能しなくなった結果、アラートの数は増加し、特に新入社員にとっては理解しづらいものとなりました。この状況が、「よくあるアラート」の誕生に繋がったのです。 「よくあるアラート」を改善するためにしたこと 結論を述べると Aチーム・Bチームそれぞれにフィードバックと意思決定権を与えました。 具体的な行動 各チームで対応の必要があると思われるアラートを選んでもらう アラートに対してチームメンションをつける アラートはメンションのある単一チームで変更していいと周知する アラート対応に関する振り返りを実施 各チームで対応の必要があると思われるアラートを選んでもらう すべての問題を即座に解決するのは難しいため、Slackに「問題なし」または「問題あり、オンコール対応が必要」というコメントを残すことを最低限行うことにしました。このとき、多くのアラートのうち、選ばれなかったアラートは一旦すべて削除しました。 アラートに対してチームメンションをつける 次に、アラートに対してチームメンションをつけることにしました。以前はアラートにメンションがなく、全てのチャンネル通知をオンにする運用でしたが、これではどのチームが対応すべきか不明確でした。そこで、アラートにメンションを付与し、「このメンションのチームがオーナーです」と伝えるようにしました。 メンションのある単一チームで変更していいと周知する 次に、バックエンドのアラートに関しては、バックエンドチーム全体の許可がなければ変更できないと考えられていました。しかし、メンションのある単一チームでの意思決定による変更を推進しました。これにより、各チームは素早く意見を反映できるようになりました。 アラート対応に関する振り返りを実施 最後に、アラート対応に関する振り返りを実施しました。最初の改善はできるだけサポートするため、メンション付きのアラート対応について1ヶ月後に第1回の振り返りを各チームで行いました。これは、必要に応じて2回、3回と続けました。この流れで、チーム内での改善が少なくとも1回行われるところまで改善できました。 今、どのような変化があったのか 現在、アラートシステムにおいて以下のような変化が生じています。 アラートに反応する人やチームの増加 アラートに反応する人数やチームが明確に増えました。 アラートの定期的な変更や見直し アラートに対応しないと自分たちが困難な状況に陥るため、変更や見直しを定期的に行うようになりました。 Runbookの整備 チームごとにRunbookが整備され、アラート対応のプロセスが民主化されています。この分野にはまだ改善の余地があると感じていますが、良い変化が見られていると思います。 これらの変化により、「よくあるアラート」から徐々に脱出していると感じています。ただし、不要なアラートが多いことや、復旧の自動化がまだ十分ではないことは、今後の大きな改善ポイントです。 まとめ アラートは組織構造とFBを受ける人が不一致の場合に機能しなくなっていく アラートは単一チームで変更の意思決定ができないと硬直化する 組織が変わった際に、アラートの組織に合わせて変更するのが大切 最後に、アラートシステムのまとめです。アラートは、チームの構造とフィードバックが不一致になると、効果を失ってしまう可能性があります。フィードバックを受ける人々が明確でない場合、アラートの機能性が低下する傾向があります。またアラートに関しては、「単純接触効果」のとおり、日常的に顔を合わせる人々に対して意見を伝えやすいことが多いです。そのため、単一のチームで意思決定ができない場合、アラートシステムは硬直化しやすいと思われます。 結論、組織が変化した際には、アラートシステムの構造も組織の形態に合わせて変更することが重要です。 その他の方の発表も気になる方はこちら! www.youtube.com 少しでも興味を持っていただいた方は是非こちらからカジュアルにお話しましょう!
はじめに こんにちは、タイミーでバックエンドエンジニアをしている 新谷 、 須貝 、 難波 です。 2月10日に 広島国際会議場 で YAPC::Hiroshima 2024 が開催されました。タイミーはGold Sponsorとしてブース出展をしており、エンジニアが3名とDevEnable室が3名の総勢6名で参加させていただきました。 どのセッションも興味深かったのですが、この記事では我々が拝見したセッションのうち特に印象に残ったものをいくつかピックアップしてご紹介します。 なお、タイミーには世界中で開催されている全ての技術カンファレンスに無制限で参加できる「Kaigi Pass」という制度があり、エンジニアはこれを使って参加しております。詳しくは下記のリンクをご覧ください。 productpr.timee.co.jp 経営・意思・エンジニアリング speakerdeck.com 普段我々が行なっているソフトウェア開発の延長線上に CTO の仕事があるよ、という発表でした。経営者が物事をどう捉えているのかを垣間見ることができ、個人的にはベスト トーク でした。 ソフトウェア設計と組織設計が相似的な アーキテクチャ であるということは コンウェイ の法則などもあることから直感的に理解できましたが、事業設計とも相似的な アーキテクチャ であるという話はまだピンときていないのでまたどこかのタイミングでお伺いしたいと思っています。 また、意思が重要という話はプロジェクトを成功するためには強い意思を持つ推進者が必要不可欠という点で共感していました。ただ、プロジェクトが短期間で終わるものであれば良いのですが、ある程度期間のかかる類のものは個人の意思では難しいこともあるかと思っていて、そういったものはどう対処しているんだろうとも気になりました。 短期的成果の重力に負けないよう、これからのプロダクト開発を行なっていきたいと思います。 (新谷) 関数型プログラミング と型システムのメンタルモデル speakerdeck.com コンピュータ アーキテクチャ に近い手続き型プログラミングから 関数型プログラミング へメンタルモデルを変えていこう、という発表でした。私は普段 Ruby on Rails でアプリケーション開発をしていて 関数型プログラミング とは距離があるのでとても興味深く聞かせていただきました。 オニオン アーキテクチャ は DI ができるとかモックが可能とかが重要なのではなく、 手続き型言語 の考えに引き摺られがちな I/O の部分を業務ロジックから切り離し、業務ロジックに対して別の パラダイム を適用できるようにするのが本質という話を聞き、なるほどと勉強になりました。 一方、 関数型プログラミング が Web アプリケーションのバックエンドに本当に適用できるのかはまだイメージが湧いていないのが正直なところではあります。質疑応答で質問をさせていただいて RDB の書き込みに相当する I/O の部分は Repository 層に閉じ込めるという話は納得したのですが、Web アプリケーションは本質的に並行処理だと思っていて、リク エス トを処理している最中に状態が書き換わることをどうやって純粋な関数で表現するのかが気になっています。 懇親会で確定申告の話と一緒に質問しようと思っていたのですが残念でした… 「スマンな!確定申告の話はまた今度!」 と、便の都合で先にかえるnaoya氏 #yapcjapan pic.twitter.com/drogfb5b5Q — 941 (@941) 2024年2月10日 (新谷) 変更容易性と理解容易性を支える自動テスト speakerdeck.com 自動テストの目的は 信頼性の高い実行結果に 短い時間で到達する状態を保つことで、 開発者に根拠ある自信を与え、 ソフトウェアの成長を持続可能にすること という結論からスタートし、その結論に向かって一つずつ解説していく内容でした。 この目的は極限まで削れば「ソフトウェアの成長を持続可能にすること」だと私は思います。これだけだと飛躍があるので一つずつ順を追っていくと、まずソフトウェアの持続可能な成長には変更容易性(変更しやすい)と理解容易性(わかりやすい)が必要です(ないとツラい)。そして変更による既存機能への影響を知る手段のひとつに自動テストがあります。また、自動テストには既存コードの理解を助ける役割もあります。もちろんただ自動テストがあればよいわけではなく、 良い自動テスト が必要です。 ではどうすれば良い自動テストを書けるのかという話になるわけですが、ここで私が思い出したのは「 単体テスト の考え方/使い方」(Vladimir Khorikov 著、須田智之 訳)です。 この本の「4.1 良い 単体テスト を構成する4本の柱」で以下の4つの要素が挙げられています。 退行(regression)に対する保護 リファクタリング への耐性 迅速なフィードバック 保守のしやすさ 目的で挙げられた「信頼性の高さ」は「退行に対する保護」( 偽陰性 からプロダクション・コードを守るもの)と「 リファクタリング への耐性」( 偽陽性 の数を最小限に抑えるもの)であり、「短い時間で到達する状態」は「迅速なフィードバック」に相当します。そして「信頼性の高い実行結果に短い時間で到達する状態を 保つ 」ためには「保守のしやすさ」が欠かせません。つまり冒頭の二行に良いテストの条件がすべて凝縮されていたのです。 発表にあった「実行結果は情報」という指摘には良いフィードバックの重要性も感じました。また、 Google のテストサイズの話なども非常に勉強になりました。今回のセッションをきっかけに改めて自動テストの目的に立ち返り、自分たちがより根拠のある自信を持ってコードを書けるようにしていきたいと強く感じています。 最後に余談ですが、発表の中で気になったことを懇親会でtwadaさんご本人に直接質問できたのはオフラインイベントの醍醐味だなとしみじみ感じました。 (須貝) 非同期な開発体制を支えるドキュメント文化 speakerdeck.com 時差のあるメンバー同士でも適切にコミュニケーションを行うために Launchable, inc.で実際に行われている ドキュメンテーション の事例を紹介頂く内容でした。 発表の中で特に印象に残ったものを3つほど挙げさせていただきます。 フィードバックの平等性 検索性の意識 ドキュメントの型化 まず「フィードバックの平等性」についてです。組織にいるメンバーは多様であり聞いた話について素早く考えて話すことが得意な人もいればじっくり考えたい人もいます。また組織内 公用語 として使われている言語が 第一言語 でない人もいます。そういった場合に同期的な MTG でやり取りすると議題に対するフィードバックを行う人が偏る傾向があり、またフィードバックの観点も偏りがちです。非同期にフィードバックをもらうようにすることでこの課題の対策としているというのは良い視点だと思いました。なお、タイミーでも参加者が多い一部の MTG では議事録のドキュメントにフィードバックの欄があり、また MTG の録画を行うことで非同期にフィードバックを行いやすい運用をしていたりします。 次に「検索性の意識」についてです。ドキュメントをしっかり残すことは非同期か否かに関わらず非常に良い文化であり実践している組織も多いと思いますが、ドキュメントが増えると必然的に起きるのが検索性の悪化です。タイミーでは ドキュメンテーション にNotionを使用しているのですが、閲覧したいドキュメントがなかなか見つからなかったり、見つかったドキュメントが実は古いものだったといったことはどうしても発生します。その対策としてまず部門ごとにConfluenceのspaceを分けているとのことでした。他部門の情報が簡単に閲覧できるという透明性は重要ではあるものの、それは権限管理をしっかりやれば解決できることです。また積極的に アーカイブ (≠ 削除)を行うことでデフォルトの検索設定では検索にヒットしないようにするという話もあり、これはその通りだと思う一方でそれを組織文化とするのは一朝一夕では無いなと感じます。 最後に「ドキュメントの型化」についてです。ドキュメントが一定のフォーマットに準じて作られていれば書き手にとっては書くべき情報が漏れにくいですし、読み手にとっても慣れれば慣れるほど要点を理解しやすくなります。また適切なフィードバックを受けるための 30/60/90% framework for feedback についても勉強になりました。これはドキュメントのフェーズに対して適切なフィードバックを行おうというもので、普段から意識してはいたもののそういった名前が付いていたことは知らなかったので今後のコミュニケーションの際に使おうと思います。そして関連資料のドキュメントへの記載です。ドキュメントを書く際は何かしら参考にした別のドキュメントというものがある場合が多いですし、書き手にとっては自明でも読み手にとってはそうでない場合も多いです。こういった資料のリンクを書き手だけでなく、読み手も積極的にドキュメントに残していこうというのは今後より意識していきたいです。 (難波) 杜甫 々さんのキーノート あの日あの場にいたことを自慢し続けようと思います。 (須貝) おわりに YAPC は長く続いているイベントですが、今回エンジニアで参加したメンバーは初参加だったり9年ぶりの参加という感じでした。それでも YAPC の和やかな雰囲気と Perl に関係するテーマもそうでないものも受け入れている包容力で皆大変楽しむことができ、また勉強になったカンファレンスでした。 来年以降もまたスポンサーや参加ができればと思います。 最後にランチとして配られた広島名物のあなごめしの画像を貼って終わりとします。
イベント概要 2023年11月15日に「GENBA #1 〜RubyとRails開発の現場〜」と題してRuby/Railsでの開発に関するトピックでタイミーとエンペイ社合同で勉強会を開催しました。 その中でタイミーバックエンドエンジニアのpokohideさん( @pokohide )の発表「Railsアプリで秘匿情報を環境変数からCredentialsに移行した話」をイベントレポート形式でお届けします。 登壇者紹介 Credentialsとは Credentials は、Rails 5.2から追加された秘匿情報を管理するための仕組み※1 で、Rails 6から複数の環境をサポート※2 しています。 【主な登場人物】 暗号化ファイル: config/credentials/ .yml.enc 復号用の伴: ENV[”RAILS_MASTER_KEY”] or config/credentials/ .key 【セキュアな構成管理】 Railsアプリ起動時に Rails.env に対応する暗号化ファイルと鍵を参照し復号する 復号化が完了すると Rails.application.credentials 経由で取得可能になる 【暗号化と参照方法】 YAML形式 のファイルを暗号化(YAMLの構文に依存) ⇆ 復号 復号化された後は ActiveSupport::OrderedOptions を介してアクセス可能 fetch や dig が使える ▲Credentialsの例 ※1Add credentials using a generic EncryptedConfiguration class #30067 ※2Add support for multi environment credentials. #33521 Credentialsへの移行目的 Credentialsへの移行は、組織内での秘匿情報管理の責任を明確化し、デプロイプロセスを効率化することを目的としています。 手間の削減 以前はECSのタスク定義に環境変数としてパラメータストアのSecureStringを利用していました。秘匿情報を追加する際にパラメータストアに登録し、ECSタスク定義とアプリケーションコードの両方を変更する必要があり、手間がかかっていました。 責任境界の曖昧さ AWSリソースの管理はインフラチームが主導していましたが、その結果、責任境界が曖昧になることがありました。 ⇒ Credentials導入によって、秘匿情報の管理に関する責任の所在が明確になり、責任境界が明確化されました。 デプロイの難易度 複数の場所での操作が必要だったため、デプロイが容易ではありませんでした。 ⇒ Credentials導入によって、アプリケーションコードを変更することで秘匿情報を追加・参照できるようになるため、デプロイも容易になりました。 レビューの困難さ 独自の対話型CLIを使用してパラメータストアを操作していたため、プロセスのレビューが困難でした。 セキュリティの向上 ⇒ Credentials導入の副産物として、セキュリティ向上が挙げられます。RAILS_MASTER_KEYのみを管理することでパラメータストアの操作権限を削減でき、全体的なセキュリティレベルが向上しました。 Credentialsの安全性 Credentialsの安全性は、主に使用される暗号化アルゴリズムとマスターキーの管理方法に依存します。2023年時点で、AES-256-GCM暗号化アルゴリズムを用いた暗号化は、最も安全だといわれています。 しかし、最も重要なのはマスターキーの管理です。マスターキーが流出すれば、暗号化された情報が容易に解読されてしまう可能性があります。そのため、マスターキーの安全な保管とアクセス管理は非常に重要です。 管理方法については、ビジネスの環境やリスクに応じて慎重に検討し、適切なセキュリティ対策を講じる必要があります。 Credentials 移行の手順 移行の手順は、とてもシンプルです。 何を移行するか決める 移行対象の秘匿情報を全てCredentialsに追加する 少しずつ Rails.application.credentials に移行する 1. 何を移行するか決める まず、何をCredentialsに移行するかを決定します。アプリケーションの構造を分析し、環境変数をリストアップします。秘匿情報には、環境変数だけでなく、証明書、秘密鍵、Google Cloudの認証用JSONキーなどが含まれる可能性があります。 また、秘匿情報が本当にCredentialsへの移行が必要かを考えましょう。環境ごとの固有の設定であれば config_for を使用することで解決できるかも知れません。コンテナ化された環境やデータロックサービスのような動的に注入する必要がある情報や、頻繁に更新される情報は、Credentialsへの移行が適切かどうかを慎重に検討します。 2. 移行対象の秘匿情報を全てCredentialsに追加する 秘匿情報を一括でCredentialsに追加することをおすすめします。その理由は、暗号化ファイルのレビューが難しいためです。Credentialsへの移行前もレビューは難しい状況でしたが、暗号化ファイルを扱う現在も同様です。そのため、秘匿情報をまとめて移行し、Railsコンソールでリリース前に値が正しく一致しているか確認することで、プロセスがよりスムーズになります。 3. 少しずつ Rails.application.credentials に移行する Rails.application.credentials への移行は段階的に行います。このプロセスは、多くのプルリクの作成と対応を伴い、障害が発生する可能性もあります。実際に起きた一例として、全角スペースと半角スペースを間違えて登録し、参照時にエラーが発生しました。秘匿情報のファイルレビューは通常、Syntax Highlightが効かない素のVimなどで行われるため、特に細心の注意が必要です。 タイミーでは技術改善のために割り当てられる時間が全体の約20%で、この時間を利用してCredentialsへの移行作業を行いました。全体としては約5ヶ月の期間を要しました。もし環境が異なれば、移行にかかる時間は1ヶ月程度に短縮可能かもしれません。移行の過程では、ステージング環境と本番環境で同じ秘匿情報を使用していたこともあり、そのような点にも対応しながら作業を進めました。 Credentials移行時のTips 1. config.require_master_key 設定を有効にする Railsアプリケーションを起動する際には、Credentialsのマスターキーが必須です。マスターキーがないとアプリの起動に失敗する設定を有効にしておくと良いでしょう。 2. エディタの指定 暗号化ファイルの編集にはエディタの指定が必須なので用意(Dockerを利用している場合はemacsなどでもOK) 3. エスケープ文字の扱い 秘匿情報にエスケープ文字が含まれている場合は、ダブルクォーテーションで囲むことが推奨されます。暗号化ファイルがYAML形式に依存しているため、YAMLの構文規則に従う必要があります。 4. 改行の利用方法 秘匿情報に改行を含めたい場合は、パイプなどのYAMLの構文を利用します。 5. 外部サービスとの認証方法を変更する 外部サービスとの認証方法も変更しました。具体的には、以前は秘匿情報をファイルから読み込んでいた認証方法を、Credentialsで管理する形式に変更しました。 6. バイナリデータの取り扱い YAML形式はテキストベースのデータ形式であり、バイナリデータの直接的な扱いには向いていません。特に、証明書などのバイナリデータをCredentialsで管理する際は、事前にBase64でエンコードする必要があります。アプリケーションでは、このエンコードされたデータを取得し、適切にデコードして使用します。データの識別を容易にするために、YAMLファイル内でエンコードされた値には base64_encoded というプレフィックスを付けると便利です。 7. 秘匿値をコンソールで非表示にする Railsコンソールを使用する際、デフォルト設定では秘匿値が表示されてしまうことがあります。(Rails 7.1からは、この秘匿値を非表示にする機能が標準で実装されています。)この変更によって、Railsコンソールから秘匿情報が誤って露出するリスクを軽減できます。 8. SECRET_KEY_BASEを Credentials に移行 Secretsは Rails 7.1から明示的に非推奨化 されたため、SECRET_KEY_BASEを Credentials に移行しました。各環境の credentials.yml に SECRET_KEY_BASE を移行すればOKなはずです。Rails 5.1以前で secrets.yml を使用して秘匿情報を管理していたアプリケーションの場合、移行プロセスは少し複雑になる可能性があります。 9. SECRET_KEY_BASE_DUMMYの活用 Rails 7.1から SECRET_KEY_BASE_DUMMY が導入 されました。これは、SECRET_KEY_BASE の代わりにダミー値を自動的に設定する SECRET_KEY_BASE_DUMMY です。assets:precompile 実行時に SECRET_KEY_BASE が必要ない場合でも、エラーが発生することを防げます。 10. Heroku Data for Redis これはタイミーではなく個人のアプリでの経験ですが、 Herokuで運用、Heroku Data for Redisを利用してる個人アプリのREDIS_URLをCredentialsに移行したらRedisに接続できなくなりました。自分で管理していない環境変数などを移行する場合は注意しましょう。 移行の結果 Credentialsに移行した結果、下記のような成果を実感しています。 ただし、依然としてレビューが大変です。データが暗号化されているため、プルリクエストを出しても差分が分からず、暗号化ファイルのdiffを確認するには公式の bin/rails credentials:diff を利用できますが、Railsの実行環境からgit操作が必要です。一般的な環境ではないかもしれませんが、当社では開発環境にDockerを使用し、ホスト側でgit操作を行っています。そのため、コンテナにgitを導入する検討をしています。 記事の発表やその他の発表が気になる方はこちら! www.youtube.com 少しでも興味を持っていただいた方は是非こちらからカジュアルにお話しましょう! product-recruit.timee.co.jp
イベント概要 2023年11月15日に「GENBA #1 〜RubyとRails開発の現場〜」と題してRuby/Railsでの開発に関するトピックでタイミーとエンペイ社合同で勉強会を開催しました。 その中でタイミーバックエンドエンジニアの正徳さん a.k.a 神速さん( @sinsoku_listy )の発表「Railsアプリと型検査」をイベントレポート形式でお届けします。 登壇者情報 Railsアプリと型検査 RBSの基本 RBSとは RBS(Ruby Signature)は、Ruby 3.0から導入された言語機能で、Rubyのコードに型情報を追加し、型検査と入力補完を可能にするための言語です。RBSファイルの拡張子は .rbsで、通常はプロジェクト内の sig/ ディレクトリに配置されます。 RBSのメリット RBSの主なメリットは「型検査」と「入力補完」の2つがあります。 型検査とは 型検査には、Steepと呼ばれるツールがあります。Steepを使用すると、RBSの定義に違反するコードを検出する役割を果たします。例えば、関数に指定された引数の数が実際の呼び出しと一致しない場合、エラーが検出されます。この型検査は、Rubyコードを実行する前に問題を発見できます。 下記は型検査(Steep)の実行例です。 入力補完とは VS Codeに soutaro.steep-vscode 拡張をインストールすると、RBSファイルを読み込んで、Rubyコードの入力補完が賢くなります。 IRB v1.9.0で、RBSを使った入力補完がサポートされました。入力補完を有効にするには、gem install prismコマンドでprismをインストールし、IRBを起動するときに-r prismオプションを指定します。 タイミーの導入事例:実際の手順 ここまで一応RBSの基本の話だったんですけど、弊社が実際に導入事例を紹介したいと思います。 RBS導入のきっかけ RubyKaigi 2023やメドピアのブログを読んだことから、RBSの導入への意欲が高まりました。 実際に試してみると、型チェックを無効にして、入力補完に重点を置くことで、比較的簡単にRBSを導入できることが分かりました。すぐに社内での調整を行い、方針を策定しました。 社内の開発者に質問してみたところ、RBSを完全に書くことには乗り気ではないものの、重要な部分だけを一部記述したいというニーズがありました。 しかし、それを別のファイルに書くのは少しつらいという声も聞かれました。 そこで元々弊社で使用していた Yard(ヤード)のドキュメントを活用し、重要な部分に型情報を明示し、コメントからRBSを生成して活用するアプローチを考えました。 実際にプロジェクトで検証した結果、うまく機能しそうだったため、「入れてみてダメだったら消そう」というノリで、試してみることになりました。 1. Gemfile に rbs_rails, steepを追加します 2. Steepfileを追加し、既存の型検査エラーは無視する 3. rbs_collection.yaml を作成する Ruby公式で管理されている rbs-gem-collection というリポジトリに、有志の方が提供している情報を利用し、rbs_collection.yaml ファイルを作成します。 4. RBSを生成するRakeタスクを追加する 様々なコマンドを個別に実行するのは手間がかかるため、一度にタスクを生成できる「RBSセットアップ」という独自のコードを作成しました。 このコードは、rbs-gem-collection からRBSをダウンロードし、自社のプロダクトのコードを解析し、適切な雛形を生成し、全てのクラスとメソッド名が含まれたRBSを生成できるものです。 5. .gitignore でディレクトリを無視する RBSは生成されるものとして扱っているため、 .gitignore ファイルでこれを無視するように設定します。 6. RBSの定義エラーを回避するために最小限の型を書く これまでの作業で、多くの型情報を生成できましたが、やはり一部の型情報は自動生成できない場合があります。そのような場合、手動で最小限の型情報を記述することで、エラーを回避します。例えば、Active Admin など一部のジェムは公式の型情報が提供されていないため、自社で型情報を記述する必要があります。ここまで実施し、RBSの文法エラーがない状態にプロジェクトを持っていきます。 まとめ:最小限のRBSで入力補完に型を使用できる RBS + Sord の導入方法 Sordというジェムを使用しヤードドキュメントからRBSコマンドの型を生成します。 まずSordを導入し、Rakeタスクでsordを実行します。このとき sord のバグは、GSub で書き換えるとうまくいくことがあります。 この手順で、 bin/rails rbs:setup を実行するとRBSが生成され、入力補完が賢くなる世界を作ることができました。 ちなみに、RubyMine や VS Code を使用していると、入力補完が賢くなるケースがあるようです。 型検査の課題 タイミーにおける型検査の課題は、Steepの型定義が少ないため、誤検知が発生する可能性があること、 また、特定のファイルのみを無視することができないため、段階的な導入が難しいことが挙げられます。 実際にどれくらいエラーが検出されるか検証をしてみると、656件ありました。ほとんどが誤検知ですが、そのなかで3件ほど面白いエラーがありましたのでご紹介します。 型検査で見つけたコード例1 型検査では、nilチェックが甘いため、ハーストした後にnilが来る可能性があることを考慮せず、IDなどの値に代入してしまうケースがありました。 型検査で見つけたコード例2 タイミーでは、ハッシュから銀行コードを取得する際に、全銀コードがない場合、nilが返されます。このときエラーを検知してしまいます。これは、Steepが全銀コードが正しい値しか渡されないことを前提としているためです(全銀コードが存在しないケースを想定できていない) 型検査で見つけたコード例3 足し算と掛け算をするときに、右の値をぼっち演算子を使うのですが、このときNilエラーが発生します まとめ 今後、開発がさらに進化し、堅牢なコードを手軽に書ける世界がやってくるかもしれません。特に、入力補完の文脈で型検査を導入することは導入ハードルが低く、Railsアプリケーションの開発に大きな価値をもたらす可能性があります。明日からでも是非、Railsアプリ開発に型検査を取り入れてみてください。 記事の発表やその他の発表が気になる方はこちら! www.youtube.com 少しでも興味を持っていただいた方は是非こちらからカジュアルにお話しましょう! product-recruit.timee.co.jp
タイミーでバックエンドエンジニアをしている新谷 id:euglena1215 です。 今回は社内で決めたコーディングルールに強制力を持たせるために CustomCop を作った話を紹介します。 背景 タイミーの Rails アプリケーションには /app/services ディレクト リがあり、 Service クラスが存在しています。 これまで社内で Service クラスは、なるべく使わない方が好ましいものの、どんな時に使っていいかは特段明言されていない状況でした。 その結果かは分かりませんが、一部の機能では Service クラスを多用し Service クラスが Service クラスを呼んでいるなど複雑になっており、コードリーディングの負荷が高まっていました。 この現状に課題感を持った @rhiroe が以下のような問題提起を行いました。 この問題提起を受け、チーム横断の技術領域ごとのトピックについて話し合う MTG で今後の Serivce クラスの運用方針は以下のように決まりました。 Serviceクラスは基本的に積極的な利用は推奨しない。 Service クラスは Controller や Sidekiq Worker から呼ぶものと位置付ける。それら以外から呼びたくなった場合は Model の作成を検討すること。 方針についてバックエンドエンジニア全体に周知は行われましたが、あくまで「きちんと覚えておきましょうね」に留まり、仮に実装者とレビュアーが思い出すことができなければそのままマージされてしまいます。 そのため「このルールを 機械的 に適用できるといいよね」という話があり、用途に合わせた CustomCop を作ることになりました。 特定のsuffixを持つクラス以外からのサービスクラス呼び出しを警告する cop 早速ですが、CustomCop の実装をまるっと公開します。 # frozen_string_literal: true begin require ' rubocop ' rescue LoadError return end module CustomCops # 特定のsuffixを持つクラス以外からサービスクラスを呼び出した場合に警告します。 # AllowSuffix は config パラメータで設定できます。 # # @example # # bad # # AllowSuffix に Service が含まれていない場合 # class SampleService # def call # Service2Service.new.call # end # end # # # good # # AllowSuffix に Service が含まれている場合 # class SampleService # def call # Service2Service.new.call # end # end # class AllowServiceCallClassSuffix < RuboCop :: Cop :: Base MSG = ' 特定のsuffixを持つクラス以外からサービスクラスを呼び出すことはできません。%<suffixes>s のみが許可されています。 ' # ① 許可されている Suffix を持つクラスの定義かどうか # ② クラス定義の中で更にクラスかモジュールを定義しているかどうか # この cop で重要なのは最も深いクラス定義での情報なのでネストしているものは無視(≒許容)する def_node_matcher :define_allow_class? , <<~ PATTERN { (class (const ... #allow_class_name_suffix?) ...) (class const ... {class module}) } PATTERN # (send (const nil? #service_class_name?) :new ...) => FooService.new(...) # (send (const cbase #service_class_name?) :new ...) => ::FooService.new(...) # (send (const const #service_class_name?) :new ...) => Bar::FooService.new(...) def_node_matcher :call_service_class? , <<~ PATTERN (send (const {nil? cbase const} #service_class_name?) :new ...) PATTERN # on_class はクラス定義が行われた時に呼び出されるメソッド def on_class (node) # 許容されるクラスであれば無視する return if define_allow_class?(node) node.each_descendant( :send ) do |send_node| # サービスクラスの呼び出しをしていれば警告する add_offense(send_node, message :) if call_service_class?(send_node) end end private # AllowSuffix で指定した suffix を警告メッセージに加えたかったので上書きしている def message format( MSG , suffixes : allow_suffixes.join( ' , ' )) end # call_service_class? マッチャで使っている def service_class_name? (name) name.to_s.end_with?( ' Service ' ) end # define_allow_class? マッチャで使っている def allow_class_name_suffix? (name) allow_suffixes.any? { |suffix| name.to_s.end_with?(suffix) } end def allow_suffixes # `cop_config` で rubocop.yml で指定した設定を取得できる @allow_suffixes ||= cop_config[ ' AllowSuffix ' ] || [] end end end rubocop.yml には以下のような記述を行います。 CustomCops/AllowServiceCallClassSuffix : AllowSuffix : - Controller - Worker どんな cop かを軽く説明します。 rubocop.yml で指定した AllowSuffix を suffix に持つクラスからの Service クラスの呼び出しを許容し、それ以外のクラスからの呼び出し時には警告を出します。 タイミーでは、Service クラスに XXXService.call のような特異メソッドを用意せず、 XXXService.new.call というように インスタンス を作成した上で呼び出すことが通例となっているため XXXService の new メソッドが呼び出されたことを検知しています。 ここは、各社の通例に合わせてもいいですし、任意のメソッドを呼び出したことを検知しても良いと思います。 また、 service_class_name? メソッドではクラス名の suffix が "Service" かどうかをチェックしていますが、ここを変更すれば Service クラス以外にも適用可能です。 Model, View, Controller 以外のレイヤを採用している Rails アプリケーションであれば、Service クラス以外でも呼び出し箇所を制限したいことがあるかもしれません。 結果どうなったか 上記の CustomCop をタイミーの Rails アプリケーションに導入した結果、違反している箇所が 67件 見つかりました。違反しているファイルを rubocop_todo.yml から眺めてみると、Model から Service を呼び出しているケースと Service から Service を呼び出しているケースが半々くらいのようです。 2024/01/24 時点では、導入したばかりでこれらの違反を解決するための動きは取れていません。 ですが、増やそうとすると RuboCop に怒られるのでこれ以上増えることはないのではないかと考えています(そう信じています)。 タイミーのプロダクトは 1つの モノリス な Rails アプリケーションの上で動いています。その中での67件が多いか少ないかはみなさんの判断にお任せします。我々はこれが伸びしろだと捉え、がんばっていこうと思います。
はじめに 私自身の事例 日々の学習・研究時間の確保 育児との折り合い パートナーや家族のサポートの重要性 日々の学習や研究の効率化 効率的な勉強法や研究の進め方の文献 社会人の特権のツールへの投資 ストレス管理と心の健康 タイミーという最適な環境 育児への支援制度 自己研鑽への支援制度 DSグループでの働き方 まとめ はじめに こんにちは、株式会社タイミーのデータエンジニアリング部データサイエンス(DS)グループ所属の貝出です。 私は現在タイミーで働きながら、育児しつつ、社会人大学院(修士)に通っています。今回のブログでは、仕事・育児・社会人大学院をどう調整して進めていくかについて書いていきたいと思います。 私自身の事例 簡単な私のプロフィールとしては、以下となります。 妻と一歳の息子の三人家族 妻は2023年度までは育休を取得予定 タイミーで週5リモートワーク勤務 JAIST博士前期課程社会人コースの社会人大学院生(2023年4月から) となります。 もともと大学時代では別分野を専攻していたということもあり、業務を進める上で情報科学の知識や研究経験が十分でないことに課題を感じていた私は、妻の後押しもあり、2022年2月頃に社会人大学院への進学を決意しました。研究室の先生や前職の同僚の助けもあり、無事にJAISTに入学することができました。 ただ、入学することよりも修了することの方が何倍も大変であり、そのためには、育児と仕事をこなしつつ、日々の学習や研究を進める必要がありました。 日々の学習・研究時間の確保 社会人大学院生は、通常の大学院生に比べて圧倒的に時間が足りなくなります。それに加え、育児によりさらに時間がなくなります。そのため、どうにか工夫をして時間を捻出する必要がありました。 時間を確保するアプローチとして、個人的には以下をとっています。 育児との折り合いをつけ、時間を確保する 日々の学習や研究を効率的に進める 育児との折り合い 基本方針としては、子供が寝ている間に学習・研究時間の確保が可能です。そのため、 朝5時に起き、子供が起きるまで集中的に時間を確保する 子供の寝かしつけが終わってからの時間を確保する ができます。私の場合は、早朝の 5:00~7:00 と、夜の 21:00 ~ 22:30 のあたりを確保しています。ただ、子供が6:30ぐらいに起きることもあるので、そのときは早めに切り上げたりしています。 パートナーや家族のサポートの重要性 あとは、週末や休日の仕事がないとき、妻に子供を見てもらっている時間に、学習・研究時間を確保します。ただし、ここについては家庭内で十分コミュニケーションを取り、妻の理解を得ることが必要です。また、夫婦間でバランスが崩れないように調整することも必要です。 自分が子供を見る時間は、一緒に公園や近所の公民館に行き、妻のフリーの時間をなるべく確保できるように努力しています。最近は歩けるようになって、すごく楽しそう! 日々の学習や研究の効率化 時間を確保するアプローチの2つ目として挙げた、「日々の学習や研究を効率的に進める」を実施するために、 効率的な進め方に関する文献を調査し、実践する テクノロジーを活用したツールに惜しみなく投資する を行っています。 効率的な勉強法や研究の進め方の文献 効率的な勉強法や研究の進め方ってそもそもどうやんの?というところを現役の学生になったつもりで再度勉強しました。参考になった本としては、以下の本があります。 「勉強法のベストセラー100冊」のポイントを1冊にまとめてみた。 研究の育て方: ゴールとプロセスの「見える化」 卒論・修論研究の攻略本:有意義な研究室生活を送るための実践ガイド 学習については、「(1)こまめに復習をする と (2) 覚えたことをアウトプットする(口に出す、空で説明する、書く)」を大事にしています。あとは、時間を決めて集中できるようにして取り組むなど。 一年目は講義に集中していたため研究はあまり進んでいないですが、先程挙げた本を参考に研究の効率化も進めればと考えています。 社会人の特権のツールへの投資 社会人と現役の学生の最大の違いは時間とお金だと思っており、社会人は時間がない分、仕事で稼いだお金を使って自身の学習への投資が可能になります。 私のケースだと、論文読みやノートのために iPad Air を購入しました。便利なアプリとしては以下を利用しています。 Good Note 6(電子ノート) Paperpile(論文管理ツール) Kindle(本) これらのツールを用いることで、ノートや本、論文を持ち歩かなくても、どこでも学習や論文読みが可能になります! Good Note 6 は、空白のノートだけでなく講義のスライドも読み込めるので、デジタル上でスライドに書き込めるところがとても便利です。 Paperpile は論文管理ツールですが、講義の Class Note や PDF形式の教科書として読み込んでも便利です。例えば、目次や式の番号をパースしてくれて、リンクとして飛べるようになっているので、読む効率が上がります。自分の認識している範囲だと、Good Note 6にはこの機能がないので、使い分けています。ペンやマーカーなどの書き込む機能については、Good Note 6の方が自由度が高いですね。 ストレス管理と心の健康 日々の限られた時間の中で、仕事と育児、それから社会人大学院とたくさんやることがあり、生活に余裕がなくなってしまい、知らないうちにストレスを溜めてしまうことがありました。それが原因で、眠れなかったり、いらいらしたりしてしまうこともありました。心の健康を保つためにもストレス管理に注意する必要があります。 私が気をつけるようにしていることは、 1,2 時間ぐらい机で作業した後は、10分ぐらいふらっと散歩したりストレッチしたりする。 頭が疲れて回らない場合は、ぼーっと10分ぐらい何もしない、何も考えない(瞑想といえば瞑想)。 眠いときは遠慮せずに寝る 定期的に家族内や友達のイベントを作って、全力で楽しむ ジムに行ったり、ジョギングをしたりなど、定期的な運動の習慣を作る 1日の最後は夫婦でおしゃべりをして、リラックスする です。 また、学習や研究がどうしても予定通りにいかないことがあります。子供が熱で体調を崩したり、急遽別の予定が入ったりなど。また、自分のタイムマネジメントがうまくいかず、思ったように学習や研究が進まないこともあります。 そのようなときは一旦無理なスケジュールを引いている状態を認識して、緊急度と重要度のマトリクスを作成し、優先度の低いものからは撤退するようにしています。やっぱり無理なものは無理なので。 タイミーという最適な環境 さて、これまでは育児や大学院での過ごし方などプライベートに関する話がほとんどでしたが、冒頭にも書いた通り、タイミーでは育児や自己研鑽への支援制度があり、私のような技術職には大変ありがたい環境となっています。 育児への支援制度 タイミーでは産休・育休とは別に以下の制度があります。 出産休暇:配偶者が出産する際、産休・育休とは別に、出産当日までの間で3日間の特別休暇を付与(有給) 子の看護休:子どもの看護を目的に、子ども1人につき年間5日付与(子ども2人以上は10日が上限) corp.timee.co.jp 自己研鑽への支援制度 また、タイミーではエンジニアの市場価値向上につながる成長支援、学習支援、機会提供、生産性向上に資する取り組みも実施しています。そのための組織として DevEnable 室を設立し、「TDE10(Timee Dev Enable)」という、エンジニアの進化のための10の施策が進められています。 DSグループでの働き方 DSグループでは、フルリモート勤務も可能であり、フレックスタイム制(コアタイム12:00~16:00/所定労働時間8時間00分、休憩60分)であるため、個人の状況にあわせて働き方を調整することができます。実際に、保育園に通っているお子さんがいる社員は、保育園へのお迎えの時間にあわせて就業時間を調整していたりします。 まとめ 今回の事例では、私のケースが育児と社会人大学院の両立というレアなケースでしたが、タイミーでは働きながら育児や自己学習に取り組む社員がたくさんいます。当社は多様な働き方が可能な職場環境を提供し、柔軟でサポートが充実している条件のもと、異なるバックグラウンドやライフスタイルを持つ方達が活躍しています。 現在、タイミーではデータサイエンティストやエンジニアなど、一緒に働く新しいメンバーを積極的に募集しています! また、気軽な雰囲気での カジュアル面談 も随時行っておりますので、ぜひお気軽にエントリーしてください。↓ hrmos.co hrmos.co
自己紹介 部署紹介 一日の流れ 朝のルーチン: 午前中の仕事: 9:00~11:00 フォーカス課題の分析 11:00~11:30 データアナリスト全体のデイリーミーティング 11:30~12:00 他のメンバーのクエリレビュー 昼休憩: 午後の仕事: 13:00~13:30 依頼タスクのヒアリング 13:30~14:30 依頼タスクの対応、納品 14:30~16:30 フォーカス課題の分析 16:30~17:00 定例ミーティング(部署連携の持続PJT) 17:00~18:00 採用面接 18時から中抜け(あるいはそのまま退勤): 20~21時以後: 20:00~20:30 面接の議事録完成、評価の完了 勤務体系 We’re Hiring! 自己紹介 こんにちは、タイミーのデータアナリストチームの一員、胡です。 私の日本でのキャリアは約10年前、早稲田大学院でMBA取得を目指して来日したことから始まりました。 学位取得後、開発ベンダー企業でエンジニアとしてキャリアをスタートし、その後中小企業でシステム統括の責任者、製造業のベンチャー企業での経験を積みました。 これらの職場で、データに関する多くの課題に直面し、自らの手で社内のデータ環境を整備することもありました。 この経験が、データアナリストとしてのスキルを磨く大きな契機となり、最終的にタイミーでのキャリアをスタートさせるに至りました。 プライベートでは、2歳になる娘を持つ三人家族の一員として、忙しい日々を過ごしています。 最近では、趣味と言えばすっかり子育てに夢中になっています。子育ては日々の新しい発見と喜びに満ちており、私の人生にとって大切な部分です。 家庭と仕事のバランスを保ちながら、日々成長を続けていけたらと思います。 タイミーで働くことで、充実したキャリアを築きつつ、家族との時間も大切にすることも可能です。 部署紹介 タイミーは、急速に成長を遂げているベンチャー企業です。その成長の基盤の一つが、私たちデータ統括部です。 データアナリストは、現場のチームと協力しながら、実際の業務に即した分析を行っています。また、経営層との密接な連携を通じて、経営に関する直接的な提案を行うことも可能です。 私はプロダクトアナリティクスチームに所属し、プロダクトの改善と向上に日々貢献しています。同じ部署での同僚であるtakahideさんの記事も参考になるでしょう。> takahideさんの記事はこちら 今日は、タイミーのデータアナリストとしての一日を紹介し、私たちの業務の流れを具体的にお伝えします。それでは、さっそく始めていきましょう。 一日の流れ 朝のルーチン : 朝は7時頃に起きます。家族との朝食は一日の始まりの大切なひととき。 娘を保育園に送り出した後、9時前後に自宅の仕事スペースへと移動し、一日の業務をスタートします。 仕事を始める前に、短い時間を使ってメールのチェックや一日のスケジュールを見直します。 午前中の仕事 : 9:00~11:00 フォーカス課題の分析 直近のフォーカスしている課題として、時給と勤務状況の関係性に関する分析です。 こちらは、プロダクトマーケティング(PMM)部と連携しながら進めており、得られたデータから新たなビジネス洞察を得ることが目標です。 フォーカス課題は、担当する部署の目標から派生した課題や、日々の業務から得た気付きに基づく自由研究も含まれます。 進め方としては、議論を重ねて仮説を立てて、それを検証していくサイクルを回します。この過程に置いて、PMM部との協力は非常に重要です。彼らの市場に対する深い洞察と私たちのデータ分析能力が相乗効果を生み出すことで、最終的には、この分析がプロダクト機能の拡張という形で実現されることを目指しています。 11:00~11:30 データアナリスト全体のデイリーミーティング この時間帯は、データアナリストチーム全体でのデイリーミーティングを行います。 ここでは、チーム全員で共通の連絡事項を共有し、データアナリスト部向けの依頼タスクの対応方法について話し合います。通常、このミーティングは30分間設定されていますが、内容によっては早く終わることもありますし、新しいアイデアや施策につながる議論が盛り上がることもあります。 依頼タスクについて少し詳しく説明します。現在、私たちのチームはマーケティング、ビジネス、プロダクトといったユニットごとに分かれており、各ユニットは通常、特定の課題に集中しています。しかし、全社からのデータ抽出依頼が多数寄せられるため、これらに対応するにはチーム全体でリソースを効率的に調整する必要があります。 Lookerの導入と普及により、多くのデータ抽出は各部署が自力で行えるようになりましたが、複雑なデータ集計やLookerで対応できない項目がある場合は、依然として私たちのチームへ依頼が来ます。 これらのタスクは専門性を要求されることは少ないですが、緊急性が高く迅速な対応が求められます。メンバー一人ひとりがこれらのタスクに取り組む頻度は、週に1回くらいです。 11:30~12:00 他のメンバーのクエリレビュー 一般的に、私たちの日常的な課題や依頼タスクの成果物は、データを抽出した後、そのまま提出して完了となります。 しかし、社外向けの資料や財務に関わるデータなど、特に正確性が重要視される場合があります。こうした場合には、原則としてレビュワーを割り当てて、二重チェックの体制を取ります。 この二重チェックプロセスは、データの品質を保証し、エラーや誤解を防ぐために不可欠です。レビューは、データの正確性だけでなく、使用される分析方法や導かれた結論の妥当性についても検証します。 これにより、提供するデータと情報の信頼性を向上させ、私たちのデータアナリスト業務の品質を高めることができます。 昼休憩 : 昼休憩の時間は、日によって多少前後することがありますが、基本的には冷蔵庫にある食材を使って手早く料理を作り、食事をします。 時間が許せば、10〜15分の短い仮眠をとることもあります。 午後の仕事 : 13:00~13:30 依頼タスクのヒアリング 午前中にアサインされた依頼タスクの取り組みに先立ち、依頼者へのヒアリングを行います。依頼タスクの要件は通常、事前に依頼者によって文書化されていますが、より詳細な情報が必要な場合はさらなる確認が行われます。 このステップは必ず行うわけではなく、要件が明確に定義された場合は、成果物を作成した後に依頼者とイメージをすり合わせたり、結果を直接チャットで伝えたりすることもあります。 使い道の確認 抽出データがどの程度の規模で、どれくらいの期間使用されるかを確認し、それに基づいて適切な出力形式を提案します。また、抽出データが他の目的にも汎用的に使用できる場合、今後の依頼タスクでの流用の可能性を検討して作成していきます。 項目の定義のすり合わせ 項目によっては、部署ごとに基準が異なることがあります。そのため、集計条件や項目の定義を明確にしておきます。 抽出項目の提案 時に依頼者がデータに関するリテラシーが低い場合や、要件が十分に記載されていない場合があります。このような状況では、実際に求められている内容を詳しくヒアリングし、最適な出力方法をアドバイスします。 13:30~14:30 依頼タスクの対応、納品 先ほどヒアリングで得た結論に基づいて早速作業に取り組みます。タスクの難易度にはばらつきがあるため、完了までの時間はさまざまです。通常は30分から60分で完了するタスクもありますが、依頼者との段階的なやりとりが必要な場合は、全体として数時間を要することもあります。 14:30~16:30 フォーカス課題の分析 午前中に取り組んでいたフォーカス課題の分析作業を続けます。この作業には、集中を要するため、中断されることなく継続的に取り組むことが重要です。そのため、あらかじめスケジュールをブロックしておくことで、分析に専念する時間を確保できます。 16:30~17:00 定例ミーティング(部署連携の持続PJT) データ統括部以外の部署と協力して進めている持続的なプロジェクトの定例ミーティングを行います。プロジェクトの性質によって、その期間は通常数週間から数ヶ月に及び、状況に応じて定例ミーティング以外の方法での連携も行われることがあります。 この定例ミーティングでは、私が社内でリリースした営業用ダッシュボードの利用状況と改善点に重点を置いています。このダッシュボードは社外向けで、営業活動における重要なツールとして利用されています。現在、社内で最も頻繁に参照されるダッシュボードの一つであり、営業効率の向上と営業レベルの平準化に大きく寄与しています。 17:00~18:00 採用面接 急速に拡大しているタイミーでは、新たな才能とスキルを持つ仲間を増やすことが非常に重要です。 面接では、候補者の技術的能力やチームとの相性、将来のポテンシャルを評価します。これには、専門的なスキルだけでなく、組織文化への適合性やコラボレーション能力も含まれます。私たちは、優秀な人材を見極め、チームと会社全体の成長を支える人材を採用することを目指しています。 18時から中抜け(あるいはそのまま退勤) : 一日の仕事を終えた後の夕方は、家族との大切な時間です。 最初に保育園に娘を迎えに行き、その後は家で夕食の準備に取り掛かります。家族みんなで食事を共にし、その後は子供と一緒に楽しいバスタイムを過ごします。 毎晩ではないものの、娘が就寝する時間が近づくと、その準備は妻が担当し、私はその間に追加の仕事に取り組むことがあります。 20~21時以後 : 20:00~20:30 面接の議事録完成、評価の完了 行われた面接に関する議事録のまとめや、面接評価を行います。 また、この時間を使って追加分析やタスクの整理を行うこともあります。あるいは、そのまま切り上げてプライベートで映画や読書などに充てることもあります。 こちらは私のある一日の過ごし方です。タイミーでデータアナリストとして働く中で、仕事とプライベートのバランスを保ちつつ、様々な課題に取り組む毎日を送っています。 いかがでしょうか。少しでもタイミーでのデータアナリストとしての仕事のイメージをつけたら幸いです。 勤務体系 データ統括部では、フルリモートワークが可能であり、始業時間も柔軟に設定できます。これにより、私たちは自分のライフスタイルに合わせた働き方を選ぶことができます。 私の場合、育児のため、18時には仕事を切り上げることができます。これにより、家族との時間を大切にしながら、効率的に業務を進めることが可能になっています。 さらに、最近は娘が月に一度程度熱を出すことがあり、その都度スケジュールを調整したり、同僚からのサポートを受けたりしています。タイミーでは、このような状況にも柔軟に対応しやすい環境が整っています。 We’re Hiring! 私たちは、ともに働くメンバーを募集しています!! product-recruit.timee.co.jp
タイミーのyama_sitter、須貝、小林です。 国内最大級の アジャイル 、 スクラム 関連のイベント「Regional Scrum Gathering Tokyo 2024(RSGT2024)」 が1/10〜1/12の3日間にわたって開催されました。 2024.scrumgatheringtokyo.org タイミーには世界中で開催されるすべての技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。 productpr.timee.co.jp こちらの制度を利用して今年は スクラム マスター3名、エンジニア3名が参加してきました。 前編 に続き、後編の今回はエンジニア3名から参加レポートをお送りします。 SM/EMからエンジニアに視点を変えて参加 エンジニアの yama_sitter です。 参加は今年で2回目になります。前回は前職からSM/EMの立場として参加しましたが、今回はタイミーの現場エンジニアという立場で参加する形となりました。 「エンジニアからSMになり、EMを経てエンジニアに戻った人」という視点で、特に印象に残ったセッションが3つありましたので紹介します。 Badプラクティスを選んで失敗しながら進めた新規プロダクト開発 自分はSM時代に「形」に捕らわれ過ぎて色々な失敗を重ねてきました。一方で今所属するチームではいわゆる スクラム の形式では仕事をしておらず、それでもちゃんと成果が出せている状態です(※1)。これらの経験から、この1年ほどは「 アジャイル は形じゃない」というのを自分なりに理解し、また考え続けていました。(この間、世に出回る「べき論」や「プ ラク ティス」みたいなものをとにかく疑ってかかっていました) そんな中見たのがこの「Badプ ラク ティスを選んで~」のセッションです。ここでは世間的にはNGとされるプ ラク ティスを敢えて用い、(もちろん苦しみながらも)ちゃんと成果を出した事例が語られていました。Badと言われるものだと分かった上で、そのリスクを理解し取り入れ、結果に結び付ける。このあり方は教科書的でこそないものの、ちゃんとした一つの解だなぁ、と。 つまるところ「価値に向き合い、自分たちが考えうる/持ちうる最大の力で成果を生み出す」ことが重要なのであって、形ではないなという話です。今の自分が感じていることを後押しし更に前に進めてくれたこのセッションは非常に有意義なものでした。 こちらはスライドもあるので是非ご一読を。 speakerdeck.com ※1 あくまで会社全体としては スクラム に力を入れており、自チームは特殊なケースです Lack of curiosity: The silent killer of agile 「好奇心の無さはアジリティを殺す」という話です。内容は勿論ですが、特にこのタイトルが強く印象に残っています。 入社して半年、以前考えていた抽象的な問いからは離れて今はひたすらに具象と向き合っています。入社直後に感じていた様々な疑問も少しずつ薄れてきました。アウトプットこそ出せているとは思います。が、少しずつ「疑問に思う力」や「ワクワクする力」がマヒしていっているのを感じています。 これだと、本当に向き合うべき課題に気付き向き合うことができないんですよね。セッションでも述べられていましたが、「人間はルーチンが好き」なので尚更です。 自分や目の前のコードとひたすら向き合うだけでは高い視点からは物事を考えられません。疑問に思わなければ脳が刺激を受けずに鈍化していきます。ワクワクしていなければ途中で力尽きます。結果として気付ける課題、向き合う課題がすごくミニマムになっていく。 現場にフォーカスするだけだと、巡り巡って良いエンジニアにはなれないなぁ、ちゃんと好奇心を持ち続ける努力をしないとなぁ、と感じさせるセッションでした。 Solving The Value Equation 「レガシーコード改善ガイド」の著者であるMichael Feathersさんのキーノートです。 めちゃくちゃためになる話ばかりでしたが、個人的に刺さったのは「プロセス、 アーキテクチャ 、チームの能力、組織構造といった各レイヤーの目標は、 “価値に至るまでのプロキシ” でしかない」という話です。 “プロキシ” というのが特に良くて、これを意識すると「今の取り組みとその結果は、必ず何らかの価値に転換されるために存在する」という考え方ができます。当然のことではあるんですが、目の前のことにフォーカスしたり「べき論」に囚われたりすると忘れがちだなぁ…と思ったりします。 余談ですが、前職のSM最初期の頃は「それっぽいメトリクス」を見つけては右往左往していました。あれはあれで必要なプロセスだったものの、できればこの “プロキシ” の考え方を持っておきたかったです。 視点を変えての参加となりましたが、選ぶセッションも見るスタンスも感じることも得られるものもかなり違うし、得るものの幅が増えていることに気付いて面白かったです。一度全力でSMをやってからエンジニアに戻ると面白いですね。 とまぁここまで色々書きましたが、正直セッションよりも「素晴らしいセッションを見たあとに同じ熱量を持ったタイミーメンバーと集まり、酒を飲みながら議論する」時間が一番良かったです。こういった時間のために行っているフシすらある。 総じて、RSGTは今年も良いイベントでした。企画/運営の皆さま、ありがとうございます。 メンバーと自分たちの組織について語り合うきっかけに エンジニアの 須貝 (CSM保持)です。 RSGTは今回が初参加でして熾烈なオンサイトチケットの争奪戦を勝ち抜いて現地に行ってまいりました。自分は現在はマネージャーでも スクラム マスターでも無いのですが、以前からチーム・組織で成果を出すにはどうすれば良いかといったテーマに興味があったので参加しました。 基本はセッションを聞くことを中心に、合間の休憩時間などで知り合いの方とお話をして過ごしました。中でも印象に残ったセッションのひとつはJoe Justiceさんの「 ジョーが語る、Teslaでの衝撃的な開発スピード 」です。電気自動車メーカーTeslaの開発サイクルのあまりの速さに本当に自動車の開発なのか!?と驚きの連続でした。と同時にハードでこのスピードでできているのだからソフトウェア開発をしている自分たちももっとやれるのでは、勝手にできないと思っているだけなのでは、という反省もありました。 オフトピックなところだと会場内でプロのカメラマンに写真を撮ってもらえるフォトブースがあったのが良かったです。Global Scrum Gathering Amsterdamで行われていたものが日本にも輸入されたそうです。 プロのカメラマンに撮影されるりっきーさんとShinoPさん 自分たちは普段フルリモートなので、弊社のメンバーと自分たちの組織などについて対面でじっくり話せたのも非常に良い体験でした。チャンスがあればまた参加したいと思います。 RSGTは気づきと学びの場 こんにちは!タイミーでQA スペシャ リストを担当している小林依光です。 RSGTはオンラインで参加しましたが、今回も「やっぱりそうだったんだ」と自分の知識や経験を後押ししてくれる発表内容に、感謝の気持ちでいっぱいになりました。 事例/実績、考え方の共有は気づきと学びの場だと、改めて思いました。 少しですが、私が気になったセッションについて、紹介したいと思います。 「 ベロシティ Deep Dive 」ではベロシティを生産性に活用することをやめましょう!ということを多様な角度から説明していました。どの角度からの説明も納得感のあるものばかりでしたが、一番印象的だったのが、“ アジャイル や スクラム が目指すのは価値の実現であり、この文脈での生産性は「付加価値生産」である”という説明でした。 アジャイル を採用し探索的/実験的にプロダクトを開発し価値を提供するという基本を忘れてはいけないと学べました。 「 プロダクトをあきらめるとき 」のセッションは一般的な スクラム の話ではありませんでしたが、実際のプロダクト開発で遭遇する実例でした。特に“プロダクトを終了させるときの費用”をプロダクト バックログ の順位の下の方に入れておくという考えには共感でき、あきらめる判断やサービス撤退に必要な洗い出しは、プロダクトを止めるときでなく開発を始める際に決めておく必要があると何度か痛感していたので、改めていままでの経験は役に立つことがあると思いました。 紹介したセッション以外からも多くを学べたRSGT、来年は現地で参加できるようにしたいと思いました。 まとめ いかがでしたでしょうか。 参加して満足して終了では意味がない!ということで後日参加者全員で振り返り(Fun Done Learn)も行いました。しっかりと ネクス トアクションも生まれたので、ここからチーム・組織に今回得た学びを還元していければと思います。 来年もまたGatheringしましょう!
タイミーのmaho、ShinoP、りっきーです。 国内最大級の アジャイル 、 スクラム 関連のイベント「Regional Scrum Gathering Tokyo 2024(RSGT2024)」 が1/10〜1/12の3日間にわたって開催されました。 2024.scrumgatheringtokyo.org タイミーには世界中で開催されるすべての技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。 productpr.timee.co.jp こちらの制度を利用して今年は スクラム マスター3名、エンジニア3名が参加してきました。 その参加レポートとして印象に残ったセッション、ワークショップや学びなどを参加者それぞれの視点で共有できればと思います。今回は前後編の前編として スクラム マスター3名のレポートをお送りします! 初参加で OST のホストに挑戦 スクラム マスターをしているmahoです。RSGTは今回が初参加で緊張していましたが、一緒に現地参加するメンバーがいたので心強かったです。 私はまだまだ スクラム マスター初心者ということもあり、セッションを聴いて学びを深めることを一番の目的にしていました。どのセッションも興味深い内容でしたが、全体を通して感じた共通点は以下の三つです。 チームの基盤を支える重要な柱のひとつは関係性であること 変化は時間がかかることを理解して忍耐を持つこと システム全体を捉えるよう努めること 私もこれが体現できるように、学びを実践しながら精進していきたいと思います。 また、三日目の OST には話したいテーマを発表し、ホストとしての参加に挑戦してみました。不安でいっぱいの中、いざ始まってみると集まってくださった方々と予想以上に議論が盛り上がり、とても楽しい時間を過ごすことができました。セッションを聴くだけでなく、Gatheringとしてもよい体験ができたので、もし次回も参加することになれば、より積極的に話す機会を作ってみたいと思いました。 どう社内に持ち帰るかを話す時間は何事にも変え難い タイミーで スクラム マスターをやっているりっきーと申します。昨年に引き続き2回目の現地参加になります。 私は毎年年末にテーマを決めていまして、1年かけて達成したかどうかを振り返っています。 その中で、RSGTは年初一発目ということで年末に決めたテーマについて知見を得たり、ディスカッションをできるので非常に助かっています。 私の本年度のテーマは「 スクラム マスターとして成長できる・やってみたくなる環境を作る」です! テーマに最も関連していたので以下を紹介いたします。 「 スクラムマスターを職能にする挑戦 - 健全なチームを増やし組織をチームワークであふれさせる道のり 」 スクラム マスターをどのように増やしていったか、どのような仕組みを作っていったかは大変参考になり、勇気がもらえました! 1on1や コーチン グ、メンタリング活動は弊社としても取り組み始めていたのですが、給与レンジの検討や成長支援の予算などは検討できてない部分なので弊社ならではを組み合わせつつ、一つの事例として社内に紹介したいと思います。 また、メンターとしては初心者の方もRSGTで楽しめるように社外の人との会話に入ってもらったり、 OST に参加するように促したりを 裏目 標として持っていましたが、楽しめたようで何よりでした! 皆さんも書いてますが、同じものを見て聞いてそれについてどのように社内に持ち帰るかを話す時間は何事にも変え難いので、来年も参加したいなと思いました。(オフライン参加は難しいかもしれませんが) RSGTのオススメの歩き方 こんにちは!タイミーで スクラム マスターをしている ShinoP です! 今回のRSGTは現地参加としては2回目なのですが、前回はセッションを聴くことに夢中になっていて、本当の意味でのGatheringができませんでした。 その中でも OST のホストをやった事で、参加者同士の触れ合いを体験しGatheringの本当の意味を理解しました。 ですので、セッションに関しての感想というよりは、RSGTのオススメの歩き方を紹介したいと思います! 今回のRSGTでの立ち回りはセッションを聴くだけでなく… 「廊下で初めて会った人と話す」 「お昼に社外の人と話す」 「研修やコミュニ ティー で面識のある人と話す」 「登壇者と話す」 「飲み会に参加する」 「お昼の30秒宣伝コーナーで話す」 などを積極的に行った結果、同じような悩みを抱えている方と話すことによってヒントを得られたり、登壇者の方と話してアド バイス をもらったり、面識のある方々とワイワイできたり…このような歩き方も学びがあるので是非試してみてください! また、RSGTや スクラム フェスは人に話しかけやすい構造になっていると思いますので、隣に座っている人とかに話しかけたりすると繋がりが広がっていくと思っていますので、是非思い切って話しかける事がオススメです! 今回のレポートは以上となります。 続きの後編は「エンジニア編」として近日公開予定です。
こちらは Timee Advent Calendar 2023 シリーズ1の25日目の記事になります。 昨日は @tomoyuki_HAYAKAWA による Swift Concurrency AsyncStreamを使ってみる #Swift - Qiita でした。 タイミーでバックエンドエンジニアをしている id:euglena1215 です。 メリークリスマス🎄 みなさんの手元にはプレゼントは届いているでしょうか。 Ruby の世界では Ruby コミッターサンタさんがクリスマスプレゼントとして新しい Ruby バージョンをリリースしてくれます。 今年は Ruby 3.3 ですね。個人的には 3.3 の YJIT がどれだけ速くなるのか楽しみです。 また、新しいバージョンのリリースにはアップグレードがつきものです。アップグレードせずには新しいバージョンの恩恵を受けることはできません。 ということで、今回はタイミーが社内で運用している社内版 Ruby Rails アップグレー ドガ イドを社外に公開します。 社内版の情報を黒塗りしては社内版を公開する意味がありません。そのため、最大限 原文ママ でお送りします。前提として足りない部分は「記事用補足」と追記しています。 社内版 Rails アップグレー ドガ イド このドキュメントは Rails アップグレードのために普段からやること、実際のアップグレードの際にやることをまとめたものです。基本的には一般的な Rails アップグレー ドガ イドと同じですが、QAチェックの必要性など社内特有の事情も考慮されています。 下記のドキュメントは Rails のメジャーバージョン・マイナーバージョンを上げる際に意識すべきことです。パッチバージョンは普段のライブラリアップデート同様に上げてもらって構いません。 🟥 MUST: 安全なアップグレードのために必ず実施しなければいけません。 🟨 SHOULD: 必ず実施しなくてもいいですが、やっておくことを推奨します。 🟩 MAY: 行わなくてもアップグレードは実施できます。関心がある方だけで構いません。 以下の作業は基本的に並列かつ複数人で実施可能です。 社内版 Rails アップグレードガイド 普段やること Rails Edge のキャッチアップ(🟩 MAY) Rails Edge 起因で失敗しているテストの修正(🟨 SHOULD) Rails へのコントリビュート(🟩 MAY) アップグレード前にやること アップグレード先のCIを用意する(🟨 SHOULD) Railsバージョン起因でスキップしているテストをなくす(🟥 MUST) deprecation warning をなくす(🟨 SHOULD) rails app:update の実行(🟥 MUST) Rails アップグレードガイドのバージョンに対応した変更を読んで問題ないことを確認(🟥 MUST) リリース前の手動での動作確認(🟥 MUST) アップグレード作業中に行うこと アップグレードの事前周知(🟥 MUST) rollback 用のコミットハッシュを取得する(🟥 MUST) Revert PR を作成する(🟩 MAY) 各種監視を行う(🟥 MUST) アップグレード後にやること new_framework_defaults_x_y.rbの有効化(🟨 SHOULD) config.load_defaultsの更新(🟨 SHOULD) 参考 普段やること Rails Edge のキャッチアップ(🟩 MAY) #guild_rails_edge には毎日 rails / rails の main branch にどんな変更がマージされたのかが流れてきます。ここで次のアップデートでどんな変更が入るのかをチェックしましょう。日頃からチェックしておくとアップデート時に情報の波に飲まれにくくなります。 (記事用補足:ここで流しているのは y-yagi さんのブログです) y-yagi.hatenablog.com Rails Edge 起因で失敗しているテストの修正(🟨 SHOULD) 通常の Rails バージョンでは動作するが Rails Edge で動かないテストは pending: pending_if_rails_edge をつけて pending してあります。 grep して pending しているテストを見つけて問題を特定し修正しましょう。 (記事用補足:タイミーでは CI で Rails Edge を使ったテストを実行しています。詳しくは以下) tech.timee.co.jp Rails へのコントリビュート(🟩 MAY) 「 Rails Edge 起因で失敗しているテストの修正」の大半はアプリケーションコードに起因する問題であることが多いですが、たまに Rails 本体のバグに遭遇することもあります。その際は Rails にバグレポートや修正 PR を送ることを推奨しています。 リリース済みのバージョンの仕様を変えるのは難しいですが、betaやrc版ではissueやPRを送ることで仕様を変えられる可能性があります。意図しない破壊的変更を見かけた場合は積極的にやりとりしましょう。 参考: Get started with OSS contributions - Speaker Deck アップグレード前にやること アップグレード先のCIを用意する(🟨 SHOULD) アップグレードを検討している頃には既にアップグレード先のバージョンがリリースされているため、 Rails Edge はその次のバージョンになっていることが多いです。そのため、 Rails Edge CI ではアップグレード先のバージョンでのテストは実行できません。 アップグレード先の Rails バージョンでの CI を用意しましょう。そうすることで、アップグレード先バージョンでのテストが普段から実行できるようになるので問題を早期発見できます。 参考 (ここに Rails 7.1 の CI を用意した Pull Request URL が貼ってありました) Rails バージョン起因でスキップしているテストをなくす(🟥 MUST) Rails バージョン起因でスキップしているテストはアップグレード後に動かなくなるテストです。このテストを放置したままアップグレードを実施すると該当機能が動かなくなるので必ずスキップしているテストがないことを確認しましょう。 「 Rails Edge 起因で失敗しているテストの修正」を実施していればスキップしているテストはほとんどなくなっているはずなので、このステップの対応が楽になります。 参考 (ここに Rails バージョン起因でスキップしているテストを修正している Pull Request URL が貼ってありました) deprecation warning をなくす(🟨 SHOULD) ほとんどの問題は「 Rails バージョン起因でスキップしているテストをなくす」によって解消されますが、テスト環境では捉えきれない問題も存在します。それらの問題を洗い出すために、タイミーでは本番環境で発生した deprecation warning をログとして出力するようにしています。出力されたログは Datadog Logs で確認できます。 また、ログが出力されすぎて Datadog のコストを圧迫することを防ぐためにログ出力は確率的としています。deprecation warning が減ってきたら合わせて確率を100%に近づけ漏れなくキャッチできるようにすることを推奨します。 rails app:update の実行(🟥 MUST) Rails では app:update というコマンドが提供されています。 Gemfile に記載されている Rails のバージョンを更新後、このコマンドを実行することで、新しいバージョンでのファイル作成や既存ファイルの変更を対話形式で行うことができます。 $ bin/rails app:update exist config conflict config/application.rb Overwrite /myapp/config/application.rb? (enter "h" for help) [Ynaqdh] force config/application.rb create config/initializers/new_framework_defaults_7_0.rb ... 予期しなかった変更が発生した場合は、必ず差分を十分チェックしてください。 https://railsguides.jp/upgrading_ruby_on_rails.html#アップデートタスク デフォルトに合わせていた方が今後のアップグレードが楽になるため、既存の挙動をなるべく変化させないように更新分を取り込みましょう。 変更差分を知りたい場合は https://railsdiff.org/ から確認できます。 Rails アップグレー ドガ イドのバージョンに対応した変更を読んで問題ないことを確認(🟥 MUST) 公式の Rails アップグレー ドガ イドにはメジャーバージョン・マイナーバージョンのアップグレードに対して破壊的変更など何らかの対応が必要な変更がまとまっています。これらを確認して問題がないことを確認してください。懸念がある場合は #prd_ch_ruby_on_rails で相談するなど適切な対応を行なってください。 例:7.0→7.1 Rails アップグレードガイド - Railsガイド 参考 (ここに確認したログをまとめた Notion リンクがありました) リリース前の手動での動作確認(🟥 MUST) リリース前の手動での動作確認は必須ですが、社内向け管理画面の最低限の疎通確認のみで問題ありません。 背景: (ここに意思決定の証跡として MTG 議事録リンクが貼ってありました) また、社内向け管理画面においても十分なテスト カバレッジ があれば動作確認を省略することができます。社内向け管理画面のテスト カバレッジ を上げるプロジェクトについては(Notion URL が貼ってありました)を確認してください。 (記事用補足:プロジェクトの Notion URL よりもTimee Advent Calendar 2023シリーズ1の5日目記事の方がより詳細にプロジェクトの説明をしています。興味があればご覧ください。) tech.timee.co.jp アップグレード作業中に行うこと アップグレードの事前周知(🟥 MUST) Rails アップグレードのリリース直後に rollback が困難な変更が行われると Rails アップグレード起因で問題が発生した際に rollback が困難になり、問題の復旧が遅れます。そのため、アップグレードを事前に周知しアップグレード後30分間はデプロイ(=マージ)を行なわないよう呼びかけてください。 rollback 用のコミットハッシュを取得する(🟥 MUST) 問題があった際の復旧を早めるために rollback で戻す先のコミットハッシュを用意しておきましょう。 https://github.com/x/x/commits/master から確認できます。 Revert PR を作成する(🟩 MAY) 問題があった際の復旧を早めるために merge 後すぐに Revert PR を作成しておくことを推奨します。先に Revert PR を作っておけば feature branch での CI 待ちをショートカットすることができます。 問題が発生せずに無事リリースできた場合はきちんと PR を close しておきましょう。 各種監視を行う(🟥 MUST) リリース直後は問題を早期発見するために各種の監視を行なってください。15分様子を見て問題が見つからなければ急いでrollbackする必要はありません。 Sentry 普段見かけないエラーが発生していないかどうか Datadog ダッシュ ボード 大きなメトリクスの変化がないかどうか APM レイテンシやエラーレートに変化がないか (記事用補足:Sentry や Datadog など各種 URL が貼ってありましたがさすがに削除させていただきました) アップグレード後にやること new_framework_defaults_x_y.rbの有効化(🟨 SHOULD) Rails をアップグレードしただけでは多くの新しい機能は有効化されていません。 rails app:update で作成された new_framework_defaults_x_x.rb の コメントアウト を1つずつ確認してデフォルトに合わせられそうなものは有効化しデフォルトに合わせ、意図を持ってデフォルトとは異なる設定を行う場合は application.rb に設定を追記しましょう。 config.load_defaultsの更新(🟨 SHOULD) app:update タスクでは、アプリケーションを新しいデフォルト設定に1つずつアップグレードできるように、 config/initializers/new_framework_defaults_X.Y.rb ファイルが作成されます(ファイル名には Rails のバージョンが含まれます)。このファイル内のコメントを解除して、新しいデフォルト設定を有効にする必要があります。この作業は、数回のデプロイに分けて段階的に実行できます。アプリケーションを新しいデフォルト設定で動かせる準備が整ったら、このファイルを削除して config.load_defaults の値を反転できます。 https://railsguides.jp/upgrading_ruby_on_rails.html#フレームワークのデフォルトを設定する 参考 railsguides.jp qiita.com いかがでしたか? タイミーは上記の Rails アップグレー ドガ イドを用いて Rails アップグレードを行なっています。とは言ったものの、このアップグレー ドガ イドは Rails 7.1 アップグレードでやったことを体系的にまとめたもので本当に運用され始めるのは Rails 7.2 アップグレードのタイミングになります。 Rails アップグレードは属人的なタスクになりがちです。特定の人物がアップグレードの番人になるのではなく、誰でもアップグレードにチャレンジできるようにしたかったのがアップグレー ドガ イドを作成した背景になります。 ネットには質の高い Rails アップグレー ドガ イドがたくさん存在します。ですが、どのステップをどんな期待値で実施するか・動作確認はどこまでやるかは各社の状況に依ると思います。社内の暗黙値を減らすためにも社内版 Rails アップグレー ドガ イドを作ってみてはいかがでしょうか。
こんにちは!株式会社タイミーでプロダクトマネージャーをしているAndrewです。 私はオフショ アメンバー が関与するSquadに所属しています。このSquadはエンジニア組織の中でもユニークな環境であり、ここで直面した問題とそれを乗り越えるための取り組みをこの記事で紹介したいと考えています。 オフショ アメンバー とのコラボレーションの課題 約半年前、オフショ アメンバー のいるSquadと関わり始め、このSquadの各メンバーを知るきっかけとなりました。 最初は、日本メンバーとオフショ アメンバー のコミュニケーションがスムーズでないと感じました。ミーティングでは通訳担当の方以外、オフショ アメンバー 全員がほとんど発言しませんでした。 また、ミーティングで話されている内容が彼らが理解できる言語で記録されていないケースが多く、情報の透明性に欠けていました。開発した機能の目的が何かを理解しない場面を見かけたこともありました。 しかし、これは単なる課題ではなく、Squad全体のポテンシャルを引き出すためのチャンスでもあると考えました。 エンジニアは機能を作るだけでなく、プロダクトに関心を持ち、価値を届けることに注力すれば、より多くのアイディアやソリューションが生まれ、良いプロダクトが作れるのではないかと。そのためには、オフショ アメンバー が積極的にディスカッションに参加できるようにする必要がありました。 最初は言語の壁があると感じたため、心配もありましたが、様々な施策を試してみました。その一環として、ドキュメントの整理とオンライン言語交流会を実施してみました。 情報透明性を向上するためのドキュメント 「ドキュメントのメンテナンスが面倒くさい!」、「コードを読む方が早い!」と思う方は少なくないでしょう。 コードにコメントがないと、そのコードが何をしているか理解することが難しくなります。それと同様に、ドキュメントがないと、システムや機能の全体像を把握するのに時間がかかり、理想的な状態と言えません。 コードで説明できない背景や設計の意図、特定の決定の背後にある論理をコメントで説明することで、コードを読む人が理解しやすくなります。しかし、コードのコメントでわかりやすく説明できる内容はテキストベースの情報に限られているということもあり、コードは特定のメンバーしかアクセスできないため、ここでドキュメントが強力な情報共有手段になります。 ドキュメントに対する工夫 ドキュメントを書くときにわかりやすくするためにいろんなテクニックがあります。 テキストに色をつけたり、フォントサイズを変えたり、ページの余白を活かすことで視覚的なメリハリをつけることが重要です。 これにより、複雑な情報も読みやすくなり、重要な情報を強調することができ、逆に強調したくない情報を目立たなくすることもできます。デザインが好きな私にとっては、ドキュメントは良いデザインを表現することのできる優れたツールです。 わかりやすいドキュメントを書くことは簡単ではありません。いろんなドキュメントの種類の中で、エンジニア向けのものもあれば、 ステークホルダー (非エンジニア)向けのものもあるので、伝わるように読み手のバックグラウンドや知識に合わせて書くことが必要です。 難しい単語ではなく、あえてシンプルな単語を選び、物事を説明することで言語の壁をなくせるので、自分の言葉の知識を見せびらかす必要なんてありません。 このような意識をもって書けば、ドキュメントを書くことは単調な作業ではなく、実は楽しい作業なんです。 バランスがすべて 口頭でコミュニケーションが取りづらい状況では、ドキュメントは尚更重要です。 ドキュメントがあることで、メンバーはいつでも情報にアクセスでき、フィードバックや提案もしやすくなります。ただし、あまりにも詳細な内容、たとえばコード実装のレベルの情報まで書いてしまうと、細かなコードの変更が生じるたびにドキュメントを更新しないといけなくなってしまいます。 同様に、テキストだけの長い文章を書いてしまうと、ドキュメントの恩恵が受けられなくなり、わかりやすさが損なわれ、逆に効果が薄れてしまいます。適度な詳細と抽象度のバランスを取ることが大切であり、ドキュメントが管理の手助けとなるよう心がけが必要です。 活用されるドキュメント 実際にこの取り組みを導入して、Squadの振り返りミーティングで「 ドキュメンテーション をよく参照するようになって、仕事において役立った」「ドキュメントが整理されていてわかりやすい」というメンバーからの声がありました。 今後、ドキュメントを書くのは私ではなく、オフショ アメンバー 全員も同じようなケイパビリティを持たせたいので、以上に書いたポイントを彼らに教えました。 今ではオフショ アメンバー 全員がドキュメントを書くようになり、 ステークホルダー から仕様確認の問い合わせが来ても、すぐ回答できるようになりました。これにより、プロジェクト全体の透明性が向上し、知識の共有がスムーズになりました。 長期的な視点で見れば、ドキュメントはSquad全体の知識の蓄積として機能し、メンバーが増えても情報の共有の負担は軽減されます。 オンライン言語交流会 ドキュメント整理が進む中、私たちはSquadメンバーがより積極的に参加し、アイディアを共有できる環境を整えるためにもう一つの取り組みを始めました。それが、オンライン言語交流会です。 知っている人とコミュニケーションを取ることは楽ですが、知らない人となると相手の意図がどのようなものかもわからないし、ミスコミュニケーションの原因にもなります。できるだけオフショ アメンバー とのコミュニケーションを増やすことで、彼らもより気軽に話しかけてくれるだろうと期待しています。しかし、日本語もできず、英語にも自信がないメンバーとどのようにすれば交流できるのか悩んでいました。そこで、オンラインで言語交流会を試してみました。 オンラインで実施しやすいアイスブレイク いきなり何かを英語で話せと言われても難しいですよね。 そこでアイスブレイクゲームを導入し、わざわざ自分でトピックを考える必要がなく、よりカジュアルに話せる環境にしました。最初は簡単なものから始め、英語で自分のカバンに入っているものを紹介したり、謎解きをしたりしました。 カバンに入っているものを紹介する中で、お弁当の中身だったり、意外なエアコン用のリモコンの話も出てきて、会話が弾みました。謎解きをするときもトリッキーな謎が多く、あるメンバーがたくさん正解を回答できて、他のメンバーから カンニング しているだろうと冗談で言われたりしていた覚えがあります (笑)。 これにより、お互いの趣味や考え方を知ることができ、メンバー同士のコミュニケーションが深まりました。 伝わることの喜び オフショ アメンバー と会話を重ね、最初は英語に対して悲観的で、喋ろうとしないメンバーも自然と喋るようになりました。この記事を書く際に彼らにその理由を聞いてみました。 「英語の発音は下手ですが、理解してくれる人がいるので勇気が出る」「私の英語で喋っても笑われていないし、Andrewからの促進で一歩踏み出そうと思うようになって、ディスカッションに関与する重要性を理解できるようになった」という素敵なコメントをいただきました。 これらの言葉を通じて、協力し合いながら成長するプロセスに感謝しています。 このオンライン言語交流会の ファシリテーション は最初は私が担当していましたが、現在はオフショ アメンバー が積極的に ファシリテーション することもあります。今では毎回アイスブレイクゲームだけでなく、単純に英語で雑談することもできる環境になりました。 また、この会の名前の通り、英語に限らず、最近私が彼らから言語を学ぶ機会も得ました。 Squadの成長と今後 まだ完璧な状態には達していませんが、Squad全体がどんどん成長している実感があります。オフショ アメンバー が積極的にコミュニケーションに参加し、自ら意見を言うようになったことは、大きな進歩と言えます。 異なる文化やバックグラウンドの人と仕事することは、チームが結束するまでには時間がかかりますが、結束ができた際には異なる視点から物事を判断でき、それによるメリットも大きいです。 私の過去の経験では、さまざまなバックグラウンドを持つ人々が集まれば、クリエイティブなアイディアが生まれやすくなります。そのため、このような多様性を大切にしていきたいです。 最後に、今後もSquad全体で協力し、より良いプロダクトを生み出すために努力していきたいと思います。
こちらは Timee Advent Calendar 2023 シリーズ1の19日目の記事です。 はじめに こんにちは、タイミーで Android エンジニアをしているsyam( @arus4869 )です。 この記事では、タイミーで実際に利用しているBitriseとFirebase App Distributionを用いた Android アプリの配布方法を実例を交えながら紹介していこうと思います。 この記事を通じて、同じようなツールを利用している他の開発者の皆さんにとって、参考になる情報を提供できればと思います。 BitriseとFirebase App Distributionについて Bitriseは、モバイルアプリのCI/CDプロセスを自動化するプラットフォームです。ビルドからデプロイまでを簡単に管理でき、開発サイクルを効率化します。 Firebase App Distributionは、アプリのベータ版やテスト版をテスターに迅速に配布するためのツールです。新しいビルドをテスターに届け、フィードバック収集が可能です。 これらのツールを組み合わせることで、 アプリ開発 の流れをスムーズにしてくれます。 事前準備 BitriseとFirebase App Distributionを使用する前に、いくつかの事前準備が必要です。 まず、BitriseとFirebase、そして Google Cloud Platform( GCP )のアカウントを準備します。 それぞれのツールを利用するには適切なアクセス権と設定が必要です。事前に準備しましょう。 詳細なアカウント作成方法については、それぞれの公式を参照してください。 参照URL Bitrise Firebase Google Cloud Platform(GCP) 次は具体的な手順へ進めていきます。 手順1: Firebase App Distributionのグループとテスターの設定 Firebase App Distributionを使用してアプリを効率的に配布するためには、適切なグループとテスターの設定が必要です。 以下のステップに従って設定を行いましょう。 Firebaseプロジェクトにアクセス Firebaseコンソールにログインし、対象のプロジェクトを選択します。 テスターグループの作成 「App Distribution」セクションに移動し、「テスターとグループ」タブを選択します。 「新しいグループを作成」をクリックし、グループ名(例:product_team)を入力します。 テスターの追加 新しいグループを選択し、「テスターを追加」をクリックします。 テスターのメールアドレスを入力し、グループに追加します。 テスターは開発用と本番用のアプリに分けてグループ化すると管理がしやすくなります。 この手順により、特定のテスターグループに対して、アプリのテストビルドを簡単に配布できるようになります。 グループとテスターの設定が完了したら、次にFirebaseの認証用サービスアカウントの作成をしていきます。 手順2: Firebaseの認証用サービスアカウントの作成 Firebase App Distributionでアプリを配布するためには、Firebaseの認証用のサービスアカウントを設定する必要があります。この手順では、その設定方法を説明します。 Google Cloud Platform( GCP )でサービスアカウントを作成 GCP の ダッシュ ボードにアクセスし、「サービスアカウント」ページを開きます。 「サービスアカウントを作成」を選択し、アカウントの詳細を入力します。 必要なロールを割り当て サービスアカウントに以下のロールを割り当てます: Firebase 品質管理者 Firebase App Distribution Admin SDK サービス エージェント これらのロールにより、アカウントはFirebase App Distributionでのアプリ配布に必要な権限を持つことになります。 秘密鍵 の生成と保存 サービスアカウントに対して新しい 秘密鍵 を生成します。 生成された 秘密鍵 を安全な場所に保存し、後のBitriseの設定で使用します。 次は、このサービスアカウントを使用して、Bitriseでのプロジェクト設定を行います。 手順3: Bitriseの設定 次は、BitriseからFirebase App Distributionを通じてアプリを配布するためには、Bitrise上での適切な設定が必要です。以下のステップに従って、Bitriseでの設定を行いましょう。 Bitriseプロジェクトのセットアップ : Bitriseにログインし、新しいプロジェクトを作成または既存のプロジェクトを選択します。 プロジェクトのビルド設定を確認し、必要に応じて調整します。 Firebase App Distributionステップの追加 : プロジェクトのワークフローを編集し、「[BETA] Firebase App Distribution」ステップを追加します。 このステップにより、ビルドが成功すると自動的にFirebase App Distributionを通じてアプリが配布されます。 認証情報の設定 : GCP で生成したサービスアカウントの 秘密鍵 をBitriseの「Code Signing & Files」タブにある「GENERIC FILE STORAGE 」 セクションにアップロードします。 「[BETA] Firebase App Distribution」ステップの設定で、Service Credentials Fileの項目に「GENERIC FILE STORAGE」セクションにアップロードしたサービスアカウントの 秘密鍵 のパスを設定します。 これらのステップにより、BitriseはFirebase App Distributionと連携し、アプリのビルドと配布を自動化できるようになります。設定が完了すれば、BitriseからFirebase App Distributionを通じてアプリをテスターに配布する準備が整います。 参考程度に「[BETA] Firebase App Distribution」に設定している項目を記載します。 項目 説明 例 Service Credentials File Bitriseのアップロードした 秘密鍵 のパス $BITRISEIO_development_service_account_key_URL App Path APK及びAABファイルが格納されているパス $BITRISE_APK_PATH Firebase App ID Firebaseコンソールのプロジェクトの設定から見れるアプリ ID 1:1234567890: android :0a1b2c3d4e5f67890 Release Notes テスターが見るリリースノート メインブランチにマージされたビルドです。 Test Groups 手順1で設定したテスターグループ product_team まとめ この記事では、BitriseとFirebase App Distributionを活用して Android アプリを配布するための手順を紹介しました。以下は、ポイントのまとめです。 事前準備が鍵 :BitriseとFirebase、 GCP のアカウント設定から始め、必要なツールと情報を確認することが重要です。 Firebase App Distributionの設定 :適切なテスターグループとテスターの設定を行い、アプリのテスト版を簡単に配布できる環境を作ります。 Bitriseの自動化設定 :ビルドプロセスをBitriseで自動化し、Firebase App Distributionを通じてアプリを配布する設定を行います。 このプロセスを通じて、テストアプリの配布が可能となります。あとはテストアプリをどのように使ってもらえるか、開発者以外のメンバーにもフィードバックをもらえるようにドキュメント化することをお勧めします。本記事が、みなさまの開発に役立つことを願っています。
こんにちは、データ統括部BIグループ所属のtakahideです。 本記事では、BIグループで取り組んでいる全社的なデータ活用に関してご紹介します。 この記事を通して、少しでも「社内のデータ活用を進めたい」と思っている方のお役に立てたら幸いです。 ※ Timee Advent Calendar2023 の12月18日分の記事です。 課題感 データ活用に役立つスキル 講習会の開催 少人数の相談会 データ活用スキルの指標化 おわりに We’re Hiring! 課題感 まずは、データ活用を進めるに至った経緯を簡単に説明させてください。 タイミーは、データを用いた意思決定を大切にしているのですが、 近年の組織拡大にともない、データ活用を全社的に推進するニーズが高まっていました。 一方で、データを利用するメンバーのスキルとニーズとの間に乖離が存在していることが分かってきました。 そこで「データ活用を全社的に推進するPJT」をBIグループ中心に立ち上げることになりました。 データ活用に役立つスキル データ活用といっても人によって解釈が異なるため、 データアナリストが日々の業務で用いているスキルの言語化から始めました。 機械学習やプログラミングといった一部の職種で使われるスキルは除外して、 どの職種の方でも役に立つ汎用的なスキルを選択しています。 「課題の発見→課題の解像度の向上→検証に必要なデータの解釈→結果のまとめ」といった流れを意識しています。 講習会の開催 スキルの整理ができたので、次にスキルの意義や使い方を伝える講習会を行うことにしました。 データの価値を実感してもらうことを優先して「データ抽出」の講習会を実施して、 顧客の行動を数値で見る体験をしてもらいました。 具体的には、簡易にデータを扱えるツールとしてLookerの講習会を開催しました。 講習会をキッカケにLookerの利用者が増え、データを見る習慣が作られたと考えています。 最初はお試しで始めた講習会も、現在は毎月実施していて、新入社員の方がデータに触れる機会を作っています。 (詳細は こちらのブログ をご覧ください) 次に行ったのが「論理的思考」「データ構造の理解」「データの解釈と可視化」の講習会です。 これらはデータ抽出の前後に用いることが多く、「データ抽出」の後に実施することで理解が深まると考えました。 下記のように、First Step→Second Stepと段階を踏んで進めてきました。 少人数の相談会 ここで、講習会を通じて見えてきた課題とその対応をお伝えできたらと思います。 課題として分かったことは大きく二つで、 「講習会の難易度」と「質疑応答のしづらさ」になります。 「講習会の難易度」ですが、 講習会では必要最低限の内容をコンテンツに盛り込んでいるものの、 参加者の習熟度の違いを吸収しきれていませんでした。 また、「質疑応答のしづらさ」ですが、 講習会の参加人数が50~100人になるため、質問しづらい雰囲気がありました。 特に、どのレベルの質問をして良いかが分かりづらいという声が挙がりました。 これらを踏まえて、少人数の相談会を進めようとしています。 テーマを絞った数人〜十数人の会にすることで、活発な意見が出ることを期待しています。 全社向けの講習会を定期開催しつつ、補完的に相談会を実施することで、 講習会の内容の充実にも繋がると考えています。 データ活用スキルの指標化 最後に、データ活用の測定に関してお話しできたらと思います。 全社のデータ活用を推進する上で、データ活用スキルの習熟度の把握が重要になります。 タイミー全体でデータ活用がどの程度進んでいるかが分かることで、 データ活用のPDCAが回しやすくなり、スキル習得のモチベーションにも繋がると考えます。 おわりに この記事では、BIグループが実施している、データ活用の取り組みを紹介しました。 改めて「社内のデータ活用を進めたい」と思っている方のお役に少しでも貢献できていたら嬉しいです。 今回は全体の紹介で、個別の詳細はお伝えできていなかったので、 そちらも機会がありましたらお話しできたらと思います。 We’re Hiring! タイミーのデータ統括部では、ともに働くメンバーを募集しています!! product-recruit.timee.co.jp