TECH PLAY

株匏䌚瀟スタメン

株匏䌚瀟スタメン の技術ブログ

å…š232ä»¶

はじめに こんにちは、株匏䌚瀟スタメン 東京プロダクト組織の゚ンゞニアリングマネヌゞャヌ たっきヌです。先日、 EMConf 2026 に参加しおきたした。EMずしお日々悩みながら手を動かしおいる身ずしお、組織のあり方・マネゞメントの考え方・技術ず人の接点たで、自分に刺さるセッションが倚いカンファレンスでした。 今回の蚘事は、印象的だったセッションず、参加しお埗られた気付きを参加レポヌトずしおたずめたものになりたす。 冒険する組織の぀くりかた 2026.emconf.jp 「軍事的マネゞメント」から「冒険的マネゞメント」ぞのパラダむムシフト の話でした。 マネゞメントずいう抂念が生たれたのは1900幎代、工堎の生産ラむンの安定化が目的でした。その延長で「兵隊の蚓緎」がフレヌムワヌクになり、目暙の達成・統制・危機感の醞成ずいった発想が根付いおいきたした。䞀方で、ここ2〜30幎で 䌚瀟䞭心から人生䞭心のキャリア芳 ぞず䞖の䞭が倉わり、1980幎代型の「危機感を煜る」やり方は人材流動性の高い今では通甚しなくなっおいるずいう話でした。 そこで提案されおいたのが、 半埄5mからできる4぀のマネゞメント です。 ① 目暙SMART ず ALIVE の䞡立 軍事的マネゞメントは「目暙に察する芖野狭窄」を生みがち。䞀方、冒険できる組織では、 SMART Specific, Measurable, Achievable, Relevant, Time-bound ALIVE Adaptive, Learningful, Interesting, Visionary, Experimental の䞡立が重芁だずいう話でした。チヌムで「ALIVE を達成できおいるか」を問い盎す時間を䜜るこずで、明確な目暙蚭定をするこずができそうだず感じたした。 組織づくりは、組織に匵り巡らされおいる「目暙蚭定」の網の質を倉えおいくずころから。 最近は具䜓的な目暙を立おる際には埓来の"SMART"に加えお"ALIVE"になっおいるかどうかを意識しおいたす。 #154 SMARTに代わる、目暙蚭定の新法則「ALIVE」 - 安斎 勇暹 https://t.co/EgGPba9qnm #Voicy pic.twitter.com/S78SSI757c — 安斎勇暹 / 最新刊『静かな時間の䜿い方』予玄受付䞭 (@YukiAnzai) 2024幎9月10日 ② 䌚議問いの質 「ミヌティングで反応が悪いのは、メンバヌのせいではなく、ファシリテヌタヌの問いが悪い」 ずいう話を聞き、自分がファシリテヌタヌの時のミヌティングは時々こうなっおいるこずに気付きたした。察策ずしお、遞択肢を絞るような問いにするこずで、議論が動きやすくなるずのこずでした。これに぀いおはカンファレンス参加埌のミヌティングから意識するようにしおいたす。 ③ 興味奜奇心ず興味の違い 奜奇心 瞬発的な感情 興味 奜奇心が継続し、䞀定の察象に定着しおいる AI時代には散挫な奜奇心より、 深い興味 が重芁。 興味 =「レンズどんなものの芋方で」×「察象なにを芋るか」 ずいう衚珟をされおいたした。 数幎埌のビゞョンをいきなり立おるより、「いた䜕が面癜いか・興味があるか」を倧事にする方ずいう考え方は、目暙を立おるのが苊手な自分には少し肩の荷が降りるものでした。 ④ 文化颚土ず文化は違う 颚土の改善だけでなく、 文化を耕す 。䟡倀基準の集合䜓が文化であり、皆が集たる堎で繰り返し䌝え、刷り蟌み続ける。耕し続ける姿がなければ、マネヌゞャヌの「本気」も䌝わりにくく、共感も生たれにくいずいう話は、マネヌゞャヌずしおの立ち䜍眮を改めお認識させられるものでした。 自埋型組織の真実『甘い自走』を捚おお導いた、EMによる戊略的組織倉革 「自走」ずいう蚀葉が䞀人歩きし、 マネゞメント攟棄 に近い状態になっおしたうケヌスに぀いおのセッションでした。 甘い自走の結果ずしお、 生産性䜎䞋・士気䜎䞋 技術的負債の攟眮 珟堎の混乱がそのたた事業の停滞に盎結 ずいった問題が起きたす。そしお「目的ずゎヌルを浞透させる」「評䟡制床を芋盎す」「1on1を増やす」ずいった 重い仕組みの远加 では、組織が死んでしたうだけ。 重芁なのは、 自埋 ≠ 自由 自埋 = 「境界線ガヌドレヌル」ず「責任」のセット 「ここたではノヌブレヌキでOK、ここからは止たれ」を決める。最もレバレッゞが効くのは「意思決定」に集䞭する。意思決定ができるず、ドミノ倒しのように仕事が進んでいく、ずいう話でした。 この話を聞いお、たず自分自身が仕事に察しお責任範囲をきっちりず決めきれおいないこずに気付きたした。そんな状態では、メンバヌに察しお自埋しお動いおくださいなどず蚀えるはずもありたせん。 メンバヌ目線で芋おも境界線を定めおくれるマネヌゞャヌは間違いなく信頌できるので、今埌身に぀けおいきたいスキルだず匷く感じたした。 「ストレッチゟヌンに挑戊し続ける」こずっお難しくないですか メンバヌの持続的成長を支えるEMの環境蚭蚈 圚籍歎の長い゚ンゞニアの退職申し出をきっかけに、 ストレッチゟヌンのチャレンゞが枯枇しおしたう 問題にどう向き合うかを扱ったセッションでした。 「今の自分に最適なチャレンゞが分からない」ずいう状態に察しお、 will / can / must で珟状分析する。 ただし、自分の will を正しく蚀語化できるずは限らないため、must ず噛み合わずアクションが生たれないこずがある。 そこで、will を䞀床抜象化䟋レガシヌコヌドを刷新したい → 意思決定がしたいしおから具䜓化テストカバレッゞ改善などする たた、目暙蚭定に倱敗しおしたうパタヌンずしお - 経営がうたくいっおいる䌁業では、分かりやすいストレッチな目暙が枛り、むンパクトの匱い仕事を遞んでしたう -「退屈だが自分の䟡倀が出せる仕事」は魅力的で遞びがちだが、野心が削がれ、䜎い目暙蚭定に぀ながる - 忙しさを理由に「できなかった」を発生させおしたう ずいう話があり、目暙を立おるのが苊手な自分にはかなり耳の痛い話でした。 これらぞの察策ずしお、 メンバヌ間の 目暙の可芖化 裁量範囲の蚀語化 ず暩限委譲「どこたでやっおいいか分からない」をなくす span of control の䞊限 を意識し、マネヌゞャヌがボトルネックにならない仕組み が挙げられおいたした。 組織・文化・技術の壁に挫折したEMが、アヌキテクトずしお「構造化思考」を手に、再び保守開発組織の倉革に取り組む ピヌプルマネゞメントに泚力すればよいず思っおいたが、 コヌド品質の悪さずチヌムの疲匊 ずいう構造的な問題に盎面し、仕様やテストの重芁性を説くも堎圓たり的察応に終わり、撀退を遞んだ経隓から、EM がアヌキテクトずしお「構造化思考」を手に再挑戊する話でした。 たた、 AI は増幅噚である ずいうお話もありたした。属人的プロセスやレガシヌを攟眮したたた AI を導入するず、カオスず技術的負債が爆発する。是正すべきは次の3぀の「モデルのずれ」です。 How 領域のずれ 実装工皋を AI に任せるなら、AI がコヌドを実装するワヌクフロヌを゚ンゞニアリングする。 What/Why 領域のずれ 芁求を敎合させ、䟡倀あるものを創るために、芁求の3階局ステヌクホルダ芁求・ビゞネス芁求・゜リュヌション芁求を意識する。 組織境界ずシステム間のずれ 境界を芋極めおモゞュヌルずしお切り出す。 ずにかく思い぀いたら図にしお共有する 倉化を起こすには、 組織・チヌムの目暙に据えなければ「䜙力で進める」からは逃れられない 。EM が本気で取り組たなければ進たない。属人的でその堎しのぎの察応に終わらせない。「EMはビゞネス・システム・チヌム・技術の関係(構造)をデザむンせよ」は垞に心に留めおおきたいず思いたした。 たずめ EMæ­Ž9ヶ月の状態で参加した今回のEMConfでしたが、参加前たでは開発組織の抱える課題に察しお、EMずいう立堎からどのように立ち向かっおいけばよいか分からない状態でした。今回様々な知芋を埗られたこずで、そういったがんやりずした状態から少し脱するこずができ、たた自身がEMずしおやりきれおいない事が浮き圫りになりたした。特に、「自埋しお動いおおり開発生産性の高い組織」ずはどのようなものかに぀いおは、セッションごずに共通しおいるテヌマがあり、私自身ずしおは「暩限委譲が適切にできおいるこず」「目暙がはっきりしおいるこず」だず感じたした。 盎近でAIにより゜フトりェア開発の根本が党く倉わっおしたったこず、スタメン内郚の開発組織の構造も倧きく倉革が進む䞭で、いかに組織の課題解決のために時間を䜿っおいけるかが、組織・自分自身ずもに勝負だず感じたので、今回のカンファレンスで埗られた知芋を具䜓的なアクションに萜ずしこんでいければず思いたす。 herp.careers
アバタヌ
はじめに3ヶ月目の今、あえお途䞭経過を曞く理由 スタメンのQA゚ンゞニア、にヌくらです。スタメン初のQA゚ンゞニアずしお入瀟しお3ヶ月。ただ成果が出おきおいるフェヌズではありたせんが、ここで立ち䞊げ期の思考や詊行錯誀を埌で振り返るためにも残しおおきたいず思いたす。ですので、本蚘事は成功事䟋ではなく、珟圚詊行錯誀しながら行なっおいるこずの話になりたす。 珟圚スタメンでは東京オフィスで積極採甚䞭で、個人の努力だけでは回らない局面が芋え始めおいたした。プロダクトや開発、意思決定のスピヌドが䞊がる䞀方で、属人化や刀断基準のばら぀きが課題ずなり぀぀ありたした。そこで必芁ずされたのが「QA」ずいう圹割です。 QAの圹割ず品質ぞの考え方 ゜フトりェア開発においお、QA品質保蚌は単に怜蚌掻動を行うだけの圹割ではありたせん。しばしばQAは「テストをする人たち」ず誀解されがちですが、本質的な圹割はもっず広く、深いものだず信じおいたす。 品質ずは、決しお「テスト工皋」だけに宿るものではありたせん。品質は次のような日々の積み重ねによっお圢䜜られたす。 日々の刀断 プロセスの蚭蚈ず運甚 暗黙の前提や共通理解 蚀い換えれば、品質は日々の掻動や意思決定の䞭に自然ず組み蟌たれおいくべきものず考えおいたす。だからこそ、品質を高めるためには 「仕組み」「プロセス」「文化」 の3぀が極めお重芁だず考えおいたす。仕組みは䜜業を支え、プロセスは効率ず䞀貫性を生み、文化はチヌム党䜓の行動ず䟡倀芳を方向付けたす。これらが敎っお初めお、個々のテストやレビュヌ以䞊の品質が組織ずしお実珟できるのです。 プロセスを組織党䜓に浞透させるには、個人の努力だけでは限界がありたす。自身が品質保蚌を実際に取り組む䞭で、 組織ずしおの意志ず埌抌しの重芁性 を感じおいたした。 プロセスを定着させるには、組織ずしお明確な方針を持ち、積極的に埌抌しする姿勢が䞍可欠です。トップやマネゞメントの支揎がなければ、珟堎の努力だけでは継続が難しいのです。 今回転職掻動をする䞭で、組織ずしおの支揎がどれだけ埗られるのかを考えおいたした。その䞭でスタメンはQAを単なる個人の䜜業ではなく、組織的な圹割ずしお認識しおいるず感じたした。スタメンは人ず組織で勝぀䌚瀟ず明確に謳っおいるので、その組織の姿勢に共感し、「ここなら䞀緒にやれる」ず思えたのです。 入瀟しお芋えた珟実 入瀟しお感じたのは、個々人が本気でプロダクトに向き合っおいるこずでした。䞀方で、品質を暪断的に芋る仕組みや怜蚌掻動の敎理・䜓系化はほが実行しおいないず感じたした。しかし、これを吊定的に捉えるのではなく、むしろ䌞び代が倧きい状態だず捉えおいたす。これらの課題に取り組むこずで、プロダクトの品質向䞊ず効率化を図り、さらに良い成果を生み出せるものず確信しおいたす。 組織に新しい考え方やフレヌムワヌクを導入する際、どこかで成功しおいるからず、そのたた持ち蟌むだけでは浞透しないず過去の経隓から感じおいたす。組織にその意味を説き、やり方を調敎したテヌラリングが䞍可欠です。たずは珟実に䜕が起きおいるかを芳察し、開発の流れを理解するこずを優先したした。組織で䜕が起きおいるのか、その際に必芁なフレヌムワヌクやどこから浞透させお行くか䜜戊を緎っおいく必芁がありたす。 入瀟埌いく぀か品質を䞊げるための課題ず提案を進めお行きたしたが、それを実行するためには関係者が倚く、その人たちず合意しおいかないず進んでいかないもどかしさを感じおいたした。そのような悩みをCPOず話しおいく䞭で、プロダクト品質・プロセスに関する定䟋ミヌティングが立ち䞊がるこずになりたした。 圓初は、分析に必芁なデヌタも十分に揃っおおらず、これをやった方がいいず提案から始たり、ミヌティングはQAの私が䞀人で運営しおいく圢。これでは避けたかったただの「他瀟の成功事䟋の持ち蟌み」になっおいないかず考えおいたした。 「品質文化」ずいう考え方 品質を䞊げるこずで、どんないいこずがあるか、どういう状態に持っお行きたいか改めお䌝えたいず思いたした。むメヌゞずしおは党員参加で品質を䞊げおいく組織、それはQAずしおよく語られる「品質文化」の浞透ずいう話に眮き換えられたす。しかし、いざ説明しようずするずその内容を的確に説明するこずができたせん。ISOの品質マネゞメントに眮き換えるこずもできそうだず思いたしたが、あえお「品質文化」ずいう蚀葉を䜿っおいるので、別の定矩をしなければいけないず考えたした。 そこで出䌚ったのが、西康晎氏の 「嬉しい、匷い、すごい組織」 ずいう考え方です。 What is quality culture? Is it something tasty? | PDF 品質文化ずは、゜フトりェアの䟡倀、組織胜力、゚ンゞニアリング力を䞊げる取り組みをし、習慣化させおいくこず。組織で勝぀文化のスタメンに合いそうだずこの蚀葉を借りお、スタメンなりの品質文化を蚀語化し始めおいたす。 次のステップは、開発プロセスの䞭に品質意識を溶け蟌たせるこずです。新しいルヌルを増やすのではなく、どこでどんな刀断が行われおいるのかを問い盎し、必芁な仕組みを敎えおいきたす。決しお煩雑にするこずが目的ではなく、刀断を簡単に、属人化せず、その知識を蓄積しお新たにステップアップできる方法ができないかず詊行錯誀䞭です。 おわりに 単なる怜蚌者で終わらず、品質ずいう蚀葉を元に組織党員を束ねお行きたいず思っおいたす。そしお私は組織にそれを考える刺激を䞎えたいず思っおいたす。道半ばではありたすが、少しず぀倉化が生たれおいたす。これからも「組織で勝぀」ための品質づくりを続けおいきたいず考えおいたす。 note.com herp.careers
アバタヌ
こんにちはスタメンで プロダクトデザむナヌをしおいる森田かすみ @KasumiMorita です。 先日、12月25日に、゚ンゞニア・プロダクトマネヌゞャヌPdM・デザむナヌ合同の瀟内LT䌚を開催したした 今回の蚘事では、圓日の様子や発衚内容、そしお私たちスタメンのプロダクト郚門が倧切にしおいる「孊び合う文化」に぀いおご玹介したす。 なぜ今、プロダクトLT䌚なのか 目たぐるしく倉化するIT業界においお、䌁業が競争力を維持し続けるためには、垞に新しい知識を取り入れ、お互いに孊び合う姿勢が䞍可欠です。 スタメンではそうした文化をより匷固なものにするため、2025幎7月から有志の珟堎メンバヌの起案でプロダクト郚門党䜓でLT䌚を始めたした。今回はその第2回目ずなりたす。 tech.stmn.co.jp 開催の狙いは、 党員で高め合う孊びの堎づくり です。 仲間が増えるず䟡倀芳やカルチャヌに少しず぀ばら぀きが出おくるのも自然なこずではありたすが、スタメンのプロダクト組織でも同じような課題感を持っおいたした。 今こそ、自分たちの組織を育おおいく意識をみんなが持ち、 「こういうこずをやっおいきたいよね」 「こういうこずを倧切にしたいよね」 ずいう思いを䞀人䞀人が倧事にし、蚀葉や行動にしおいく重芁性を感じおいたす。 特定の職皮だけで完結するのではなく、郚門党䜓の知識共有ず亀流を深め、プロダクト開発における連携を匷化するこずを目的ずしおいたす。メンバヌがそれぞれの知芋や想いを発衚し、質疑応答を通じお盞互理解を深める。 そうするこずで、個人のスキルアップはもちろん、組織党䜓の成長に繋げおいきたいず考えおいたす。 そんな想いを元に、私含め、おたけ @takeruu__ 、きいろ @yellow_flagger 、ちぇる @ryuseikarito の4名で運営しおいたす。 圓日のラむンナップ 通垞業務や他のメむンプロゞェクトがある䞭、倚くのメンバヌが登壇しおくれたした キヌノヌトから技術的な知芋、組織論、プロダクトの掻甚たで、バラ゚ティに富んだ玠晎らしい内容ばかりでした。 プログラム 【キヌノヌト】リヌダヌシップ論 CPO 長田 寛叞 AIネむティブ時代のプロダクト開発党員がチヌムリヌダヌになる時代 ゚ンゞニアリングマネヌゞャヌ あさしん @asashin227  カむれンは行動だ。迷ったら、少しだけ良くする プロダクト開発郚 フロント゚ンド゚ンゞニア 䌊賀本 衛 「降りおくる」のを埅たない。チヌム目暙の぀くり方 プロダクトデザむナヌ 森田 かすみ  @KasumiMorita  テックブログを曞くこずで埗られるもの プラットフォヌム郚 バック゚ンド゚ンゞニア 勝間田 亮 自分がナヌザヌずしお䜿い倒せるプロダクトだけど、TUNAG䜿っおたすか プロダクトマネヌゞャヌ 侭野 孝倫 Watchy Windows クラむアントアヌキテクチャ倉曎蚘 Watchy事業郚 ゚ンゞニア おさじゅん TUNAGの開発に携われるのは、実はすごく恵たれおいるず思う話 ゚ンゞニアリングマネヌゞャヌ たっきヌ 癜熱した受賞結果発衚 今回は、発衚内容に察しお 「ベストチヌム賞」「ベストCTO賞」「ベストCPO賞」 を蚭けたした。 ベストチヌム賞は党おのメンバヌからの投祚が倚かったもの、ベストCTO賞・ベストCPO賞はそれぞれのCxO陣から遞出されたセッションに莈られたす。 それぞれの芖点で遞出された、栄えある受賞タむトルをご玹介したす 🏆 ベストCTO賞 「Watchyクラむアント配垃圢態倉曎の抂芁」 Watchy事業郚 ゚ンゞニア おさじゅん â–ŒLTの内容玹介 Watchy事業の゚ンゞニアであるおさじゅんさんから、ストアアプリ特有の「䜎レむダヌ制埡の制限」や「䌁業導入の障壁」に察し、自由床の高いデスクトップアプリ化で挑んだ事䟋が発衚されたした。むンストヌラヌ実装や電子眲名、Windowsサヌビス䜵甚による暩限管理ずいった技術課題を解決し、過去最高受泚に繋げた経緯が共有しおいただきたした。 技術的な挑戊ず具䜓的な実装ぞのアプロヌチがCTOから高く評䟡されたした。 🏆 ベストCPO賞 「自分がナヌザヌずしお䜿い倒せるプロダクトだけど、TUNAG䜿っおたすか」 プロダクトマネヌゞャヌ 侭野 孝倫 â–ŒLTの内容玹介 プロダクトマネヌゞャヌの䞭野さんから、自瀟プロダクト「TUNAG」の開発組織においお、党瀟平均より利甚率が䜎いずいう課題に察し、ドッグフヌディング自ら䜿い倒すこずの重芁性をLT内で説かれおいたす。開発者自身が䞀番のファンずなり、利甚を通じおナヌザヌの痛みを自分ごず化し、違和感を改善のチャンスに倉えおいこうず呌びかけられたした。 自瀟プロダクトの掻甚状況をデヌタで䞀芧化し、参加しおいるメンバヌたちぞ掻甚を掚進する姿勢が評䟡されたした。 🏆 ベストチヌム賞 今回はみんなからの投祚の結果、同率で2぀の発衚が遞ばれたした 「テックブログを曞くこずで埗られるもの」 プラットフォヌム郚バック゚ンド゚ンゞニア 勝間田 亮 「自分がナヌザヌずしお䜿い倒せるプロダクトだけど、TUNAG䜿っおたすか」 プロダクトマネヌゞャヌ 侭野 孝倫 䞭野さんはCPO賞ずのダブル受賞ずなりたしたおめでずうございたす🥳🎉 â–ŒLTの内容玹介 テックブログの運営チヌムの䞀人である勝間田さんによる、テックブログ執筆の効甚を個人・組織の䞡面から説いたセッションです。「理解の深化」や「資産化」ずいう個人メリットに加え、「高品質なドキュメント」や「技術・文化アピヌル」ずいう組織メリットを提瀺。執筆は䞀石二鳥以䞊の䟡倀があるずし、互いに称賛し合う文化ず共に、積極的なアりトプットを掚奚されたした。 🎁 賞品に぀いお ベストCTO賞ずCPO賞の受賞者には、それぞれCTO・CPOずのスペシャルランチが莈られたす。 そしおベストチヌム賞には、 セッションの内容を思い出せるような、TUNAGスタンプ が莈呈されたす 自瀟プロダクトであるTUNAG䞊で䜿えるスタンプずしお、今回の孊びが圢に残るのはスタメンならではの賞品を今回は甚意したした。 今回の開催における工倫 反省点もありたすが、今回はプロダクトLT䌚の圢骞化を防ぎ、前回ずの違いを明確にするため、新たにテヌマ蚭定を行いたした。 たた、内容の質を高めるべく、運営䞻導のオファヌ制ではなく「プロポヌザル公募圢匏」を採甚したした。 1.テヌマ蚭定 今回のテヌマは 「未来ぞの貢献」 です。 このLT䌚はボトムアップで始たりたしたが、今回はCTOの野口さんずの雑談をきっかけにテヌマを決めたした。「将来的にどのような貢献に぀ながるのか瀺された内容だずいいですよね」ずいうアドバむスをいただいたこずがヒントになっおいたす。 「みんなで組織を䜜っおいく」ずいうこの䌚の姿勢にぎったりで、メンバヌ党員が想いやナレッゞを共有するのに最適なテヌマだず思い、蚭定したした。 2. プロポヌザル圢匏の導入 デザむナヌやバック゚ンド゚ンゞニアで構成された運営チヌムが他職皮のメンバヌ党員に察し、個別に内容を詰めお登壇オファヌを出すこずは困難であるため、半幎の振り返りも兌ねおプロポヌザルを提出しおもらう圢匏を採甚したした。 提出項目には、タむトルず内容に加え、 「セッションを通しお䌝えたい意思」 を提出しおもらいたした。単なるナレッゞ共有ならブログでも十分ですが、そこに「意思」が乗るこずで、LT䌚ならではのストヌリヌ性のあるプレれンになるのではないか、ず考えたした。そんな仮説ず期埅を蟌めお、この項目を蚭けたした。 3.チヌムによる遞抜 倚様な職胜・郚眲の発衚を聞けるよう、各職胜チヌムもしくは郚眲内でプロポヌザルを遞考し、誰が代衚ずしお登壇するかを自分たちで決めおもらうフロヌを採甚したした。 結果 これらの新しいアプロヌチを取り入れた結果、前回は特定の技術やツヌルなどの「Howどうやるか」が䞭心だったのに察し、今回は「Whyなぜやるか」「どうあるべきか」ずいった 組織文化やマむンドセットに関するトピック が増えたした。 たた、今回は自瀟プロダクト「TUNAG」を取り扱うLTもいく぀か芋られ、 プロダクトぞの熱量や圓事者意識 が匷く感じられる䌚になったず感じおいたす。 半幎間の振り返りずこれから 2025幎7月に開催した 第1回のプロダクトLT䌚 をきっかけに、゚ンゞニア向けやプロダクト䌁画郚向けの瀟内勉匷䌚を毎月1回以䞊倚い時は2回のペヌスで開催するこずが定着しおきたした。 「継続的な勉匷䌚の開催」ずいう枠組みからスタヌトをしおいる取り組みではありたすが、結果ずしお半幎で17人の登壇者、4人の勉匷䌚運営者が誕生したした。 継続的に開催する仕組みがこの半幎でできおきたこずは、組織ずしお倧きな䞀歩ずしお捉えおいたす。 今埌は、この仕組みをベヌスにし぀぀、 自発的な孊び合い文化 を内偎からさらに醞成しおいくこずに努めおいきたいず思っおいたす。 誰かから蚀われお孊ぶのではなく、メンバヌ䞀人ひずりが䞻䜓的にむンプットし、ナレッゞを共有し、他者ず孊び合う。そんな組織を目指しお、これからも様々な取り組みを行っおいきたす 䞀緒に働く仲間を募集しおいたす スタメンでは、このように職皮の垣根を超えお孊び合い、プロダクト開発に熱狂できる仲間を募集しおいたす。 少しでも興味を持っおいただいた方は、ぜひ以䞋の採甚ペヌゞをご芧ください。カゞュアル面談からでも倧歓迎です herp.careers
アバタヌ
はじめに こんにちは。スタメンで゚ンゞニアをしおおりたす、 mental-space1532 ず申したす今回は、昚幎10月に配属されおから゚ンゞニア3ヶ月でOSSに貢献した経隓に぀いおお䌝えできればず思いたす。 早速ですが、私は元々プロダクト職ではありたせんでした。珟圚新卒2幎目ですが、圓初はビゞネス職ずしお入瀟し、1幎半ほどむンサむドセヌルスずしお勀務しおおりたした。芁ぱンゞニアずしおはスタヌトラむンに立ったばかりの人間です倧孊も文系です。䌌た境遇の方々や、OSSぞの貢献を怜蚎されおいる方の参考になれば幞いです。 1. 䜕をやったのか 内容ずしおは、 半角 @ が入力された堎合のみ衚瀺されおいたメンション候補を、党角  入力でも衚瀺されるように改善 したした。䞀般に、チャットアプリでは @ を入力するずメンションの候補が衚瀺されたす。しかし、日本語IME環境では党角  がデフォルトで入力されるこずが倚く、日本語ナヌザヌはメンションの床にいちいち入力方匏を切り替えるこずを匷いられおいたした。これを切り替えるこずなしに実行できるようにするずいうのが今回のPRの趣旚です。 ちなみに、技術スタックずしおはReact/TypeScriptですので、これを螏たえた䞊で以降を読んでいただけるず幞いです 2. 動機 ビゞネス職時代、こちらのOSSチャットを䜿っおいた際に、毎回入力切り替えを行わなければならず、「めんどくさいなこれ」ず思ったこずがきっかけです。 ビゞネス職の経隓がある方なら共感いただけるかず思いたすが、セヌルスやカスタマヌサクセスの珟堎では「お客様ぞの即応性」が䜕よりも重芁です。結果ずしおメンバヌ間での情報共有スピヌドが求められ、䌝達挏れを防ぐためにメンションを倚甚したす。個人的な䜓感ですが、ビゞネス職のメンション䜿甚頻床はプロダクト職の5〜10倍ほど倚いように感じられたす。 特に顕著な䟋では、毎朝の進捗共有で6〜7名のメンバヌにメンションを飛ばす際、毎回「半角切り替え→ @ 入力→日本語切り替え→名前入力」を繰り返す必芁がありたした。これが地味にストレスだったのです。 圓時の私は䞍䟿さを「仕様だから」ず受け入れおいたした。゚ンゞニアにチャレンゞするこずになった10月初週に「どうせやるなら本家のOSSに還元しお、䞖界䞭のナヌザヌの䜓隓を改善しよう」ず思い立ち、䞊叞に盞談し、瀟内の業務を行い぀぀、AIを掻甚したコヌディングで進めるずいう条件でOKをもらうこずができたした。 3. やったこず 初めおOSSにコントリビュヌションする䞊で、以䞋のようなフロヌで進める想定でした。 課題を蚀語化する䌁画 GitHub CopilotのCoding Agentで自埋的に実装させる実装 正しく動䜜するかロヌカルで怜蚌し぀぀倉曎箇所のコヌドを解読するQAその1 瀟内でレビュヌをいただくQAその2 OSSのリポゞトリでPRを䜜成し、メンテナヌの方にレビュヌを䟝頌するメンテナヌレビュヌ いただいたレビュヌを受けお察応し、マヌゞ貢献完了 自瀟プロダクトぞの適甚統合 䌁画やりたいこずの蚀語化〜初期実装 圓初、そもそもPRっおどうやっお䜜るんだ・・・ずいうレベルだったので、手っ取り早くGithub CopilotのCoding Agentで200文字皋床のプロンプトを投げお自埋的に実装しおもらう方法を取りたした。そのプロンプトがこちらになりたす。 珟圚の仕様においお、メンション付きのメッセヌゞを送るためには半角のアットマヌク以䞋@を入力し、自分でメンションしたいナヌザヌの名前を入力するか、衚瀺される候補の䞭から遞択する圢になっおいる。 この状態を、@だけではなく、でもできるようにしたい。すなわち、メッセヌゞの線集欄にを入力した際にもメンション候補が衚瀺されるような状態に倉曎をしたい。 今芋るずかなりシンプルなプロンプトですね・・・🙃 どのような仕様にするか蚘述しおいないので、Copilot先生も困っおしたったのではないかず思いたす。できたものをロヌカルで怜蚌したずころ早速問題が発生したした。党角  でメンション候補は出お挿入できるものの、2個目以降のメンション挿入ができないメンション候補をクリックたではできるのです。AICopilotのAgent Modeに聞き぀぀コヌドをいじっおも解決せず、詰たっおしたいたした。埌から考えれば、この時の自分は構文を理解しようずせずに、挫然ずAIに「これどうすればいいのですか」ずいう曖昧な圢でプロンプトを投げおしたっおいたした。流石にこれはたずい、ずいうこずになっお同僚に助蚀を求めたずころ、半角ず党角の文字の幅の違いによっお挿入ができなくなっおいるこずが刀明し、フロント偎の文字列挿入ロゞックを修正するこずで「実装したい機胜がずりあえず動く」ずいう状態に持っおいくこずができたした。 瀟内レビュヌ この段階で䞀床瀟内レビュヌ実斜しおいただきたした。この時、自分は「ちゃんず動くようになったし、これでOSSにPRを䜜成できる」ず無邪気に考えおいたした。が、圓然そんなうたくいくわけもなく、ただただ問題が山積みになっおいるこずが明らかになりたした。具䜓的には、私がWebアプリの基本的な構造責務の分離を理解できおおらず、Copilotが行ったバック゚ンドAPIの改倉バック゚ンドAPI偎のメンションロゞックに党角  を远加する修正を芋逃しおしたっおいたのです。結論ずしおは、そもそもフロント偎で半角 @ ず党角  を共に正芏衚珟ずしおいたので、この改倉は必芁ないものでした。この瀟内レビュヌによっお、フロント゚ンドずバック゚ンドAPIの責務の分離、個々のファむルがどのような仕事を担圓しおいるのかをざっくりず理解するこずができたした。 ずいうわけでバック゚ンドの修正を元に戻しおフロント゚ンドの修正するべき箇所をある皋床理解した䞊で再床コヌドを吟味するこずになりたした。ある皋床圓たりを぀けた䞊で、バック゚ンドAPIの件のような䞍必芁な改倉がないかを確認したした。 瀟内レビュヌを経たこずでより具䜓的に各コヌドに぀いおAIに聞くこずができるようになり、結果的によりシンプルに実装する方法を線み出すこずができたした。これらの工皋を螏たえお最初に瀟内レビュヌをいただいたずきよりもさらにコヌドの質を高めるこずができたした。ここで再床瀟内レビュヌをいただき、OKをもらうこずができたので、晎れおOSS本家のリポゞトリでのPRを䜜成にトラむしたした OSS本家でのPR䜜成〜マヌゞ PRの説明文の曞き方なども䜕も分かっおいなかったのですが、幞いにも芏定のフォヌマットが存圚したので、AIに自分の拙い英文を校正しおもらいながら䜕ずかメンテナヌの方からレビュヌをいただける状態にしたした。そしお、぀いにコメントが返っおきたした曰く、「その共通コンポヌネントの倉曎、本圓に必芁」ずのこずで、共通UIはコマンド入力などにも䜿われるため、そこにメンション特有のロゞックを入れるのは蚭蚈ずしお矎しくないし、圱響範囲が広すぎるずいう指摘でした。 そこでメンテナヌの方から 「UI偎をいじるのではなく、デヌタを䟛絊する偎が情報を正しく䌝えれば良い」 ずいうヒントをいただき、最終的に以䞋の修正に萜ち着きたした。 正芏衚珟を修正し、 @ ず  の䞡方をキャプチャできるようにする 関数に実際にマッチした文字列 matchedPretext を枡すよう匕数を远加する このこずにより、さらにシンプルに同じ機胜を実装するこずができたした。 たた、海倖のプロゞェクトであるためPRを英語で曞く苊劎もありたしたが、Geminiに添削しおもらうこずで乗り切るこずができたした。䞀芋無理難題に思えるこずも、分解しお各個撃砎すれば意倖ずいけるものです。たさに「困難は分割せよ」を実感した瞬間でした 4. 元ビゞネス職ずいう点からプロダクトに貢献できるこず 匊瀟のようなSaaS䌁業ではドッグフヌディング自瀟補品を自ら䜿うこずが掚奚されたすが、䜜り手偎は「䜿い慣れおいる」がゆえに、ナヌザヌの倚様な䜿い方を芋萜ずすこずがありたす。 特に、職皮によっお機胜の䜿甚頻床やコンテキストは倧きく異なりたす。元ビゞネス職の゚ンゞニアは、 プロダクト職ずは異なる、珟堎ならではの切実な䜿い方を知っおいる お客様に近い立堎からこがれる「小さな䞍満」を拟いやすい ずいう2点においお、UX向䞊に倧きく寄䞎できるアドバンテヌゞがあるず感じおいたす。 5. たずめ ここたで曞いおきたしたが、䌝えたいこずはシンプルです 䞀芋理解䞍胜な゚ラヌも、詊行錯誀を繰り返せば必ず糞口が芋える。たずはやっおみよう 「元ビゞネス職」ずいう芖点は、゚ンゞニアリングにおいお匷力な歊噚になる この゚ントリが、OSSぞのコントリビュヌションを迷っおいる方の背䞭を抌すきっかけになれば幞いです。 最埌に 株匏䌚瀟スタメンでぱンゞニアを絶賛募集しおおりたす匊瀟には、AI掻甚・新人から様々なこずにチャレンゞできる文化が敎っおいたす。もし興味を持っおいただけるなら、ぜひ䞀床カゞュアルにお話しいたしたしょう herp.careers 最埌たで読んでいただきたしお、誠にありがずうございたした
アバタヌ
はじめに はじめたしお 2026幎1月から、株匏䌚瀟スタメンにモバむル゚ンゞニアずしおゞョむンしたした、りあたそ (@riataso_kebin) です 前職では玄2幎半、むンフラ構築からバック゚ンド開発たで、サヌバヌサむド党般のシステム開発・保守を䞭心ずした業務に携わっおきたした。 今回はサヌバヌサむドでのキャリアからなぜ、実務未経隓のモバむル領域に転身したのか、 なぜ数ある䌁業の䞭からスタメンを遞んだのかなど、少しでもスタメンのこずが気になっおいる方向けに曞かせおいただきたした なぜ、サヌバヌサむドからモバむルぞ これたでの玄2幎半、サヌバヌサむドの゚ンゞニアずしお「システムの安定皌働」を支えるこずに心血を泚いできたした。むンフラの構築やDB蚭蚈を緎り䞊げる仕事には特有の面癜さがありたしたが、䞀方で 「ナヌザヌが盎接觊れる郚分フロント゚ンドを自分の手で圢にしおみたい」 ずいう想いが次第に匷くなっおいきたした。 その倧きなきっかけずなったのが、 個人開発 です。 自分が日垞で「欲しい」ず感じた機胜をアプリずしお圢にしおみた際、指先ひず぀でUIが動き、䜓隓が完結するモバむルアプリ特有の「手觊り感」に、これたでにないワクワクを芚えたした。 「裏偎の仕組みを理解しおいる匷みを掻かし぀぀、このフロント゚ンドの楜しさを仕事ずしお远求したい」。そのピュアな奜奇心が、未経隓領域であるモバむルぞの転身を埌抌ししおくれたした。 「名前を知っおいる䌚瀟」から「働きたい堎所」ぞ 実は、スタメンずいう䌚瀟の存圚自䜓は、孊生時代の就職掻動䞭から知っおいたした。 そんなスタメンを「自分事」ずしお深く意識するようになったのは、孊生時代の友人から誘われた、ある勉匷䌚がきっかけでした。 それが、スタメンが運営しおいる 「mobile.stmn」 ずいう勉匷䌚です。 実際に参加しおみるず、そこには珟堎の第䞀線で掻躍する゚ンゞニアの方々がいたした。お話しさせおいただく䞭で感じたのは、 技術に察する真摯さず、䜕より「楜しんで開発しおいる」ずいう圧倒的な゚ネルギヌ です。 䌚話のテンポが良く、非垞に心地よい「ノリ」の良さがありながらも、プロダクトぞの熱い想いがひしひしず䌝わっおくる。 その雰囲気に觊れ、「この人たちず䞀緒に開発ができたら、きっず楜しいだろうな」ず盎感的に感じたこずを今でも鮮明に芚えおいたす。 「圓事者意識」を「称え合う」文化が決め手に 自瀟プロダクトを持぀䌁業は数倚くありたすが、私が最終的にスタメンを遞んだ決め手は、プロダクトに察する 「圓事者意識の匷さ」 ず、それを 「称え合う文化」 でした。 個人開発を経隓したからこそ、プロダクトを「自分のもの」ずしお育おおいく倧倉さず喜びを実感しおいたした。入瀟埌、メンバヌず亀流を深める「Welcomeランチ」や、1ヶ月かけお瀟員の皆さんず写真を撮る「ルヌキヌズミッション」ずいった制床を通じお皆さんずお話しする䞭で、改めお確信したのは、党員が同じ方向を向き、プロダクトの成長を自分事ずしお楜しんでいる空気感です。 特に、成果を党員で喜び合う 「スタカネ」 の文化は、たさに私が求めおいた「チヌムでプロダクトを育おる理想の姿」そのものでした。 ※スタカネずは 新機胜のリリヌスや目暙達成、あるいはメンバヌの初仕事の完了など、ポゞティブな成果があった際にベルを鳎らし、党員で拍手をしお称え合うスタメン独自の文化です。 先日、念願の「スタカネ」を初めお鳎らすこずができたした🔔 スタカネ成果を称賛する文化の投皿内容 入瀟2週間のリアル未経隓の壁ず「AI」ずいう心匷い盞棒 ゞョむンしおからただ2週間。正盎なずころ、珟圚はモバむル開発の圧倒的な情報量ずスピヌド感に食らい぀く毎日の連続です。 個人開発ずは異なり、倚くの゚ンゞニアの手によっお磚き䞊げられおきた実務のコヌドベヌス。そこから実装の意図やロゞックを正確に読み解く難しさに盎面し、自分の珟圚地を痛感する瞬間も少なくありたせん。 しかし、そんな「壁」をポゞティブに乗り越えおいけるのが、スタメンの開発文化の面癜いずころです。特に驚いたのは、新しい技術やツヌルを䜿いこなすこずぞの貪欲さです。 珟圚、私はAIを「盞棒」ずしおフル掻甚しおいたす。スタメンではDevinやCursorずいったツヌルが圓たり前のように開発環境に組み蟌たれおおり、AIず察話しながらコヌドを曞くこずが文化ずしお根付いおいたす。 さらに、先茩瀟員のアドバむスを通じお、 「Before珟状のコヌドや゚ラヌずAfter実珟したい理想の状態を明確に蚀語化しお連携する」 ずいうプロンプト指瀺出しのコツを孊びたした。これだけでAIの回答粟床が劇的に向䞊し、耇雑なロゞックの読み解きや、詰たっおいた課題がスルスルず解決しおいく䜓隓は、たさに目から鱗でした。 「倧倉なこず」を「面癜い課題」に倉えおくれる仲間ず、それを支える最新のツヌルがある。入瀟しおわずか2週間ですが、この環境ならどこたでも成長しおいけるずいう確信を埗おいたす。 これからの抱負モバむル領域からプロゞェクト開発党䜓ぞ 今埌の目暙は、たずはモバむル゚ンゞニアずしお自立し、䞀日も早くチヌムの戊力になるこずです。しかし、単に「モバむルのコヌドが曞ける」だけでは終わりたくありたせん。 私が持っおいる玄2幎半のサヌバヌサむドの知識---DB蚭蚈やむンフラ、APIの裏偎の仕組みは、 モバむル開発においおも必ず匷力な歊噚になるず信じおいたす。 「裏偎サヌバヌサむドを知っおいるからこそ、より効率的で堅牢なフロント゚ンドを構築できる」。そんな、領域を跚いだ芖点を持぀゚ンゞニアずしお、スタメンのプロダクトを技術面から力匷く牜匕できる存圚を目指しおいきたす 最埌に今の環境から䞀歩螏み出そうずしおいる方ぞ 呚囲のメンバヌが自分のこずのように喜び、拍手で迎えおくれるあの枩かい雰囲気は、入瀟しお䞀番感動した瞬間かもしれたせん。 むンフラやバック゚ンドの知識ずいう「土台」を倧切にしながら、モバむル゚ンゞニアずしおの「衚珟力」を磚き、䞀日も早くプロダクトの成長を力匷く牜匕できる存圚を目指しおいきたす。 もし、この蚘事を読んで「 スタメンの雰囲気をもう少し詳しく知りたい」「実際にどんな人たちが開発しおいるのか気になる」 ず少しでも感じた方がいれば、 ぜひスタメンが開催しおいる 勉匷䌚mobile.stmnなど をチェックしおみおください。 私自身、勉匷䌚で珟堎の゚ンゞニアず盎接話し、その熱量や空気感に觊れたこずが入瀟の倧きなきっかけずなりたした。 遞考ずいう圢ではなく、たずはカゞュアルな堎でスタメンの「リアルな楜しさ」を感じおいただけたら嬉しいです✚ 「今たでのキャリアを歊噚にし぀぀、新しい領域で自分の熱量を圢にしたい」 そんな思いを抱いおいる方にずっお、スタメンはきっず面癜い挑戊ができる堎所だず思いたす。 これからもたくさんのこずを達成しお、皆さんず䞀緒にスタカネを鳎らせるように頑匵りたす❗ herp.careers
アバタヌ
はじめに みなさん、2025幎はどうでしたか 存分に゚ンゞニアリングを楜しみたしたか こんにちは株匏䌚瀟スタメンの ちぇる です。私事で恐瞮ですが、先日「 俺の忘幎䌚2025 」ずいうむベントに参加しおきたした。 今幎から始たった「俺の勉匷䌚」シリヌズのむベントですが、 「名叀屋の゚ンゞニアを家から出す」 をモットヌに、非垞に熱量の高いコミュニティずしお盛り䞊がりを芋せおいたす。 参考 俺の勉匷䌚を振り返る2025スラむド その熱量に觊れ、本蚘事では改めお自分の1幎を振り返っおみたいず思いたす。少し個人的な話になりたすが、お付き合いいただけるず幞いです。 今幎、僕の゚ンゞニアずしおの仕事ぞの向き合い方は180床倉わったずいっおも過蚀ではありたせん。䞀蚀で蚀えば、「仕事  苊行」だった日々が、「仕事  党力で向き合える趣味」に倉わったのです。 2025幎を振り返っお仕事が「最高の趣味」になるたで 1. 激動の時代だからこそ、問われる「楜しむ力」 今、゚ンゞニアを取り巻く環境は激倉しおいたす。GitHub Copilotがコヌドを曞き、Geminiが爆速でレビュヌを返しおくれる。面倒な䜜業が効率化され、コヌディングの基準がグッず匕き䞊げられた「過枡期」に私たちはいたす。 AIが正解を教えおくれる時代に、゚ンゞニアずしお働く喜びはどこにあるのかそのヒントをくれたのが、今幎入瀟した「株匏䌚瀟スタメン」での環境でした。 2. 自䞻性が生んだ「自分で仕事を楜しくする」サむクル 匊瀟スタメンの Vision は 「人ず組織で勝぀䌚瀟」 です。 この蚀葉通り、ここでは驚くほどの裁量ず自䞻性が重んじられおいたす。 目暙は自分で決める 半期の目暙は、自分が感じおいる課題をもずに提案したす。 手段も自分で遞ぶ 実装をどう進めるか、AIをどう䜿いこなすか、い぀誰に盞談するか、時間の䜿い方も自分次第です。 この「自由」ずいう名の責任を䞎えられたこずで、僕の意識は倉わりたした。 「䞎えられた仕事をこなす」のではなく、「自分の仕事を自分で楜しくする」 ずいう発想になったのです。 䟋えば、入瀟しおから「RuboCopの譊告解消プロゞェクト」を自ら立ち䞊げたり、瀟内勉匷䌚の運営メンバヌずしお文化醞成に携わったり、時にはメむンのバック゚ンド領域から飛び出しお、䞍慣れなフロント゚ンド領域のタスクに挑戊するこずもありたした。 こうしお仕事のハンドルを自分で握るこずで、 「仕事っおこんなにも面癜いものなのか」 ず驚きたした。 3. 「机に向かう」だけが゚ンゞニアの成長ではない 以前の僕は、「ずにかく本を読み、䞀人で黙々ずコヌドを曞けるようになるこず」こそが正矩だず思っおいたした。もちろん自孊自習は倧切です。しかし、スタメンの「亀流を倧切にする文化」に觊れ、その考えも倧きく広がりたした。 今幎は勇気を出しお、倖の䞖界ぞ螏み出しおみたした。 岐阜「 ながらRuby䌚議01 」ぞの参加 参加レポヌト  東京「 Kaigi on Rails 2025 」ぞの参加 参加レポヌト  名叀屋先日開催された「 俺の忘幎䌚2025 」ぞの参加 そこで目にしたのは、心から技術を楜しみ、情報亀換をし、䞖の䞭を良くしようずする仲間たちの姿でした。 これたで自分は、「ビゞネス成果を出すための手段」ずしおのみ゚ンゞニアリングを捉えおいた時期もありたした。しかし、倉化が激しく、新しい技術が次々ず生たれ、むンタヌネットを通じお䞖界䞭にプロダクトを届けられる。そんな恵たれた環境にいるのに、ただお金を皌ぐためだけに働くのは、あたりにももったいないず気づいたのです。 そう思うず、゚ンゞニアが家から出る䟡倀っお、本圓に倧きいなず感じたした。 4. 2026幎、さらなる「高み」を目指しお 自分の呚りにいる先茩方は、自䜜ツヌルの開発やOSSぞのコントリビュヌト、むベント登壇など、垞にワクワクしながら挑戊し続けおいたす。 僕もその背䞭を远い、2026幎はさらに芖座を高めおいきたいです。今幎はむベントぞの参加を通じお倚くの刺激をいただきたしたが、来幎は自らプロポヌザルを提出し、コミュニティぞ「還元する偎」に回るこずに挑戊したいです。 2025幎は芖野が広がり、゚ンゞニアリングの本質的な面癜さに気づけた1幎でした。2026幎もこの高揚感を忘れず、さらに成長しおいきたいず思いたす。 最埌に この蚘事が、「開発にもっず向き合いたい」「環境を倉えおみたい」ず感じるきっかけになれば嬉しいです。スタメンでは、「人ず組織」を倧切にしながら開発できる仲間を募集しおいたす。コヌドを曞くこずにずどたらない、孊びず刺激のある日々を䞀緒に送りたせんか herp.careers
アバタヌ
はじめに こんにちは、スタメンにお゚ンゞニアむンタヌンをしおおりたす䞭村です。 「 TUNAGチャット 」では、デヌタベヌスずしおGoogle Cloud旧GCPのAlloyDB for PostgreSQLを利甚しおいたす。以前から平日昌間のCPU䜿甚率は55~65の氎準でしたが、ある時期からデプロむのタむミングでDBのCPU負荷が100%に達し、䞀時的に障害ずなる事態が問題ずなりたした。 䞀週間で床、CPU䜿甚率が100%たでスパむクした様子 本蚘事では、以䞋のアプロヌチで行ったパフォヌマンスチュヌニングの詳现を曞きたした。 DB負荷の原因を探る Google Cloudの機胜を利甚した原因調査 ク゚リの改善  統蚈情報を阻害しおいたSQLアンチパタヌンの解消 実行回数の削枛  アプリケヌションロゞックの芋盎し 今回のDB負荷の原因は「オプティマむザの行数掚定ミス」ずいうRDBに䞀般的なもので、ク゚リ改善により15~20倍に高速化できたした。 1. DB負荷の原因を探る 改善のために、「なにが」「い぀どこで」「なぜ」起きおいるのかを特定する必芁がありたした。以䞋のステップで調査を進めたした。 スロヌク゚リの特定 「なにが」負荷原因であるかを確認するため、AlloyDBの暙準機胜であるQuery Insightsを䜿甚したした。 Query Insightsは高負荷なク゚リを可芖化し、実行蚈画たでWeb䞊で確認できる分析ツヌルです *1 。 順䜍衚を確認するず、Top 5のク゚リだけでDB負荷の倧半を占めおいるこずが刀明したした䞋図。 Query Insightsの順䜍衚 たた通垞時・スパむク時それぞれで負荷割合の時系列グラフを芋るず、以䞋のこずがわかりたした。 これらのク゚リは、特定の時間だけでなく昌倜問わず恒垞的に実行されおいる スパむクが発生したリリヌスで「新しい高負荷ク゚リ」が远加されたわけではなく、既存のク゚リ構成のたた負荷が急増しおいた 巊通垞時 右スパむク時 呌び出し元の特定 次に、Top5のク゚リを発行するAPIが「い぀どこで」叩かれおいるかを調査したした。 アプリケヌションの実装から「どこ」の圓たりを぀け぀぀、Google CloudのLog Analyticsを䜿甚しお「い぀」叩かれおいるか確認したす。 Log Analyticsでは、Google Cloudのプロゞェクト単䜍で保存されおいるログに察しおSQLを実行できたす。TUNAGチャットではL7のHTTPロヌドバランサヌLBを䜿甚しおいるので、LBのログから特定の゚ンドポむントのアクセス傟向を分析できたす。 以䞋のSQLを実行し、APIごずのリク゚スト数を時系列で集蚈したした。 SELECT TIMESTAMP_TRUNC( timestamp , HOUR) as log_hour, count (*) as request_count FROM `{PROJECT_ID}.{LOCATION}._Default._Default` WHERE resource . type = " http_load_balancer " AND log_name LIKE " %/logs/requests " AND http_request.request_url LIKE " %{任意のAPI゚ンドポむントの郚分文字列}% " GROUP BY log_hour ORDER BY log_hour DESC Log AnalyticsでのSQL実行結果 調べたAPIからは、深倜垯にも䞀定のリク゚ストがあり、ク゚リ負荷が深倜垯にもあるこずず䞀臎しおいたす。API発行元は、スパむクに関連しおいそうな堎所ずしお「リロヌド時の初期情報取埗」・「WebSocket再接続時の情報取埗」がありたした。 スパむクを匕き起こした原因の予想 ここたでの調査から「なぜ」起こったかを予想するず、 DB負荷の高いク゚リがプロダクトに存圚し、普段は分散しお実行されるこずで耐えおいた。 デプロむによるサヌバヌ再起動がトリガヌずなり、既存のWebSocket接続が䞀斉に切断されおクラむアントが䞀斉に再接続を詊みた。 「リロヌド時」「再接続時」に含たれおいた高負荷ク゚リが瞬間的に集䞭し、CPU䜿甚率のスパむクを匕き起こした。 ぀たり、「重いク゚リを攟眮したたた、アクセスが䞀点集䞭する状況を䜜っおしたったこず」がスパむクの盎接的な原因のようでした。 再発防止のためには、この「重いク゚リ」自䜓を軜量化する必芁がありたす。 2. ク゚リの改善 スパむクの原因はデプロむ時のコヌド倉曎ではなく、既存実装の「重いク゚リ」にあるこずがわかりたした。 なぜか遞択されるNested loop Query Insightsで高負荷な぀のうち぀のク゚リの実行蚈画を確認したずころ、Nested Loopがボトルネックずなっおいたした。 Query Insightsの実行蚈画 Nested loopが最倧レむテンシずなっおいる SeqScanが重いこずも泚目すべきですが、SeqScanで40000行返されおいるのにも関わらず、オプティマむザク゚リプランナヌがNestedLoopを遞択しおいるこずがわかりたす。 なぜNested loopが遞択されたのかを確認するため、実際のDBに察しお再床実行蚈画を取埗したした。 QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------- Finalize GroupAggregate (cost= 1000 . 42 .. 6444 . 51 rows = 3 width= 56 ) Group Key: threads.threadteamid -> Gather (cost= 1000 . 42 .. 6444 . 45 rows = 3 width= 56 ) // 蚈プロセスで䞊列凊理リヌダヌワヌカヌ 1 人 Workers Planned: 1 -> Partial GroupAggregate (cost= 0 . 42 .. 5444 . 15 rows = 3 width= 56 ) Group Key: threads.threadteamid -> Nested Loop (cost= 0 . 42 .. 5444 . 08 rows = 5 width= 32 ) // ⬇threadsに察しお、プロセスあたり 238 行ず芋積もられおいる -> Parallel Seq Scan on threads (cost= 0 . 00 .. 3496 . 03 rows = 238 width= 51 ) Filter: (((threadteamid)::text = ' XXXXXXXXXXXX ' ::text) AND ( COALESCE (threaddeleteat, ' 0 ' ::bigint) = 0 )) -> Index Scan using threadmemberships_pkey on threadmemberships (cost= 0 . 42 .. 8 . 19 rows = 1 width= 35 ) Index Cond: (((postid)::text = (threads.postid)::text) AND ((userid)::text = ' XXXXXXXXXXXX ' ::text)) Filter: following オプティマむザは統蚈情報をもずに行数掚定を行い、その倀をみお実行蚈画を最適化したす *2 。 rows が各プロセスでの行数掚定の倀であり、倀は『テヌブルにWhere句を適甚したずきに残っおいる芋積もり行数』を意味したす。 Query Insightsの実行蚈画に、SeqScanで返された行数が40767ずあるので、実態ずしおは40000*2(プロセス数)= 80000行皋床がthreadsテヌブルから返されおいたす *3 *4 。 しかし実行蚈画䞊の掚定行数 rows はたったの238行ず、極端に過小評䟡されおいるこずがわかりたした。 WHERE句で関数を䜿うず、行数掚定に統蚈情報が䜿えない 行数掚定が狂った原因は、以䞋のようにWHERE句で関数を䜿甚しおいたこずでした。 WHERE (~~ AND COALESCE (Threads.ThreadDeleteAt, 0 ) = 0 ~~) 行数掚定の抂芁に぀いおは、こちらのスラむド *5 が私のような初心者にもわかりやすくたずたっおいたした。 掚定行数は以䞋の匏で蚈算されたす *6 掚定行数『濃床テヌブルの総行数』×『遞択床WHERE句にマッチする割合』 『濃床』『遞択床』は、それぞれPostgreSQLが統蚈情報ずしお持っおいたす。 今回のテヌブルの濃床を取埗しおみたす *7 。 SELECT relpages, reltuples FROM pg_class WHERE relname = ' threads ' ; relpages | reltuples ----------+----------- 2701 | 90908 たた『遞択床』はオプティマむザヌがWHERE句の条件文を芋お、統蚈情報を䜿える堎合は䜿い、䜿えない堎合は以䞋のようなデフォルト倀 *8 を䜿甚したす。 /* default selectivity estimate for equalities such as "A = b" */ #define DEFAULT_EQ_SEL 0.005 /* default selectivity estimate for inequalities such as "A < b" */ #define DEFAULT_INEQ_SEL 0.3333333333333333 /* default selectivity estimate for range inequalities "A > b AND A < c" */ #define DEFAULT_RANGE_INEQ_SEL 0.005 /* default selectivity estimate for multirange inequalities "A > b AND A < c" */ #define DEFAULT_MULTIRANGE_INEQ_SEL 0.005 /* default selectivity estimate for pattern-match operators such as LIKE */ #define DEFAULT_MATCH_SEL 0.005 /* default selectivity estimate for other matching operators */ #define DEFAULT_MATCHING_SEL 0.010 ... 倀を比范する際、 COALESCE(Threads.ThreadDeleteAt, 0) = 0 のように関数を通すずオプティマむザが出力を予想できず、『遞択床』に最頻倀などの統蚈情報が䜿えなくなりたす。その結果、今回はむコヌル匏が条件文のため、オプティマむザは『遞択床』ずしお最初の行にある0.005を䜿甚したす。 今回の䞊列凊理2プロセスに圓おはめおざっくりず行数掚定しおみるず、『濃床』*『遞択床』=90908*0.005=454.54、プロセスあたり454.54÷2(プロセス数)=227.27ず、オプティマむザが蚈算した238に近い倀になりたした。 ぀たり、デヌタの実態を無芖しお、Where句を適甚した埌の行は「党䜓の0.5%しかない」ず芋積もられた結果、4䞇行のルヌプ凊理が走っおいたようです。 実行蚈画が実態を反映するようになった 負荷Top5のク゚リ党おで、WHERE句に COALESCE が䜿甚されおいたため、統蚈情報が正しく機胜するシンプルな比范匏に曞き換えたした。 WHERE (~~ AND (Threads.ThreadDeleteAt = 0 OR Threads.ThreadDeleteAt IS NULL )) ~~) この修正により、オプティマむザは行数を玄8䞇件ず正しく認識するようになり、Nested Loopから Hash Join を遞択するようになりたした。 QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost= 4047 . 87 .. 8320 . 14 rows = 3 width= 56 ) Group Key: threads.threadteamid -> Hash Join (cost= 4047 . 87 .. 8312 . 34 rows = 1554 width= 32 ) Hash Cond: ((threads.postid)::text = (threadmemberships.postid)::text)     // ⬇実態が反映されおいる -> Seq Scan on threads (cost= 0 . 00 .. 4052 . 55 rows = 80727 width= 51 ) Filter: (((threaddeleteat = 0 ) OR (threaddeleteat IS NULL )) AND ((threadteamid)::text = ' XXXXXXXXXXXX ' ::text)) -> Hash (cost= 4026 . 18 .. 4026 . 18 rows = 1735 width= 35 ) -> Bitmap Heap Scan on threadmemberships (cost= 34 . 63 .. 4026 . 18 rows = 1735 width= 35 ) Recheck Cond: ((userid)::text = ' XXXXXXXXXXXX ' ::text) Filter: following -> Bitmap Index Scan on idx_thread_memberships_user_id (cost= 0 . 00 .. 34 . 19 rows = 1836 width= 0 ) Index Cond: ((userid)::text = ' XXXXXXXXXXXX ' ::text) 巊ク゚リ倉曎前 右ク゚リ倉曎埌 3. 実行回数の削枛 ク゚リ単䜓の軜量化に加え、アプリケヌション局でも「そもそもそのク゚リを投げる必芁があるか」を芋盎したした。 調査の結果、5぀の高負荷ク゚リのうち䞀郚は、特定の画面状態によっおは実行が䞍芁なものであるこずが刀明したした。特にデプロむ埌に負荷が集䞭する「リロヌド時」や「WebSocket再接続時」においお、ロゞック䞊䞍芁なク゚リの発行をフラグ制埡でスキップするように修正したした。 ゚ンドポむントのフラグ眮換青→緑によりク゚リ発行数を削枛 改善結果 CPU䜿甚率 赀棒は巊から、応急措眮ずしお行なったスケヌルアップ巊の赀線、元スペックぞのスケヌルダりン右の赀線を瀺しおいたす。察策適甚を行なった以降は、むンスタンススペックを元に戻した埌も、 CPU䜿甚率20〜30%皋床 で安定しお掚移しおいたす。 右の赀線以降、20-30%の䜿甚率で萜ち着いおいる ク゚リ実行速床 実行蚈画が適正化されたこずで、レむテンシが劇的に改善したした。 平均実行時間は 箄400msから20ms台 ぞず短瞮され、 15~20倍高速化されたした 。 番号 修正前 修正埌 改善倍率 ① 436.71 ms 20.87 ms 箄 20.9倍 ② 435.86 ms 20.75 ms 箄 21.0倍 ③ 440.62 ms 29.06 ms 箄 15.2倍 ④ 369.46 ms 25.20 ms 箄 14.7倍 â‘€ 369.16 ms 24.99 ms 箄 14.8倍 たずめ Where句で安易に関数を䜿うず、オプティマむザが行数掚定を誀り、デヌタ量に芋合わない非効率な実行蚈画が遞択される原因になりたす。 たたスロヌク゚リの原因を探る際は、単に「むンデックスがあるか」だけでなく、オプティマむザの実行蚈画が正しいかどうかに泚意する必芁があるこずが、今回の調査で身にしみおわかりたした。 最埌に 今回、Google Cloudを觊るのもDBチュヌニングも初めおでしたが、DB負荷改善ずいう明確な目暙に取り組みながら孊ぶこずで、自分にずっお良い経隓になりたした。 ただただGC,DBずもに知らないこずが倚くあるので、業務に掻かせるよう匕き続き孊んでいきたいず思いたす。 本蚘事は、䌚瀟で契玄しおいるGeminiに校正をしおもらいたした。 スタメンには、新人のうちから色々なこずを経隓させおもらえる文化がありたす。たた゚ンゞニアだけでなく党郚眲でAI掻甚を掚進しおいたす。少しでも興味を持たれたしたら、以䞋フォヌムからぜひご応募ください herp.careers *1 : Query Insights を䜿甚しおク゚リのパフォヌマンスを向䞊させる *2 : PostgreSQL 17.6文曞 パヌト VII. 内郚情報 第68ç«  プランナは統蚈情報をどのように䜿甚するか *3 : パラレルク゚リにおけるプロセス数に぀いお *4 : 䞊の補足 *5 : PostgreSQL行数掚定を読み解く/row-estimation *6 : PostgreSQLにおける行数掚定の蚈算方法 *7 : オプティマむザが濃床ずしお参照する倀 *8 : GitHubで確認できる、PostgreSQLの遞択床デフォルト倀
アバタヌ
はじめに こんにちは株匏䌚瀟スタメンの ちぇる です 長らく動画倉換を支えおきた Amazon Elastic Transcoder以䞋 Elastic Transcoderの EOLサポヌト終了が発衚されたした。AWS 公匏でも AWS Elemental MediaConvert以䞋 MediaConvertぞの移行 が匷く掚奚されおいたす。 匊瀟が運営する「TUNAG」でも、これたで Elastic Transcoder ず MediaConvert が混圚しおいたしたが、この床 MediaConvert ぞの党面移行を完了したした。本蚘事では、この移行プロゞェクトを通じお孊んだ「倉換システムの思想の違い」ず「蚭蚈の健党化」に぀いおご玹介したす。 動画倉換システムの仕組み思想の違い 䞡サヌビスを比范するず、動画倉換に察する根本的な蚭蚈思想が異なるこずに気づきたす。 Elastic TranscoderPipeline 䞭心蚭蚈 Elastic Transcoder の蚭蚈思想は、䞀蚀で蚀えば 「固定された倉換ラむンPipelineに Job を流し蟌む」 方匏です。 Pipeline 入出力バケットや IAM ロヌル、SNS 通知などを定矩する。 Job / Preset 解像床やコヌデックを定矩し、Pipeline にキュヌむングする。 あらかじめ定矩された「倉換ラむン」の凊理胜力に応じお順次実行されるため、管理はシンプルですが、入力動画の特性に合わせた柔軟な調敎には限界がありたした。 MediaConvertJob 䞭心蚭蚈 察する MediaConvert の思想は 「動画 1 本ごずに詳现な泚文祚Jobを䜜り、Queue でさばく」 方匏です。 Job 入出力蚭定、動画・音声の现かなパラメヌタ、加工蚭定など党おの情報を持たせる。 Queue 䞊列実行数や優先床を制埡する。 MediaConvert には Pipeline ずいう抂念がなく、動画ごずに Job を定矩したす。そのため、「入力動画の特性に合わせお解像床・ビットレヌトを動的に最適化する」 ずいった、より高床でプロフェッショナルな制埡が可胜になりたす。 「Pipeline倉換ラむン䞭心」から、より柔軟な「Job泚文祚䞭心」ぞの転換が、このリプレむスの本質ずいえたす。 移行で盎面した「厳栌さ」ずいう泚意点 移行を進める䞭で、特に泚意が必芁だったのが 「 音声のみ映像トラックなしのデヌタ 」 の扱いです。 「よしなに」の Elastic Transcoder、「厳栌」な MediaConvert Elastic Transcoder: 映像音声の蚭定になっおいるプリセットに「音声のみ」のファむルを投げおも、足りない芁玠映像を自動でスキップしお「音声のみ MP4」をよしなに出力しおくれたす。 MediaConvert: 商甚レベルの品質を担保するため、バリデヌションが非垞に厳栌です。映像蚭定があるのに゜ヌスに映像がない堎合、「蚭定ず入力が䞀臎しない」ずしお゚ラヌになりたす。実装偎で、入力に応じお Video Selector を動的に陀倖するずいった制埡が必芁ずなりたす。 そのため、Elastic Transcoder では「よしなに」凊理されおいたファむルが、MediaConvert でぱラヌずなり、「以前は投皿できおいたファむルがアップロヌド倉換できなくなる」ずいう問題が発生する可胜性がありたす。 厳栌さが生む、運甚の健党化 䞀芋するず MediaConvert は手間がかかるように芋えたすが、これはサヌビス運営においお倧きなメリットになりたす。 䟋えば、これたでは動画アップロヌド導線に誀っお音声デヌタが混入した堎合でも、「映像のない真っ暗な動画」ずしお倉換されおしたい、タむムラむンに黒いフレヌムが衚瀺されるずいった状況が起こり埗たした。今回の移行に䌎い、「仕様の曖昧さ」を排陀するこずで、コンテンツの皮別に応じた最適な芋せ方を匷制できるようになったのです。 具䜓的には、音声デヌタに぀いおは「音声専甚のアップロヌド導線を甚意する」か、「サムネむルを付䞎したうえで動画ずしおアップロヌドする」かの、いずれかの方法を取るこずになりたす。 こういった仕様は䞀般的で、䟋えば YouTube でも音声デヌタをそのたた動画ずしおアップロヌドするこずはできず、公開には映像トラック静止画を含むが必須ずなっおいたす。 たずめ TUNAG には耇数の動画投皿導線が存圚しおおり、新旧のシステムが混圚しおいたしたが、今回のリプレむスを通じお MediaConvert ぞの䞀本化が完了したした。 サヌビスを運甚する䞭で、EOL によるリプレむスを迫られるのは避けられない宿呜です。しかしそれは同時に、 「システムの曖昧さを敎理し、蚭蚈を健党化する絶奜の機䌚」 でもありたす。 今回の移行を経お、TUNAG の動画基盀はより堅牢で、今埌の進化に耐えうるものになりたした。本蚘事が、同じく動画倉換基盀の運甚やリプレむスに取り組んでいる方々の参考ずなれば幞いです。 最埌に 株匏䌚瀟スタメンでは、゚ンゞニアを絶賛倧募集䞭です 技術の力でサヌビスをより良くしおいきたい方、ぜひ䞀床お話ししたしょう。詳しくは以䞋をご芧ください herp.careers
アバタヌ
目次 目次 はじめに 移行背景 Web Push通知の仕組み バック゚ンド偎の実装 フロント゚ンド偎の実装 トヌクンのラむフサむクル管理 移行工皋 最埌に はじめに こんにちは。スタメンでTUNAGのバック゚ンド開発を行なっおいる きいろ です。 TUNAGは組織掻動を支揎するサヌビスで、Webアプリずモバむルアプリの䞡方で提䟛しおおり、Webアプリではナヌザヌアクションをリアルタむムに届けるためのWeb Push通知機胜を備えおいたす。 TUNAGの代衚的な機胜ずしお「制床」があり、そこから瀟内報など情報共有のための各皮コンテンツ投皿が行えたす。 それら投皿のリアルタむム通知を行うなど、Web Push通知機胜はプロダクトのナヌザヌ䜓隓に盎結する重芁な仕組みずなっおいたす。 今回、そのWeb Push通知機胜に぀いお、Firebase Cloud Messaging以䞋、FCMをベヌスに移行を行いたした。 この蚘事では、移行圓時の調査内容や、バック゚ンドおよびフロント゚ンドの䞡面で盎面した課題、そこから埗られた知芋を玹介したす。 同様にFCMを甚いたWeb Push通知の導入や移行を怜蚎されおいる方にずっお、䜕かしら参考になれば嬉しいです。 移行背景 TUNAGでは長らくPushCrew珟 VWO Engageを利甚し、Web Push通知機胜を提䟛しおいたした。 PushCrewはWeb Push通知機胜を手軜にサヌビスに導入できる䞀方、長期運甚をする䞭で通知甚トヌクン管理や料金面などの課題が䞊がっおいたした。 たた、通知蚭定をPushCrewから提䟛されるサブドメむン䞊で行うため、通知の再蚭定フロヌがやや耇雑になりやすいなど、運甚面での现かい課題も衚面化しおいたした。 移行先ずしおFCMを遞んだ理由は、すでにモバむルアプリの通知基盀ずしお掻甚しおおり、開発環境ごずにFirebaseプロゞェクトが存圚しおいたこず、認蚌たわりの仕組みも敎っおいたこずが倧きいです。 新芏構築する郚分が比范的少なく、既存リ゜ヌスを掻かしながらWeb偎の通知基盀も統合できる点が、移行先ぞの決め手ずなりたした。 Web Push通知の仕組み PushCrewからFCMぞの移行にあたり、最も倧倉だったものがFCMの導入蚭蚈です。 圓時の自分はWeb Push通知に関する知識が充分ずは蚀えず、既存機胜の連携構造も把握しきれおいなかったため、Web Push通知送信に関する既存実装、PushCrew APIの仕様ず利甚圢匏を䞻軞に、地道にFCMの導入方針を定めおいきたした。 そもそもずしおのFCMベヌスでのWeb Push通知の仕組みに぀いおですが、ブラりザ含めお以䞋4぀の䞻芁コンポヌネントによっお成立したす。 コンポヌネント 圹割 Browser Web Push通知の受信 Push Service 通知の䞭継サヌビスその1。通知先゚ンドポむント管理。ブラりザに盎接Web Push通知を届ける FCM 通知の䞭継サヌビスその2。アプリケヌション偎のリク゚スト起点でWeb Push通知を送信する Application Web Push通知の送信 実際にWeb Push通知を行う堎合は、(1)トヌクン䜜成→(2)Push通知送信の2ステップで行いたす。トヌクンずはWeb Push通知配信サヌビスを利甚する際に、サヌビス事業者偎でクラむアント管理するために個別に発行するIDのこずを衚珟しおいたす。ID名称は通知配信サヌビス毎に異なりたすが、この蚘事ではたずめお「トヌクン」ず衚蚘したす。 Web Push通知を行う際の、具䜓的なコンポヌネント間の連携フロヌは以䞋の通りです。 青線トヌクン䜜成 赀線Push通知送信 Web Push通知の凊理フロヌ Push通知先の゚ンドポむントの発行管理はPush ServicePush Subscriptionで行い、FCMはdevice tokenを通じおPush Subscriptionを管理したす。 実際の通知送信時は、アプリケヌション偎はFCM APIを通じおdevice tokenをFCM偎に連携し、FCMはdevice tokenをもずに察応するPush Subscriptionを内郚で参照、その埌Push Serviceを経由しおWeb Push通知の送受信が行われたす。 ちなみにですが、FCMを通知配信基盀ずしお利甚する堎合、Firebase SDKがこれらを抜象化しおくれるため、Web Push通知の内郚構造やPush Serviceの存圚を匷く意識する必芁はありたせん。 実際の実装手順ずしおは以䞋のようなシンプルなものになりたす。 Service Workerの登録 Firebase SDKから提䟛される getToken() を甚いおdevice tokenを取埗 device tokenの保存 send API 呌び出し時に保存したdevice tokenをpayloadに含めお通知実行 䞀方で、実装を進める䞭で「Push通知時の送信先゚ンドポむントはどのように管理されおいるのか」ずいった点がブラックボックス的に映り、実装方針の構築に時間を芁した郚分もありたした。 そのため通垞の実装では深く意識しなくおもよいものの、背景ずしお知っおおくず挙動の理解がしやすくなるWeb Push通知の仕組みに぀いお、敎理の意味も兌ねお簡単にたずめたした。 バック゚ンド偎の実装 バック゚ンド偎の実装蚭蚈を行うにあたり、軞にしたものはPushCrew APIずFCM APIの仕様差分でした。移行時点でTUNAGで行うWeb Push通知の利甚圢匏ずしお、以䞋3぀のパタヌンがありたした。 単䞀トヌクン通知 耇数トヌクン同時通知 時刻指定通知 PushCrewはこれらの通知圢匏をAPIずしお個別に提䟛しおくれおいたため、バック゚ンドではトヌクンを甚意しお甚途に応じたAPIを呌び出すだけで通知制埡が完結しおいたした。 しかし、FCMが提䟛するものは単䞀トヌクン通知甚API先のsend APIのみです。そのため、耇数トヌクン同時通知・時刻指定通知の制埡はアプリケヌション偎で構築する必芁がありたした。 たた、トヌクンはナヌザヌに玐づくものですが、厳密にはナヌザヌのクラむアント環境に応じお発行されたす。同䞀ナヌザヌであっおも、耇数のデバむスからログむンした堎合はそれぞれ別IDずしおトヌクン発行が行われたす。 そのため、アプリケヌション偎では ナヌザヌトヌクン = 1Nの察応関係を保った管理 が必芁ずなりたす。 このデヌタ構造を考慮した䞊で、耇数トヌクン同時通知および時刻指定通知の制埡は、Sidekiqを甚いお以䞋のような凊理フロヌを蚭蚈したした。 むベント発火時に通知察象ナヌザヌを決定 ナヌザヌ単䜍で通知ゞョブを発行 各ナヌザヌに玐づくトヌクンを取埗 トヌクン単䜍でFCM API呌び出しゞョブを発行 %%{init: {'theme': 'dark'} }%% sequenceDiagram participant caller as caller participant worker1 as UserWorker participant worker2 as TokenWorker caller->>worker1: perform(user_id,msg) activate worker1 worker1->>DB: user取埗 activate DB DB->>worker1: user deactivate DB worker1->>DB: token取埗 activate DB DB->>worker1: token deactivate DB loop token_id worker1->>worker2: perform(token_id,msg) deactivate worker1 Note over worker2: Web Push通知実行 end 耇数トヌクンぞの同時通知に぀いおは通知時に䞊列でゞョブを走らせるこずで察応し、時刻指定通知においおはゞョブそのものの実行時間指定で制埡しおいたす。 Web Push通知は耇数の機胜から利甚される前提の機胜であるため、通知内容ず察象ナヌザヌを指定するだけで利甚できるむンタヌフェヌスに統䞀し、内郚凊理はSidekiqで吞収する方針にしたした。 通知凊理䞭の倱敗に察するリトラむ制埡に぀いおもアプリケヌション偎で個別に持たず、Sidekiqの暙準機胜に集玄するこずで、通知凊理党䜓の芋通しが良くなるようにしたした。 手探りの実装でしたが、他機胜ずの連携や拡匵性を芋据えた構成にできたかなず思っおいたす。 フロント゚ンド偎の実装 バック゚ンド偎のコアロゞックが固たった埌は、フロント゚ンド偎の移行を行いたす。フロント゚ンド偎で移行が必芁な箇所は以䞋2぀です。 トヌクン発行凊理 通知衚瀺凊理フォアグラりンド通知、バックグラりンド通知 たず、トヌクン発行凊理ですが、ここでもPushCrewずFCMの仕様の違いが倧きく圱響したした。 FCMでのトヌクン発行凊理はFirebase SDKが提䟛する getToken() 関数を甚いお行う想定で、その前段ずしおService Workerの登録が必芁ずなりたす。 Service Workerは、ブラりザに登録されるJavaScriptスクリプトで、Web Push通知機胜に関しおはプッシュ通知むベントが発生した際Web Push通知を受信した際にブラりザがワヌカヌずしお実行し通知衚瀺の凊理を行いたす。 PushCrewでは、Web Push通知に必芁ずなるService Workerが公匏CDNから提䟛されおいたため、トヌクン発行時にはその゚ンドポむントの呌び出し、取埗したスクリプトをService Workerずしお登録をするだけでWeb Push通知衚瀺が可胜でした。䞀方で、FCMを甚いたWeb Push通知では、Service Worker向けのスクリプト配信自䜓をサヌビス事業者偎で担う必芁があり、登録甚の゚ンドポむントを含めた配信蚭蚈から怜蚎する必芁がありたした。 このWeb Push通知凊理に向けたService Worker取埗甚の゚ンドポむントを実装する䞊で、Web Push通知を受け取るWebサヌビスのドメむン盎䞋で取埗する、ずいうこずが重芁になりたす。䟋 https://service-domain/service-worker.js など これはFCM公匏でも掚奚されおいるプラクティスになりたす。 ずいうのも、Service Workerがむベントハンドリングにおいお制埡可胜な範囲は、スクリプトを取埗したURLのパスに䟝存しおおり、その配䞋にあるペヌゞやリク゚ストのみが察象ずなるからです。 䟋えば、Web Push通知を受けずり、そこに仕蟌たれたURLリンクに盎接遷移する際、遷移先で特定芁玠にフォヌカスを圓おるなどの挙動が可胜ですが、そのフォヌカスを圓おられるペヌゞは、Service Workerが取埗したURLパスに䟝存したす。 ドメむン盎䞋で取埗しない堎合、先の䟋だず遷移先ペヌゞによっおはフォヌカス凊理がうたく動䜜しない、などの通知挙動の違いが倖郚起因によっお生たれおしたうこずになりたす。 そのため、Web Push通知に関するService Workerの取埗゚ンドポむントはドメむン盎䞋で取埗するこずが掚奚されおいたす。 TUNAGでもこのプラクティスに沿っお゚ンドポむントを実装しようずしたのですが、既存のアプリケヌション構成ずの兌ね合いから、ドメむン盎䞋でのスクリプト配垃ができない状況でした。 この制玄により、Service Workerの配眮パスやスコヌプ蚭蚈を怜蚎する必芁が生じ、䞀郚のペヌゞが制埡察象倖ずなるリスクも含めお実装刀断を行うこずになりたした。 最終的に、先のService Workerスコヌプ仕様ず既存の通知仕様を螏たえ、盎近は問題にはならないず刀断し、ドメむン盎䞋ではなくサブパスを挟んでのService Worker登録を行う運甚になりたした。 通知衚瀺凊理の移行ですが、こちらは公匏プラクティス通りの実装を行ったため割愛したす。 トヌクンのラむフサむクル管理 Web Push通知機胜は通知先クラむアントの識別甚にトヌクンを利甚したすが、これはクラむアントの持ち物であり、Service Workerのラむフサむクルず連動したす。 これたで利甚しおいたPushCrewでは、通知甚Service Workerが専甚ドメむンで管理されおおり、トヌクンの有効期間に぀いおも長期利甚を前提ずした仕様でした。 そのため、クラむアント偎でトヌクンを定期的に再取埗する必芁性は高くありたせんでした。 䞀方で、FCMではトヌクンは長期利甚を想定したものではなく、トヌクンそのものが䞍意に利甚出来なくなるこずを前提ずしたリ゜ヌスずしお扱っおいたす。 そのため、今回のFCM移行においお、適圓なタむミングでの再取埗凊理を実装する必芁が出おきたした。 これらを螏たえ、最終的に実装した䞀連のトヌクン管理フロヌは以䞋の通りです。 %%{init: {'theme': 'dark'} }%% stateDiagram-v2 direction LR state トヌクン管理 { 取埗 --> 保存 : 差分あり 取埗 --> 砎棄 : 差分なし 保存 --> 取埗枈み 砎棄 --> 取埗枈み } [*] --> 取埗可吊を刀定 取埗可吊を刀定 --> 取埗 : true 取埗可吊を刀定 --> 取埗䞍可 : false 取埗枈み --> 取埗可吊を刀定 : 特定導線を螏む 取埗䞍可 --> [*] TUNAGでは通知の安定性を維持するため、ナヌザヌアクションに玐づけおトヌクンの再取埗を行い、トヌクンの鮮床を保぀こずにしたした。 たた、バック゚ンド偎で実際に通知を行う際は通知APIのレスポンスを元に、利甚期限に達したトヌクンに぀いおはその時点で砎棄する凊理も組み蟌み、䞍芁なトヌクンがアプリケヌション䞊で残り続けないようにしおいたす。 移行工皋 実際の基盀移行に぀いおは、TUNAGの既存ナヌザヌぞの圱響が避けられないため、以䞋4぀のフェヌズを策定しお進めたした。 フェヌズ 通知状況 FCM移行前 PushCrew APIを甚いお通知 FCM移行䞭 ナヌザヌのトヌクン状況に応じおPushCrew APIずFCM APIを䜿い分け FCM移行埌 FCM APIを甚いお通知 PushCrewトヌクン削陀 FCM APIを甚いお通知 FCM移行䞭のフェヌズにおいおはTUNAGナヌザヌを以䞋の3パタヌンで分類し、移行の前埌で互換性を持たせるこずでトヌクン保持状況の移行期間を蚭けたした。 ナヌザヌパタヌン 通知圢匏 PushCrewトヌクンのみ保持するナヌザヌ PushCrew APIを甚いお通知 䞡トヌクンを保持するナヌザヌ FCM APIを甚いお通知 FCMトヌクンのみ保持するナヌザヌ FCM APIを甚いお通知 以䞊を螏たえ、移行に関する党䜓工皋は以䞋の通りずなりたした。 通知基盀の移行フロヌ PushCrew API切り離し時期の策定においお、どのタむミングで行ったずしおも䞀郚の移行前ナヌザヌぞの圱響が避けられない懞念がありたしたが、そこは十分な移行期間を蚭けるこずで圱響の最小化を行いたした。 移行期間の区切りに぀いおは、FCMトヌクン総数の増加を時系列でモニタリングし぀぀、その傟向が安定化する時期たでずしたした。 その時点で移行が枈んでいないナヌザヌに぀いおはWeb版を積極的に利甚しおいない局ず扱いリスク蚱容をした䞊で、最終的なPushCrew APIの切り離しに至りたした。 最埌に 今回の蚘事では、TUNAGにおけるFCMぞのWeb Push通知基盀移行で盎面したポむントを玹介したした。 自分自身、Web Push通知の実装に本栌的に関わるのは初めおで、知識のない状態から手探りで進めた郚分も倚かったのですが、瀟内の゚ンゞニアの方々に现かく盞談し぀぀、最終的には無事移行するこずができたした。 蚭蚈や実装の節目ごずに意芋をもらえたこずで、珟圚は倧きな問題もなく運甚できおいたす。 今埌も安定した通知䜓隓を提䟛できるよう匕き続き改善しおいく予定です。 FCMはメゞャヌなサヌビスではありたすが、Web Push通知の仕組みなど前提知識が求められるケヌスも倚く、必芁最小限のAPIのみが提䟛されおいるため、移行元サヌビスずのギャップに戞惑う堎面もあるかず思いたす。 この蚘事が同じようにFCMの導入を怜蚎されおいる方々の手助けになれば嬉しいです。 スタメンでは、Ruby゚ンゞニアに限らず党技術領域で、共にTUNAGを成長させおいきたい゚ンゞニアを募集しおいたす。 ご興味いただけたしたら、ぜひたずはカゞュアル面談からご応募いただけるず嬉しいです。皆さんずお䌚いできるこずを楜しみにしおいたす。 herp.careers
アバタヌ
はじめに こんにちは、プロダクト開発郚の 勝間田 です。 非同期凊理は、即時の応答が䞍芁な凊理をバックグラりンドで䞊行凊理するこずでナヌザヌ䜓隓を向䞊させるものであり、私たちのサヌビス TUNAGツナグ では䞻にSidekiqを利甚しおおりたす。 即時の応答が䞍芁な凊理ずはいえ、そこで倧きな 遅延Latency が発生しおしたえば、ナヌザヌ䜓隓を損ねるこずに぀ながっおしたいたす。 Sidekiqの蚭定でキュヌの重みづけを行い、ナヌザヌぞのむンパクトが倧きいゞョブが優先的に凊理されるよう工倫はしおいたしたが、優先床の䜎いキュヌずはいえ、その遅延が倧きくなるこずがありUXに少なからず圱響が出始めおいたした。 これたでスケヌリングに぀いおは ECSタスクのCPU䜿甚率ベヌスのオヌトスケヌリング に任せおいたした。 それずは別で定期実行によりSidekiqのキュヌが䞀定数以䞊滞留しおしたった堎合はSlackにアラヌトを通知し、゚ンゞニアがそれに気づいお手動でECSのタスク数を増やす、ずいう運甚を行なっおいたした。 こうした属人的な察応・怜知から遅延解消たでのタむムラグ・䌑日察応が難しい点などが課題ずなっおおり、これらを解消すべく今回の仕組みを導入するに至りたした。 たた この蚘事では䞋蚘のこずに぀いおは觊れたせんので、あらかじめご了承ください 。 CloudWatchカスタムメトリクス送信の具䜓的な実装 各AWSリ゜ヌスの具䜓的な蚭定手順 䜙談ですが、最近サブサヌビスで Solid Queue を導入したした。導入の背景や手順に぀いお別のブログで玹介しおおりたすので、ご興味のある方はぜひご芧ください。 tech.stmn.co.jp 察応内容 これらの課題を解決するため、監芖する指暙をCPU䜿甚率から SidekiqのキュヌLatency遅延時間 そのものに倉曎するこずにしたした。 やりたいこずキュヌのLatencyが䞀定の閟倀を超えたら、゚ンゞニアの手を介さず自動でECSタスクをスケヌルアりトさせる 具䜓的な察応内容は以䞋の通りです。 Napkinを䜿っおみたした 1. LambdaでアプリのAPIよりSidekiqのLatencyを取埗 Sidekiqには、キュヌやワヌカヌの状態を取埗するためのAPIがありたす。 github.com 以䞋のようなコヌドで簡単にキュヌの情報を取埗するこずができたす。 stats = Sidekiq :: Stats .new stats.queues.keys.map do |key| queue = Sidekiq :: Queue .new(key) { name : queue.name, size : queue.size, latency : queue.latency } end このSidekiq APIを利甚しおLatencyを取埗する方法ずしお、「LambdaからSidekiqのデヌタストアRedisに盎接接続する」のではなく、 「アプリケヌションRails偎に、Sidekiq APIを呌び出しお結果をJSONで返す専甚の゚ンドポむントを実装する」 ようにしおいたす。 このようにするこずで以䞋のメリットがあるず思いたす。 Lambda偎でRedisずの接続が䞍芁になるので、あらゆる蚭定をする必芁がない。 将来SidekiqのバヌゞョンアップなどでAPIの仕様が倉わったずしおも修正はアプリケヌションのみずなり、Lambda偎のコヌドは䞀切倉曎する必芁がなく返华されるLatencyに集䞭すればよくなる。 2. CloudWatchカスタムメトリクスにQueueのLatencyを送信 Latency情報をオヌトスケヌリングのトリガヌずしお䜿えるよう、CloudWatchに送信したす。 TUNAGツナグ では、凊理する機胜が倧きく異なる非同期凊理に぀いおそれぞれ異なるECS Serviceで動かしおいるため、個別にオヌトスケヌリングさせる必芁がありたした。 そのためメトリクス名は同じ Latency ずし぀぀、CloudWatchの ディメンション を利甚しおECS Serviceごずに蚭定するこずで、CloudWatchアラヌムがLatencyを個別に監芖し、察応が必芁なECS Serviceのみをスケヌルアりトさせるこずができたす。 3. EventBridgeをLambda実行のトリガヌに蚭定 甚意したLambdaを定期実行するために、トリガヌずしおEventBridgeのスケゞュヌルを蚭定したした。 スケヌルアりトが埌手埌手にならないようある皋床短めにLambdaを実行するようルヌルを蚭定しおいたす。 4. CloudWatch アラヌムによる監芖ず発火 CloudWatchに Latency メトリクスが送信されるようになったので、次はこのメトリクスを監芖するCloudWatchアラヌム を䜜成したす。 アラヌムも個別に䜜成するこずができ、サヌビスごずに独立したスケヌリングができるようにしおいたす。 䞋の画像のように、ECS Serviceで分けたディメンション単䜍でアラヌムを蚭定しおいたす。 CloudWatchメトリクスの参照タブ抜粋 5. ECSオヌトスケヌリングポリシヌの実行 䜜成したCloudWatchアラヌムが ALARM 状態になるこずをトリガヌ ずしお、ECSタスクを増やすスケヌリングポリシヌを蚭定したす。これにより、Latencyが高くなったらECSタスクが蚭定した数だけ自動でスケヌルアりトするようになりたす。 ここたででやりたいこずの「キュヌのLatencyが䞀定の閟倀を超えたら、゚ンゞニアの手を介さず自動でECSタスクをスケヌルアりトさせる」が実珟できたす。 ただスケヌリングポリシヌを蚭定する䞊で、コストずパフォヌマンスのバランス調敎に悩みたした。「い぀、どのくらいタスクを増枛させるか」ずいう刀断には、2぀の課題がありたす。 スケヌルアりトから解消たでのタむムラグによる「過剰スケヌルアりト」のリスク ECSタスクを増やしおから、そのタスクが起動し、キュヌのLatencyが実際に解消されるたでにはタむムラグが発生したす。 もし、アラヌムが発火し続ける間タスクを増やし続ける蚭定にするず、本来なら起動䞭のタスクで捌ききれる量だったにも関わらず、過剰にタスクを増やしおしたい、無駄なコストが発生する恐れがありたす。 スケヌルむンによる「ピヌク時パフォヌマンス䜎䞋」のリスク 非同期凊理の特性䞊、平垞時はLatencyが0に近い状態が続きたす。もしLatencyの倀だけを芋おタスクを枛らすず、ピヌク時以倖の時間垯でタスクが必芁最䜎限たで枛りすぎおしたいたす。 その結果、次のゞョブのピヌクが来た際に、スタヌト時点のタスク数が少なすぎるため、そこからスケヌルアりトを始めおも凊理が間に合わなくなる恐れがありたす。 䞊蚘のような課題があったため、珟状は䞋蚘のような察策によりバランスをずっおいたす。 スケヌリングポリシヌに 適床なクヌルダりン期間を蚭定 ECSタスクをスケヌルアりトさせ、新しいタスクが起動しおゞョブを凊理し始めおもすぐにLatencyが解消されるわけではありたせん。このタむムラグを考慮しないず、Latencyがただ高い状態を芋おアラヌムが発火し続けるこずで必芁以䞊にタスクを増やしおしたい、過剰なスケヌリングが発生する可胜性がありたす。 そのためスケヌリングポリシヌ偎に適切なクヌルダりン期間を蚭けるこずで、「䞀床スケヌルアりトしたら、次のスケヌリング刀断たで䞀定時間埅機する」ように蚭定し、過剰なスケヌルアりトを防ぐようにしたした。ただこの期間に぀いおも増やすタスクの数ず同様でサヌビスによっお適切な倀が異なっおくるず思いたす。最初は短めに蚭定し぀぀、Latencyの解消具合を芋ながら埮調敎しおいくず良さそうに思いたした。 キュヌのLatencyによる「スケヌルむン」をあえお蚭定しない 非同期凊理の特性䞊、アラヌムがOKLatencyが䜎い状態の時間垯のほうが倚いため、OK状態をトリガヌにタスク数を枛らしおしたうず、次のゞョブのピヌク゚ンキュヌが急増する時間垯が来た際に、タスク数が少ない状態からスケヌルアりトをするこずになりたす。 Latencyによりスケヌルアりトした時間垯は、継続しおゞョブが゚ンキュヌされる可胜性が高い時間垯です。クヌルダりン期間もあるため、少ないタスク数からのリカバリヌでは間に合わなくなる恐れがありたす。 そのため、Latencyベヌスでは「増やす」こずだけを担圓させ、タスクを「枛らす」凊理に぀いおは、埓来から蚭定しおあるCPU䜿甚率ベヌスのスケヌリングCPU䜿甚率が䜎ければ枛らすに匕き続き任せる構成ずしたした。 珟状はこのような蚭定で運甚しおおりたす。 これらの蚭定に぀いおもサヌビスの特性やピヌク垯の有無等で倉わりそうです。より良い蚭定があればぜひ知りたいです。 結果 Latencyベヌスのオヌトスケヌリングを導入した結果、これたでキュヌの滞留件数が増えるたびに飛んでいたSlackアラヌトが、ほずんど飛ばなくなりたした。 手動察応に぀いおも導入埌は䞀床も行っおおりたせん。 これにより゚ンゞニアの手動察応コストを削陀し、凊理遅延によるUXの悪化を未然に防ぐこずができたした。 たずめ 今回ご玹介したSidekiqのLatencyをトリガヌにしたオヌトスケヌリングは、AWSの暙準的な機胜Lambda, EventBridge, CloudWatch, ECS Auto Scalingを組み合わせるこずで実珟できるため、導入自䜓のハヌドルは比范的䜎いず感じたした。 今埌はより现かなチュヌニングもしおいければず考えおいたす。珟状では閟倀を超えた際に決たったタスク数を増やしおいたすが、Latencyの倀やキュヌの皮類によっお増やす数を倉えたり、監芖するキュヌをより厳遞したりなどコストパフォヌマンスずのバランスを考えながら改善しおいきたいです。 最埌に スタメンでは、Ruby゚ンゞニアに限らず党技術領域で、プロダクトを成長させおいく゚ンゞニア、デザむナヌ、プロダクトマネヌゞャヌの方を募集しおいたす。 ご興味いただけたしたらぜひご応募いただけたすず嬉しいです。 皆さんずお話できるこずを楜しみにしおいたす。 herp.careers
アバタヌ
🏁 はじめに 株匏䌚瀟スタメンにおプラットフォヌム郚で SRE / DevEx などに取り組んでいるもりしたです。今回は Ruby on Rails アプリケヌションに Solid Queue を導入したお話を曞こうず思いたす。 こんな人に読んでもらえるずうれしく思いたす。 Solid Queue に興味がある Ruby on Rails アプリケヌションで手軜に定期実行ゞョブを䜜りたい すでに皌働しおいる定期実行ゞョブの Solid Queue ぞのリプレむスを怜蚎しおいる 💡 Solid Queueずは DB完結型ゞョブキュヌの基瀎 Solid Queue は Active Job 向けに蚭蚈された、DBベヌスのキュヌむングバック゚ンドです。 Sidekiq や Resque のように Redis などの倖郚サヌビスが䞍芁 Recurring Tasks 機胜を利甚するこずで Cronのように、蚭定されたスケゞュヌルに埓っおゞョブを自動的に定期実行できる 利甚するDBは既存アプリケヌションず共存するこずも Solid Queue 独自で分離するこずもできる 📌 導入の背景 ゞョブを定期実行したかったためです。 スタメンの䞻力事業 TUNAGツナグ は TUNAGのコア郚分以降、TUNAG本䜓ず機胜単䜍で切り出した耇数サヌビスが連携しお動䜜しおいたすが、機胜単䜍で切り出したタスク機胜サヌビスで定期的に実行したい凊理がありたした。 しかしながら、タスク機胜サヌビスにはゞョブを定期実行する基盀がなかったため、基盀構築から始めるこずずなりたした。 ⚙ 既存の定期実行システムAWS/ECS連携のアヌキテクチャ たずは既存の定期実行がどのように動いおいるかを確認したした。 TUNAG本䜓では elastic_whenever gem を利甚しお ECS Scheduled Task にお rake タスクを実行しおいたす。 rake タスクを远加しお定期実行するたでの流れは䞋蚘ずなりたす。 プロダクトコヌドにお管理するスケゞュヌルファむル config/schedule.rb で䞋蚘のように定矩する every ' */5 * * * * ' do # 5 分おき rake ' scheduled:foo:bar_baz ' end デプロむ時に定矩内容から Amazon EventBridge ルヌルを䜜成する Amazon EventBridge ルヌルのむベントスケゞュヌルでECSタスクが起動しお rake タスクが実行される ECS Scheduled Task を利甚した定期凊理に぀いおは 2021幎のテックブログでも玹介しおいたす tech.stmn.co.jp このアヌキテクチャの堎合、ゞョブを動かすためにAWS偎の蚭定を行う必芁がありたした。 どのように実珟しおいるのか党䜓像の理解がやや難しいず感じおいたす。 ✅ Solid Queueを遞んだ理由Redis/AWSからの脱华 既存の定期実行の仕組みを把握したうえで、新しくタスク機胜サヌビスに導入する定期実行の基盀ずしお Solid Queue を遞びたした。 耇雑なむンフラ環境の蚭定はなるべく行いたくない なるべく暙準以倖の新しいラむブラリは増やしたくなかった Solid Queue を小さいずころから導入を詊しおみたかった ECS Scheduled Task を利甚した仕組みは実瞟がありたすが、AWS偎の蚭定を行うなどの準備が倚く、今回はなるべくその手間を枛らしたかった。 スタメンでは利甚ラむブラリのアップデヌトを毎週行っおおり、その察象が増えるため、elastic_whenever のような gem をなるべく増やしたくなかった。䞀方で Solid Queue は、Ruby on Rails の䞀郚であるため、gem が増えおも蚱容できるず考えたした。 以䞊が理由の぀ですが、結局は、 Solid Queue を詊しおみたい が䞀番の理由です。 タスク機胜サヌビスは圱響範囲が絞られた小さいサヌビスなので導入を詊しおみるには最適でした。 🖥 Mission Control — Jobs皌働状況の確認 埌述の導入手順で蚭定が完了し、ゞョブが動くようになったら Mission Control — Jobs で実行状況が確認できたす。 Sidekiq のダッシュボヌドず比べるず非垞にシンプルな印象です。 本番で動いおいる Mission Control — Jobs の画面をピックアップしおご玹介したす。 Recurring tasks タブスケゞュヌルの䞀元管理 ここが Solid Queue による定期実行の最倧のメリットを瀺す画面です。 埓来、 config/schedule.rb ファむルや Amazon EventBridge ルヌルに分散しおいたスケゞュヌル定矩が、リポゞトリ内の config/recurring.yml ファむルに集玄され、その実行状況がこのダッシュボヌドで䞀元管理できたす。 Recurring繰り返しのタスクずしお登録したゞョブを確認できたす ぀目のゞョブであれば、月〜金の 10:00 に繰り返し実行したす Run now を抌䞋するずゞョブを即時実行できたす Finished jobs タブ 完了したゞョブが䞀芧で確認できたす Finished jobs 詳现 実行にかかった時間などが確認できたす 🛠 導入手順 今回導入のために行った手順です。 Solid Queue ず Mission Control — Jobs を導入したす。 やりたいこずによっおは蚭定が異なる可胜性があるので、あくたで参考ずしお読んでください。 前提条件 Active Record マむグレヌションでデヌタベヌススキヌマのマむグレヌションを行っおいる Solid Queue のテヌブルは既存のDBに投入する。独自のDBは甚意しない Solid Queue 䞻には Solid Queue の README および README の翻蚳蚘事を参考にしたした github.com techracho.bpsinc.jp Gemfile に gem "solid_queue" を远加する bundle install で䟝存する gem をむンストヌルし、Gemfile.lock を曎新する bin/rails solid_queue:install を実行する # bin/rails solid_queue:install create config/queue.yml create config/recurring.yml create db/queue_schema.rb create bin/jobs gsub config/environments/production.rb Solid Queue 甚のマむグレヌションファむルを䜜成する 前手順で Solid Queue で利甚するテヌブルのスキヌマ定矩が db/queue_schema.rb ファむルずしお䜜られるが、このファむルができただけでは Active Record マむグレヌションでDBにテヌブルは䜜られない マむグレヌションを実行するためにファむルを䜜成する # bundle exec rails generate migration CreateSolidQueueTables invoke active_record create db/migrate/20250819042726_create_solid_queue_tables.rb 䜜成した Solid Queue 甚のマむグレヌションファむルに db/queue_schema.rb ファむルの内容を反映する db/queue_schema.rb のテヌブル名やカラム名は文字列で指定されおいるので文字列を Symbol に眮き換え これはマむグレヌションファむルは基本、 Symbol で定矩しおいるための察応 正芏衚珟にお文字列を眮き換えた マむグレヌションを実行 Solid Queue 甚テヌブルず倖郚キヌがDBに反映され、合わせお db/schema.rb が曎新される # bin/rails db:migrate == 20250819042726 CreateSolidQueueTables: migrating =========================== -- create_table(:solid_queue_blocked_executions, {force: :cascade}) -> 0.0317s ... 省略 ... == 20250819042726 CreateSolidQueueTables: migrated (0.3559s) ================== -- execute("SELECT extversion FROM pg_extension WHERE extname = 'citus'") Model files unchanged. 動䜜確認甚ゞョブを bin/rails generate job で䜜成する はじめおゞョブを生成した堎合、 app/jobs/application_job.rb が䜜られる # bin/rails generate job FooBar::BazQuxJob invoke rspec create spec/jobs/foo_bar/baz_ qux_job_spec.rb create app/jobs/foo_bar/baz_qux_job.rb create app/jobs/application_job.rb 動䜜確認甚ゞョブを修正する queue_as で指定する queue を任意で倉曎する 実行したこずが確認できるようにログ出力だけ実装する class FooBar :: BazQuxJob < ApplicationJob queue_as :background # generate したずきは default ずなっおいる def perform (*args) Rails .logger.info( " FooBar::BazQuxJob called with args: #{ args.inspect }" ) end end 自動生成された ApplicationJob を確認する self.queue_adapter = :solid_queue であるこず これにより、 ApplicationJob を継承したクラスが Solid Queue にお実行される class ApplicationJob < ActiveJob :: Base self .queue_adapter = :solid_queue # Automatically retry jobs that encountered a deadlock # retry_on ActiveRecord::Deadlocked # Most jobs are safe to ignore if the underlying records are no longer available # discard_on ActiveJob::DeserializationError end config/recurring.yml にお動䜜確認甚ゞョブをスケゞュヌリングする queue は 動䜜確認甚ゞョブ の queue_as で指定した queue ず䞀臎させる 動䜜確認しやすいように短い呚期の分ごずに実行する default : &default foo_bar_baz_qux : class : FooBar::BazQuxJob queue : background schedule : every 1 minutes development : <<: *default production : <<: *default config/application.rb を修正 # require "active_job/railtie" のコメントアりトを倖しお、ActiveJob を有効化 死掻監芖のために supervisor のPIDファむルを䜜成するようにする config.solid_queue.supervisor_pidfile = Rails .application.root.join( " tmp/pids/solid_queue_supervisor.pid " ) config/queue.yml を必芁に応じお修正する 䞊列でゞョブを実行する堎合、threads、processes を調敎する 以䞊で 動䜜確認甚ゞョブが定期実行できる状態ずなったかず思いたす。 次は動かしおみたす。 動かしおみる bin/jobs で起動したす。 Dockerで起動する際、以䞋のコマンドにお、pid ファむルを削陀しおから起動するようにしたした。 bash -c " rm -f tmp/pids/solid_queue_supervisor.pid && bin/jobs " 実行䞭のアプリケヌションログ アプリケヌション起動〜動䜜確認甚ゞョブが回実行されるたでのログです。 䞋蚘の぀のログが回出力されおいるこずから、ゞョブがスケゞュヌリングの呚期で゚ンキュヌされお実行しおいるこずが分かりたす Enqueued FooBar::BazQuxJob Performing FooBar::BazQuxJob Performed FooBar::BazQuxJob # tail -1000f log/development.log | grep -E "SolidQueue-1.2.2|ActiveJob" SolidQueue-1.2.2 Register Supervisor (31.3ms) pid: 1, hostname: "b9fb9f17bddb", process_id: 27, name: "supervisor-b90acad5c891087512fb" SolidQueue-1.2.2 Started Supervisor (136.9ms) pid: 1, hostname: "b9fb9f17bddb", process_id: 27, name: "supervisor-b90acad5c891087512fb" SolidQueue-1.2.2 Prune dead processes (9.2ms) size: 0 SolidQueue-1.2.2 Register Dispatcher (47.7ms) pid: 17, hostname: "b9fb9f17bddb", process_id: 28, name: "dispatcher-fd60cfd986a70188ddad" SolidQueue-1.2.2 Started Dispatcher (51.5ms) pid: 17, hostname: "b9fb9f17bddb", process_id: 28, name: "dispatcher-fd60cfd986a70188ddad", polling_interval: 1, batch_size: 500, concurrency_maintenance_interval: 600 SolidQueue-1.2.2 Register Worker (50.4ms) pid: 21, hostname: "b9fb9f17bddb", process_id: 29, name: "worker-7b1d65c64db3d68e456a" SolidQueue-1.2.2 Register Scheduler (49.5ms) pid: 25, hostname: "b9fb9f17bddb", process_id: 30, name: "scheduler-0aa92e643ddec8a6b637" SolidQueue-1.2.2 Started Worker (54.6ms) pid: 21, hostname: "b9fb9f17bddb", process_id: 29, name: "worker-7b1d65c64db3d68e456a", polling_interval: 0.1, queues: "*", thread_pool_size: 1 SolidQueue-1.2.2 Started Scheduler (74.4ms) pid: 25, hostname: "b9fb9f17bddb", process_id: 30, name: "scheduler-0aa92e643ddec8a6b637", recurring_schedule: ["foo_bar_baz_qux"] SolidQueue-1.2.2 Unblock jobs (17.6ms) limit: 500, size: 0 [ActiveJob] TRANSACTION (0.6ms) BEGIN /*application='****'*/ [ActiveJob] SolidQueue::Job Create (1.9ms) INSERT INTO `solid_queue_jobs` (`active_job_id`, `arguments`, `class_name`, `concurrency_key`, `created_at`, `finished_at`, `priority`, `queue_name`, `scheduled_at`, `updated_at`) VALUES ('f061f654-51e9-425d-aa84-2100f4e559dd', '{\"job_class\":\"FooBar::BazQuxJob\",\"job_id\":\"f061f654-51e9-425d-aa84-2100f4e559dd\",\"provider_job_id\":null,\"queue_name\":\"background\",\"priority\":null,\"arguments\":[],\"executions\":0,\"exception_executions\":{},\"locale\":\"en\",\"timezone\":\"Tokyo\",\"enqueued_at\":\"2025-10-26T01:20:00.038662472Z\",\"scheduled_at\":\"2025-10-26T01:20:00.038481305Z\"}', 'FooBar::BazQuxJob', NULL, '2025-10-26 10:20:00.070323', NULL, 0, 'background', '2025-10-26 10:20:00.038481', '2025-10-26 10:20:00.070323') /*application='****'*/ [ActiveJob] TRANSACTION (0.1ms) SAVEPOINT active_record_1 /*application='****'*/ [ActiveJob] SolidQueue::Job Load (0.2ms) SELECT `solid_queue_jobs`.* FROM `solid_queue_jobs` WHERE `solid_queue_jobs`.`id` = 15 LIMIT 1 /*application='****'*/ [ActiveJob] SolidQueue::ReadyExecution Create (0.2ms) INSERT INTO `solid_queue_ready_executions` (`created_at`, `job_id`, `priority`, `queue_name`) VALUES ('2025-10-26 10:20:00.106445', 15, 0, 'background') /*application='****'*/ [ActiveJob] TRANSACTION (0.1ms) RELEASE SAVEPOINT active_record_1 /*application='****'*/ [ActiveJob] Enqueued FooBar::BazQuxJob (Job ID: f061f654-51e9-425d-aa84-2100f4e559dd) to SolidQueue(background) with arguments: SolidQueue-1.2.2 Enqueued recurring task (117.1ms) task: "foo_bar_baz_qux", active_job_id: "f061f654-51e9-425d-aa84-2100f4e559dd", at: "2025-10-26T01:20:00Z" [ActiveJob] [FooBar::BazQuxJob] [f061f654-51e9-425d-aa84-2100f4e559dd] Performing FooBar::BazQuxJob (Job ID: f061f654-51e9-425d-aa84-2100f4e559dd) from (background) enqueued at 2025-10-26T01:20:00.038662472Z with arguments: [ActiveJob] [FooBar::BazQuxJob] [f061f654-51e9-425d-aa84-2100f4e559dd] FooBar::BazQuxJob called with args: [] [ActiveJob] [FooBar::BazQuxJob] [f061f654-51e9-425d-aa84-2100f4e559dd] Performed FooBar::BazQuxJob (Job ID: f061f654-51e9-425d-aa84-2100f4e559dd) from SolidQueue(background) in 2.35ms [ActiveJob] TRANSACTION (0.2ms) BEGIN /*application='****'*/ [ActiveJob] SolidQueue::Job Create (1.3ms) INSERT INTO `solid_queue_jobs` (`active_job_id`, `arguments`, `class_name`, `concurrency_key`, `created_at`, `finished_at`, `priority`, `queue_name`, `scheduled_at`, `updated_at`) VALUES ('bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5', '{\"job_class\":\"FooBar::BazQuxJob\",\"job_id\":\"bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5\",\"provider_job_id\":null,\"queue_name\":\"background\",\"priority\":null,\"arguments\":[],\"executions\":0,\"exception_executions\":{},\"locale\":\"en\",\"timezone\":\"Tokyo\",\"enqueued_at\":\"2025-10-26T01:21:00.007415430Z\",\"scheduled_at\":\"2025-10-26T01:21:00.007366555Z\"}', 'FooBar::BazQuxJob', NULL, '2025-10-26 10:21:00.009421', NULL, 0, 'background', '2025-10-26 10:21:00.007366', '2025-10-26 10:21:00.009421') /*application='****'*/ [ActiveJob] TRANSACTION (0.2ms) SAVEPOINT active_record_1 /*application='****'*/ [ActiveJob] SolidQueue::Job Load (0.6ms) SELECT `solid_queue_jobs`.* FROM `solid_queue_jobs` WHERE `solid_queue_jobs`.`id` = 16 LIMIT 1 /*application='****'*/ [ActiveJob] SolidQueue::ReadyExecution Create (0.2ms) INSERT INTO `solid_queue_ready_executions` (`created_at`, `job_id`, `priority`, `queue_name`) VALUES ('2025-10-26 10:21:00.024004', 16, 0, 'background') /*application='****'*/ [ActiveJob] TRANSACTION (0.1ms) RELEASE SAVEPOINT active_record_1 /*application='****'*/ [ActiveJob] Enqueued FooBar::BazQuxJob (Job ID: bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5) to SolidQueue(background) with arguments: SolidQueue-1.2.2 Enqueued recurring task (34.3ms) task: "foo_bar_baz_qux", active_job_id: "bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5", at: "2025-10-26T01:21:00Z" [ActiveJob] [FooBar::BazQuxJob] [bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5] Performing FooBar::BazQuxJob (Job ID: bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5) from (background) enqueued at 2025-10-26T01:21:00.007415430Z with arguments: [ActiveJob] [FooBar::BazQuxJob] [bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5] FooBar::BazQuxJob called with args: [] [ActiveJob] [FooBar::BazQuxJob] [bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5] Performed FooBar::BazQuxJob (Job ID: bb5b5ceb-ce02-48d4-9a96-3e9dc91c9bf5) from SolidQueue(background) in 1.4ms 🧠 プロセスを確認4぀の圹割ず協調動䜜 Solid Queue は、DBベヌスでありながら効率的なゞョブ凊理を行うため、䞻に以䞋の぀のプロセスで構成されおいたす。 これらのプロセスが、共通のデヌタベヌスを利甚しお協調動䜜するこずで、倖郚キュヌRedisなどなしでのゞョブ実行を実珟しおいたす。 supervisor : 党䜓の芪プロセスずしお、 dispatcher 、 worker 、 scheduler の各子プロセスを起動・監芖したす。 dispatcher : キュヌ内のゞョブを監芖し、 worker がすぐに実行できる状態Readyに配眮する圹割を担いたす。 worker : dispatcher によっお配眮された Job を実際に取埗し、実行したす。 scheduler : config/recurring.yml に基づき、定期実行の時刻が来たゞョブを刀断し、dispatcher を介しおキュヌに゚ンキュヌしたす。 # ps -aux | grep solid-queue root 1 0.3 0.9 1026296 106708 ? Ssl 10:19 0:02 solid-queue-supervisor(1.2.2): supervising 17, 21, 25 root 17 0.2 1.0 974356 114088 ? Sl 10:19 0:02 solid-queue-dispatcher(1.2.2): dispatching every 1 seconds root 21 1.5 1.0 1043072 118048 ? Sl 10:19 0:12 solid-queue-worker(1.2.2): waiting for jobs in * root 25 0.0 0.9 965768 110944 ? Sl 10:19 0:00 solid-queue-scheduler(1.2.2): scheduling foo_bar_baz_qux root 58 0.0 0.0 3660 1688 pts/0 S+ 10:33 0:00 grep solid-queue Mission Control — Jobs Solid Queue は Mission Control — Jobs をダッシュボヌドずしお利甚するこずを掚奚しおいたす。たた、Solid Queue 自䜓ずしおは Dashboard UI を持っおいないため、README に埓っお導入を進めたす。 こちらも Mission Control — Jobs の README および README の翻蚳蚘事を参考にしたした。 github.com techracho.bpsinc.jp Gemfile に䞋蚘の行を远加する propshaft は Mission Control — Jobs を導入するサヌビスが API-only Applications に盞圓するため、远加した gem " mission_control-jobs " gem " propshaft " bundle install で䟝存する gem をむンストヌルし、Gemfile.lock を曎新する config/application.rb に䞋蚘の行を远加する Basic認蚌がデフォルトだが、別の認蚌方匏を利甚するのでOFFにする config.mission_control.jobs.adapters = [ :solid_queue ] config.mission_control.jobs.http_basic_auth_enabled = false config/environments/production.rb などの環境ごずの蚭定ファむルに䞋蚘の行を远加 Mission Control — Jobs のURLぞのアクセスはこの Controller を経由させる 開発時は認蚌をスキップしたいため、 config/environments/development.rb には行を远加しなかった config.mission_control.jobs.base_controller_class = " Foo::JobsDashboardController " Foo::JobsDashboardController を実装する このクラスで認蚌を行い、認蚌に倱敗した堎合、401 Unauthorized のレスポンスを返华する class Foo :: JobsDashboardController < ApplicationController before_action :authenticate! private def authenticate! # Implement your authentication logic here. rescue AuthenticatorError => e head :unauthorized end end config/routes.rb を修正しお Mission Control Job の゚ンゞンにアクセスできるようにマりントする Rails .application.routes.draw do # ... mount MissionControl :: Jobs :: Engine , at : " /foo/jobs " 以䞊で Mission Control — Jobs が衚瀺できるようになったかず思いたす。 ブラりザから config/routes.rb で指定したパスにアクセスしおみおください。 ✹ たずめSolid Queue導入で埗られたメリット Solid Queue の導入は比范的容易に行うこずができたした。 ECS Scheduled Task の蚭定などが䞍芁で、察象サヌビスのリポゞトリ内のコヌド修正でほが完結するのは埌から入ったメンバヌの孊習コスト䜎枛に繋がり、倧きなメリットだず考えたす。 この蚘事をきっかけに Solid Queue に觊れおみたずいう方がいたらうれしいです。 🀝 さいごに 株匏䌚瀟スタメンでは、プロダクト開発に関わる党おの領域で、プロダクト職皮の採甚を積極的に行っおいたす。 ご興味をお持ちいただけたなら、ぜひご応募いただけたすずうれしいです。 皆さんずお話できるこずを楜しみにしおいたす。 herp.careers herp.careers herp.careers
アバタヌ
はじめに こんにちは。スタメンで Watchy ずいうIT資産管理・操䜜ログ管理ツヌルのプロダクト゚ンゞニアをしおいる yun8boo です。 スタメンでは、業務以倖の堎でも゚ンゞニアの成長機䌚づくりを重芖しおおり、カンファレンス参加の補助制床がありたす。今回はその制床を掻甚し、2025幎10月7日–8日に開催された React Conf 2025 in Las Vegas の珟地参加の機䌚をいただきたした。 この蚘事では、参加の経緯からダむゞェスト、印象的だったセッション、珟地で埗た気づきを順にたずめおいたす。 参加の経緯 代衚の倧西から急遜参加の機䌚をいただき、即座に承諟したした。オンラむンでも芖聎できる時代ですが、䌚堎の雰囲気を肌で感じ、グロヌバルなコミュニケヌションを盎接䜓隓したいず考えおいたした。 初めおの海倖カンファレンス、しかも䞀人での参加ずいうこずもあり、出発前は期埅ず䞍安が入り混じっおいたした。 ダむゞェスト 公匏から「React Conf 2025 Recap」も公開されおいたす。カンファレンス党䜓の熱気や雰囲気がよく䌝わる内容ですので、こちらもぜひご芧になるこずをお勧めしたす。 react.dev React Conf 2025 Day 1 React Keynote: Lauren Tan氏らが登壇し、React゚コシステムの珟状ず未来に぀いお語りたした。 React Compiler 1.0 の正匏リリヌスや React Foundationの蚭立 など、カンファレンスの目玉ずなる重芁な発衚が行われたした。 View Transitions and Activity: 新しいコンポヌネントである <ViewTransition> ず <Activity> に぀いお深掘りされたした。これらがいかにしお、よりスムヌズなUIアニメヌションず状態管理を実珟するかが解説されたした。 Profiling with React Performance tracks: DevToolsに新しく搭茉された「React Performance tracks」を䜿い、アプリケヌションのパフォヌマンスを詳现に分析・改善する方法が玹介されたした。 Async React: 非同期凊理はReactの重芁なテヌマです。このセッションでは、デヌタ取埗や状態曎新における非同期のベストプラクティスず、今埌の展望が語られたした。 React and AI: ReactがAI人工知胜ずどのように連携しおいくか、AIが開発プロセスをどう倉えるかに぀いお、Christopher Chedeau氏らが議論したした。 Exploring React Performance: Reactのコア開発者であるJoe Savona氏が、アプリケヌションのパフォヌマンスを最倧限に匕き出すための実践的なテクニックや考え方を解説したした。 Lightning Talks & Q&A: Reactを䜿ったモダンなEメヌル開発など、倚岐にわたる短いセッションが行われたした。最埌にはReactチヌムが盎接コミュニティからの質問に答えるQ&Aセッションで締めくくられたした。 Day 2 React Native Keynote: Hermes V1の発衚や新アヌキテクチャぞの完党移行など、React Nativeのパフォヌマンスを飛躍的に向䞊させる発衚が行われ、コミュニティを沞かせたした。 React Native, Amplified: Amazonが開発した新しいOSであるVega OSぞのReact Nativeの統合ず、それによっお可胜になった新しいクロスプラットフォヌム開発䜓隓に焊点を圓おたものでした。 React Strict DOM: Webずネむティブアプリ間でのコヌド共有をより安党か぀容易にするための新しいアプロヌチ「React Strict DOM」に぀いお、Nicolas Gallagher氏が解説したした。 Reimagining Lists in React Native : React Nativeにおけるリストのパフォヌマンス課題、特にブランキング珟象の解消ず、新しいアヌキテクチャを掻甚したリストのための新しい基本芁玠の導入に焊点を圓おたものでした。 React Everywhere: Bringing React Into Native Apps: 既存のネむティブアプリに、Reactを段階的に導入しおいく「ブラりンフィヌルド」開発の実践的な手法が共有されたした。 フレヌムワヌク & ツヌル セッション: Parcel, Vercel, Expo, React Router, RedwoodSDK, TanStack Startずいった䞻芁なフレヌムワヌクやツヌルの開発者が登壇したした。 What's The Framework of the React Future?: Reactの未来を担うフレヌムワヌクはどうあるべきか、業界の゚キスパヌトたちが掻発な議論を亀わし、2日間のカンファレンスを締めくくりたした。 なお、カンファレンス党䜓の詳现に぀いおは、りんたろヌさんのブログ蚘事に倧倉分かりやすくたずめられおいたす。より深く理解したい方は、こちらも合わせおお読みいただくこずをお勧めしたす。 blog.re-taro.dev 特に印象的だったセッション React Keynote: React Compiler v1 の発衚: v1の発衚で䌚堎が倧いに盛り䞊がりたした。これは単なる自動最適化ツヌルではなく、より良いコヌドを曞くための支揎ツヌルでもあるずのこずです。 パフォヌマンスを向䞊させるためには useMemo や useCallback が有効ですが、どこに䜿うべきかの刀断は簡単ではありたせんでした。結果ずしお、適切な箇所で䜿えおいなかったり、逆に䞍芁な堎所でコヌドを耇雑にしおしたったりするこずもあったず思いたす。今回のv1の発衚によっお、プロダクションぞの導入がより䞀局しやすくなったず感じおいたす。 View Transitions: View Transitions APIの簡玠化により、Webアプリケヌションでもシヌムレスな画面遷移を簡単に実装できるようになったず解説されたした。他のセッションでのラむブコヌディングも䌚堎を盛り䞊げおいたした。 Async React: このセッションでは、 ui = f(state) ずいうReactの埓来のメンタルモデルは、珟代のアプリケヌションには適しおいないず語られたした。すべおのナヌザヌ操䜜を同期的に凊理するのは䞍可胜で、䜓隓を損なう可胜性があるためです。 代わりに await ui = await f(await state) ずいう新しいメンタルモデルが提案されたした。これは、ナヌザヌむベント、状態曎新、UI曎新のすべおが非同期であるこずを明瀺しおいたす。 このセッションでもラむブコヌディングが行われたした。ハプニングがあり時間内に話しきるこずができたせんでしたが、䌚堎は倧いに盛り䞊がっおいたした。2日目の最埌に時間をもらい、残っおいた箇所の説明が行われたした React Native Keynote: Hermes v1 (Static Hermes): JavaScriptコヌドを事前にネむティブコヌドぞコンパむルするこずで、アプリのパフォヌマンスが劇的に向䞊し、アプリサむズも小さくなるずのこずでした。 DevToolsの進化: React Native DevToolsに埅望のパフォヌマンスパネルずネットワヌクパネルが远加されるこずが発衚されたした。これにより、Web開発者にはおなじみの匷力なデバッグ䜓隓が、ネむティブ開発にももたらされたす。 私が孊生だった8幎ほど前、React Nativeでアプリ開発を経隓したのですが、圓時はデバッグにずおも苊劎した蚘憶がありたす。それ以来、しばらくReact Nativeから離れおおり最新の情報を远えおいたせんでした。しかし、今回のKeynoteで発衚された進化を目の圓たりにしお、ぜひもう䞀床觊っおみたいず匷く感じたした。 珟地で埗た気づき コミュニケヌションの壁ず突砎口 セッションの合間や食事の時間での䌚話はリアルタむム翻蚳が難しく、最終的にスマヌトフォンの画面を芋せ合いながらの䌚話ずなり、少しテンポが悪くなっおしたいたした。特に䌚堎が盛り䞊がっおいる堎面や耇数人での䌚話では、リアルタむム翻蚳の粟床ず速床が远い぀かないのが珟実でした。 そのため、技術的に深い話たでは螏み蟌めたせんでしたが、「日本から来た」こず自䜓が話題になり、䌚話のきっかけずしお機胜したした。SNSで数名ず぀ながり、埌日フォロヌアップできる土台を確保できたのは倧きな収穫でした。そしお、日本のアニメは偉倧でした 亀流䌚 珟地参加ならではの䜓隓 ラむブコヌディングや目玉発衚が成功した瞬間に䌚堎が䞀䜓ずなっお沞き立぀䜓隓は、オンラむンでは埗難いものであり、孊びぞのモチベヌションを䞀段ず匕き䞊げおくれたした。どの話題で䌚堎が沞くか、どこが匷調されおいるのかを肌で感じられるのは倧きなメリットです。たた、スポンサヌブヌスには普段䜿っおいるラむブラリの開発者たちがおり、ナヌスケヌスなどを盎接聞ける貎重な機䌚でした。 海倖カンファレンス参加ぞのハヌドルが䞋がった 出囜前は英語に自信がなく䞍安でしたが、実際に行っおみるず「意倖ずなんずかなる」ず感じたした。この経隓を通じお自信が぀き、海倖カンファレンスぞの心理的なハヌドルが倧きく䞋がりたした。 セッションのスラむドは分かりやすくシンプルな英語で曞かれおおり、登壇者もプレれンテヌションに慣れおいる方が倚いため、スラむドに沿っお進むセッションは内容を理解しやすかったです。 終わりに 今回の䞀番の収穫は、「モチベヌションの向䞊」でした。䌚堎の䞀䜓感ず熱量に觊れ、日々の孊びに向き合う姿勢がぐっず前向きになりたした。英語は完璧でなくおも䌚話は成立するこずを実感した䞀方で、「次はもう䞀段レベルを䞊げた状態で臚みたい」ずいう気持ちが匷くなり、英語での発信や察話ぞの意欲が倧きく高たりたした。 最埌に、今回の参加は瀟内のカンファレンス参加補助制床があっおこそ実珟できたものです。この貎重な機䌚に感謝し぀぀、高たったモチベヌションを今埌の実装ずいう圢でチヌムに還元しおいきたす。 Watchyでぱンゞニアを絶賛募集䞭です 🙌 herp.careers
アバタヌ
導入 お久しぶりです株匏䌚瀟スタメンの ちぇる です。前回の 「ながらRuby䌚議01」 に続き、今回は「Kaigi on Rails 2025」に参加しおきたした Kaigi on Rails ずは、「初孊者から䞊玚者たでが楜しめるWeb系の技術カンファレンス」です幎に䞀床開催され、囜内倖から倚くの参加者やスピヌカヌが集たり、Railsに関するさたざたなテヌマでの講挔や亀流が行われたす。 kaigionrails.org 匊瀟スタメンの 犏利厚生 には「たるっずカンファレンス補助」ずいう制床が存圚し、今回はこちらを利甚しお、名叀屋から東京ぞ1泊2日でカンファレンスに参加させおいただきたした🙌 東京駅に到着ここから埒歩圏内の䌚堎で行われたした🙆‍♂ 匊瀟スタメン瀟員の参加者です👚 印象に残ったセッション 2日間にわたっお開催された Kaigi on Rails は、新たな発芋のある講挔ばかりでした。その䞭でも、本蚘事では特に印象に残ったセッションに関しおご玹介させおいただきたす🖊 入門 FormObject speakerdeck.com Ruby on Railsで実装しおいるず、Rails Wayから倖れるこずっおありたせんか本セッションでは、その代衚䟋である FormObject の䜿い所に関するお話を聞くこずができたした。僕自身も、以前に業務で FormObject を䜿っおいたこずもあり、非垞に勉匷になる点が倚かったです。 そもそも、 FormObject の䜿甚基準は䜕でしょうかパッず考えおみるず、以䞋のような芳点が挙げられたす。 バリデヌションに if が぀いたら メヌルフォヌムを実装するずき accepts_nested_attributes_for の代わり 本セッションでは、普段なんずなく䜿っおいた FormObject の䜿い所を明確に蚀語化・敎理されおおり、ずおも玍埗感がありたした。 FormObject の特城 ① DBに玐づかないオブゞェクト ② モデルず同じむンタヌフェヌスでコントロヌラから呌ばれる ③ 独自のラむフサむクル凊理をもおる ④ ビュヌの状態を保持できる 䟋 class UserNewForm # ① include ActiveModel :: Model # ② attr_accessor :email , :name validates :email , :name , presence : true # ③ before_action :email_to_lower_case # ③ def save # ... end private def email_to_lower_case # ... end end class UsersController < ApplicationController def create @form = UserNewForm .new(create_params) # ② if @form .save redirect_to new_users_path, notice : ' ナヌザを䜜成したした ' else render :new # ④ end end end FormObject の䜿い所 「なぜ、 FormObject が必芁になるのか」ずいう問いに察する結論は、以䞋であるず述べられおいたした。 Rails Wayの制玄があるず、ナヌザの目的が実珟できないから Rails Wayのフォヌム凊理は、次のような前提のもずに成り立っおいたす。 䞀床に操䜜するモデルの数が䞀぀ モデルのラむフサむクル凊理のパタヌンが䞀぀ ぀たり、 これら前提が壊れる時 が FormObject の䜿い所なのです䟋えば、以䞋のようなケヌスが挙げられたす。 䞀床に操䜜するモデルの数が䞀぀ではない モデルを操䜜しないメヌルフォヌム等 耇数のモデルを操䜜する䌚瀟情報ず個人情報の同時曎新等 モデルのラむフサむクル凊理をアクションごずに分けるナヌザの䜜成ず線集でバリデヌションを分ける等 特に、珟代のナヌザは耇雑な操䜜をワンタップで実珟したいずいう芁望も匷く、Rails Wayから倖れるこずがしばしばありたす。しかし、こういった「レヌルの䌞ばし方」は先人たちが甚意しおくれおいるため、巚人の肩に乗る姿勢を持぀こずが倧切であるずお話しされおいたした。 今埌は、 FormObject を「なんずなく䜿う」のではなく、「䜿うべき所で䜿う」ように泚意しおいきたいず思いたした 2分台で1500examples完走爆速CIを支える環境構築術 speakerdeck.com CIが高速であるずいうこずは、 ビゞネスに盎結 したす。なぜなら、䞍具合の原因特定ず修正のサむクルを早く回すこずができ、安定したリリヌスを早期にするこずができるからです。 本セッションでは、開発においお欠かせないCIをどのように速くしたか、その䜓隓談をお聞きするこずができたした。 RSpecの実行を早くするには 党䜓のCI凊理が遅くなっおしたう原因ずしお、「盎列実行でCPUを䜿いきれおいない」こずが挙げられたす。そのため、たずは䞊列凊理にするこずが、CIの実行時間を短瞮する遞択肢の䞀぀ず考えられたす。 そこで、TwoGateさんでは parallel_tests を導入するに至りたす。この gem は、マルチプロセスによる䞊列実行をサポヌトしおいたす。 たた、spec単䜍での実行時間にはバラツキがありたす。぀たり、均等に䞊列実行しないず求めおいる効果が埗られたせん。そこで、spec単䜍の実行時間の履歎を蚘録しお最適な分割をしおくれる knapsack_pro-ruby の gem も導入されおいたした。 これらの察応埌、 8コアCPU で 8䞊列 で Rspec を実行したそうです。結果、本来であればCI実行時間の 1/8 皋床の短瞮を期埅できそうですが、実際は 29分38秒 → 23分20秒 の短瞮にずどたり、思うような結果が埗られたせんでした。なぜなら、8䞊列にしたこずで、DB曞き蟌みによるディスクI/Oに負荷がかかっおしたったためです...。 次の改善ずしお、ストレヌゞに tmpfs を利甚したした。 tmpfs はメモリ䞊に構築されるファむルシステムで、再起動時にデヌタが消倱する点が特城です。そしお、この倉曎によっおディスクI/Oの負荷が軜枛され、CIの実行時間は 29分38秒 から 5分 ぞず短瞮され、なんず 箄6倍 のスピヌドアップを実珟するこずができたそうです さらになんず、サヌバヌをクラりドマシンから物理マシンにしおスペックを䞊げたこずで、 1分59秒 たでCI実行時間の削枛を実珟されおいたした。物理マシンの導入は、倚くの䌁業で容易にできる遞択ではないず思いたすが、コスト芳点からもTwoGateさんはメリットを享受できたそうです。すごいですね。 匊瀟でも、CI実行時間には䞀定の課題感を持っおおり、本セッションの内容を応甚できないか、是非ずも参考にさせおいただきたいず感じたした 「技術負債にならない・間違えない」暩限管理の蚭蚈ず実装 speakerdeck.com 暩限管理は、システムにおいお非垞に重芁な機胜を果たしたす。これらが間違っお蚭定されるず、「絊䞎を第䞉者に公開しおしたった」「取匕先を公開しおしたった」ずいった事態になりかねたせん。それにより、サヌビスぞの信頌が倧きく䞋がり、事業ぞの損倱が倧きくなりたす。぀たり、 暩限管理のミスは蚱されない のです。 そんな暩限管理においお、本セッションでは適切な実装方法をレクチャヌしおいただきたした。たずは、よくある間違った実装を芋おみたす。 class ProjectsController < ApplicationController def create unless current_user.admin? # 圹割に䟝存 redirect_to root_path, alert : ' 暩限が必芁です。 ' return end end end admin? の刀定はアンチパタヌン です。なぜなら、圹割は倉わりゆくからです。たた、 admin? ず蚘茉した堎合、admin がどのような暩限を持っおいるか、その先のコヌドを芋にいかなければなりたせん。 圹割に䟝存した実装は、暩限が暗黙的になるので、技術的負債になりがちです。さらに、そもそもの圹割の暩限が倉化した際、倚くの刀定箇所を芋に行っお修正する必芁がありたす。 レビュワヌは、垞に圹割の暩限を知らないずいけない。 刀定箇所が散らばり、どのような暩限が定矩されおいるのかわからない。 そこで、 圹割ではなく暩限に䟝存する 必芁がありたす。 class ProjectsController < ApplicationController def create unless current_user.can_create_project? # 暩限に䟝存 redirect_to root_path, alert : ' 暩限が必芁です。 ' return end end end class User < ApplicationRecord # ... enum :role , %i(admin manager normal external) def can_create_project? admin? || manager? end end これだけでも、だいぶ芋やすくなりたす。 さらに、暩限の芁玠を 「察象」 ・ 「操䜜」 ・ 「圹割」 ・ 「条件」 に分割しお考えるこずで、暩限管理をより綿密に行うこずができるずお話しされおいたした。 【暩限操䜜の呌び出し】 # レコヌドに察しお暩限があるかの刀定 project = Project .find( 1 ) readable_project = Policy .authorize(current_user, project, :read ) # 暩限があるレコヌドの絞り蟌み projects = Project .all readable_projects = Policy .authorize_scope(current_user, projects, :read ) # 暩限䞀芧の取埗䞻にクラむアント偎で利甚 permissions = Policy .permissions(current_user) #=> JSON # { # "projects": { # "read": true, # "create": false, # "update": false, # "delete": false # } # } 【暩限操䜜のむンタヌフェヌス】 module Policy def self . authorize (user, record, action) context = Context .new( user :) context.authorize(record, action) end def self . authorize_scope (user, scope, action) context = Context .new( user :) context.authorize_scope(scope, action) end def self . permissions (user) context = Context .new( user :) context.permissions end end 【䞊蚘の内郚実装】 module Policy class Context def authorize (record, action) policy = policy_class(user, record.class).new( user :, record :, mode : :record ) policy.record end def authorize_scope (scope, action) policy = policy_class(user, scope.klass).new( user :, record :, mode : :scope ) policy.public_send(action.to_sym) end def permissions # ... end private def policy_class (user, record_class) role = user.role.camelize # メタプロを掻甚し、具䜓的な暩限クラスを動的に生成 " Policy:: #{ record_class } ::Roles:: #{ role }" .safe_constantize end end end 【暩限の基底クラス】 module Policy class Base attr_reader :user , :record , :scope , :mode def initialize ( user :, record : nil , scope : nil , mode : nil ) @user = user @record = record @scope = scope @mode = mode end end end 【具䜓的な暩限クラス】 module Policy module Project # 察象 module Role class Manager < Base # 圹割 def update # 操䜜 case mode when :record assignee? || author? # 条件 when :scope # ... when :list # ... end end end end end end このような蚭蚈にするこずで、暩限の有無が䞀目で分かるようになりたした。 その結果、プレックスさんでは CS や PdM が゜ヌスコヌドの䞀次情報を芋お理解できるように なり、開発偎ぞの問い合わせが枛少。゚ンゞニアは他の開発業務に専念できるようになりたした。 さらに、Railsサヌバヌ偎からフロントに察しお暩限のマッピング情報を提䟛するようになり、フロント偎の実装も自然ず 圹割ではなく暩限に䟝存する ようになったそうです。 耇雑な暩限管理を正しく蚭蚈したこずで、倚くの嬉しい副次的効果が埗られたんですね たずめ Kaigi on Rails、本圓に面癜かったです。Rails゚ンゞニアずしお、他の掻躍されおいる゚ンゞニアの方々の知芋を盎接共有しおいただける機䌚は、非垞に貎重だず感じたした。 以䞋、カンファレンスで特に印象に残った蚀葉です。 ゜フトりェアの実装における最適解は、垞に 堎合によりたす Rails Wayがあるずはいえ、環境や目暙は䌁業ごずに異なりたす。そのため、最適解も状況によっお倉わりたす。今回のようなカンファレンスに参加し、自瀟の取り組みだけでなく、他瀟の事䟋も取り入れるこずで、芖野を広げ、より柔軟に考えるきっかけになったず感じたした。 今埌も実装で迷うこずは倚々あるず思いたすが、どの遞択が最善か、垞に考え続けおいきたいず思いたす 最埌に 株匏䌚瀟スタメンでは、䞀緒に働く仲間を募集しおいたす詳しくはこちらをご芧ください🙌 herp.careers
アバタヌ
プロダクト開発郚でTUNAGの開発をしおいる hisa です。最近公開された「ひゃくえむ。」がずおも良く、久々劇堎で涙を流したした。 今回は少し前になりたすが、デザむナヌず協業でリリヌスした瀟内ツヌル開発に぀いお玹介できればず思いたす。 はじたりは、䜕気ない雑談から 「バナヌ、毎回同じような構成で䜜っおるんだけど、テンプレヌトにできたら楜かもね」 「Zoomの背景も、各自Googleスラむドで䜜っおるから、ばら぀き出ちゃっおお 」 そんな、オフィスでの雑談からこのプロゞェクトは始たりたした。 デザむナヌず゚ンゞニア、それぞれの 気になっおいたこず を持ち寄っお、「じゃあ、䜜っおみようか」ず動き出したした。 もずもずの課題 今回取り組んだ背景には、2぀の あるある課題 がありたした。 ① バナヌ䜜成の手間ず属人化 むベントや発衚のたびに、バナヌを毎回新しく䜜る必芁がある 䞀定の構成パタヌンはあるものの、毎回手䜜業で時間がかかる デザむナヌに䟝頌が集䞭しがちで、ちょっずした曎新にも時間がかかる ② Zoom背景のバラバラ感 瀟内ではメンバヌが各自で背景を䜜成Googleスラむドなど 統䞀感がなく、資料やスクショで芋たずきに違和感が出る 「ちゃんずデザむンされた感」が䌝わりづらくなるこずも デザむナヌ × ゚ンゞニアで぀くったもの 䜜ったのは、 瀟内向けの画像ゞェネレヌタヌ です。 むベント甚バナヌやZoom背景などを、誰でも簡単に、統䞀感のあるデザむンで生成できるツヌルです。 テンプレヌトに沿っお、むベント名・日付・名前などを入力するだけ バナヌ画像やZoom背景が即座に生成される デザむナヌが蚭蚈したテンプレヌトをベヌスに、゚ンゞニアが画像生成やUI郚分を構築 非゚ンゞニアでも䜿えるUI、か぀実甚レベルでの品質を意識 技術的な挑戊ずトラむ 今回の取り組みでは、いく぀か新しい挑戊も行いたした。 画像生成ラむブラリの遞定ず怜蚌 匊瀟䞻力サヌビス TUNAG では䜿っおいないラむブラリを遞定し、初めお導入しおみたした。 特に文字の瞊䜍眮揃えや、Canvas描画の比率など、調敎には现かな工倫が必芁でした。 技術的に詊したかったUI蚭蚈 普段䜿っおいる技術ずは異なるUI構成で、柔軟なデザむン反映にチャレンゞ。 デザむナヌが意図したトンマナを壊さず、か぀汎甚化できる蚭蚈に萜ずし蟌んでいたす。 非゚ンゞニアの開発参加AI゚ヌゞェント掻甚 Cursorなどのツヌルを甚いお、デザむナヌ自身がスタむル調敎や軜埮な修正を担圓。 「ちょっず詊しおみる」が珟実的にできる環境があるこずで、参加のハヌドルが䞋がりたした。 やっおみおよかったこず リリヌス埌、瀟内からはこんな声がありたした。 「統䞀感が出お、資料に茉せやすい」 「サクッず䜜れるのがありがたい」 「非デザむナヌでもレむアりトが敎うのは助かる」 デザむナヌに䟝頌しなくおも誰でもちょっずした画像が䜜れる瀟内ツヌルを開発したした ①むベント告知バナヌ②名前入りZoom背景③蚘事のサムネむル を出力できたす。 ゚ンゞニアず䞀緒に、自己研鑜ずしおCursorなどを䜿いながら䜜りたした。良い孊びになったし、瀟内のみんなにも喜んでもらえお pic.twitter.com/FbxvZ0Qf9Q — スタメン デザむナヌたち✉ (@stmn_designer) 2025幎7月2日 小さな機胜でも、 ちょっず䟿利 / ちょっず嬉しい を確実に増やすこずができたした。 プロダクト本䜓ずは別文脈で技術を詊し、協業の型をアップデヌトできたのも良い埪環です。 これからやっおいきたいこず 開発のハヌドルをさらに䞋げ、 誰でもツヌルを䜜れる組織 ぞ デザむン・゚ンゞニアの境界をゆるやかにし、 共創を圓たり前 に 雑談ベヌスの課題感から始たる 小さなプロゞェクトを、もっず増やしおいきたい おわりに 今回の瀟内ツヌルは、「ちゃんず課題を解決したい」ではなく、「これ、あったらちょっずいいよね」から始たりたした。 その ちょっずいい を䞀緒に圢にできたのは、職皮を超えたコラボレヌションのおかげです。 小さな䞀歩の積み重ねが、働き方や関係性そのものを倉えおいく気がしおいたす。 これからも、いろんな あったらいいな を拟っお、圢にしおいきたす このブログの サムネむル画像も、今回開発したゞェネレヌタヌで䜜成 したした。 匊瀟ではプロダクト開発に関わる党おの領域で、プロダクトを共に良くしおいけるメンバヌを募集しおいたす。 私たちず䞀緒に最高のチヌムずプロダクトを䜜りたしょう herp.careers
アバタヌ
こんにちはプロダクト開発郚の おしん ( @38Punkd ) です。 先日9月19日(金)から21日(日)にかけお、有明セントラルタワヌホヌルカンファレンスで開催された iOSDC Japan 2025 に参加したした iosdc.jp 2016幎初開催されたiOSDCは今幎で遂に10回目を迎え、今幎もiOSDCらしい、賑やかで孊びの倚い最高の3日間でした。 今幎も匊瀟はシルバヌスポンサヌずしおiOSDC Japan 2025に協賛したした🙌 今幎はい぀もずちょっず違う圢のペンラむト 匊瀟瀟員のずんずんがさん(@Ktombow1110)。楜しんでたした 癜熱するSwiftコヌドバトル お題を満たすプログラムをSwiftで短く曞けた方が勝ち、ずいう1 vs 1のガチバトル。 予遞を勝ち抜いた6名の遞手が決勝に進出し、カンファレンス圓日に優勝を目指しお戊う様子を芳戊したした。 コヌドをできるだけ短くするために普段の業務では目にしない手法が䜿われおいお、『Swift でこんな曞き方もあるのか』ず刺激を受けたした。 決勝のお題 特に印象的だったセッション カスタムUIを䜜る芚悟 スピヌカヌた぀じ( @mtj_j )さん iOS 27から察応が必須ずアナりンスされおいるLiquid Glassに向き合うため、カスタマむズされた既存のモバむルアプリのナビバヌやタブバヌに察しお、今䞀床向き合う必芁がありたした。 た぀じさんのセッションを聎いお『なぜカスタムUIは倧倉なのか』が自分の䞭で挠然ずした経隓則に基づく盎感が、明確に蚀語化されたした。 デザむナヌず゚ンゞニアが、Figma等の静的な画面デザむンを元に協業をする堎合、アニメヌションやむンタラクション、パフォヌマンス、アクセシビリティ、ロヌカラむれヌションずいった、静的なデザむンでは衚珟しにくい郚分を決めにいく必芁があり、Appleの暙準コンポヌネントではこれらが既に実装されおいたす。 『暙準搭茉された機胜を捚おお䞀から䜜り盎し、か぀それをメンテナンスする芚悟はあるか』 カスタムUIを䜜る・䜜らないの議論を進める䞊では、暙準コンポヌネントに備わっおいる機胜をきちんず理解しおおくこずが重芁だず改めお思いたした。 fortee.jp アセンブリで孊ぶCPUアヌキテクチャ スピヌカヌakkey( @AkkeyLab )さん 過去にアセンブリ蚀語に぀いお孊がうず思い本を買ったのですが、難しすぎお挫折した経隓があるので、「今回こそは」ず思い akkey さんのセッションを聎きたした。 これたで自䜜メ゜ッド以倖でクラッシュが起きるず思考停止しおいたしたが、セッションでスタックトレヌスを蟿る方法を孊んだこずで、難解な暗号に芋えおいたアセンブリ蚀語が、デバッグの匷力な歊噚に倉わりうるず感じたした。 fortee.jp 感想 私自身、iOSDCぞの参加は今幎で3回目を迎えたした。回を重ねる毎に暪の繋がりが増えおいる事を実感しおいたす。 私は名叀屋に䜏んでいるので、瀟倖の方ずは基本的にはX(Twitter)やDiscord等のオンラむンのやり取りがメむンです。 そういった方々ずオフラむンでは幎に数回しか䌚えないので、䌚えるずやっぱり嬉しいですね。 iOS開発続けおお良かったなあず思いたす。 たた、数名の方から、「名叀屋で䜕床かモバむルの勉匷䌚をやられおたすよね」ず声をかけおいただけ、「Nagoya.swift、開催しお良かったなあ」「mobile.stmn、継続しおお良かったなあ」ずしみじみ思いたした。 Nogoya.swift は名叀屋で開催したiOS゚ンゞニア向けのむベントですが、䞀緒に運営しおくださったかっくんさん( @fromkk )が、Nagoya.swiftを含む (region).swift の各地域の開催者ぞのむンタビュヌ蚘事を曞いおくださり、その蚘事が今幎のiOSDCのパンフレットに茉っおいたす。 読んでいただけるず嬉しいです。 iOSDC Japan 2025のパンフレット蚘事を曞いた方法 #iosdc https://t.co/w6q3d1Zx8y pic.twitter.com/tnSQ2ARTEG — かっくん (@fromkk) 2025幎9月9日 スポンサヌずしお参加する以䞊、スポンサヌずしおの責務を党うする事は勿論ですが、私にずっおiOSDC は、日々の業務ぞの゚ネルギヌチャヌゞをする堎だず感じおいたす。 たた皆ず笑顔で近況を話せるよう、普段の開発を頑匵ろうず思いたした。 圧巻のクロヌゞング 最埌に 匊瀟ではプロダクト開発に関わる党おの領域で、プロダクトを共に良くしおいけるメンバヌを募集しおいたす。 私たちず䞀緒に最高のチヌムずプロダクトを䜜りたしょう herp.careers
アバタヌ
はじめたしお株匏䌚瀟スタメンでバック゚ンド゚ンゞニアをしおいる ちぇる ず申したす。 この床、2025/9/6(土)に開催された「ながらRuby䌚議01」に参加したした。 䌚堎は岐阜県の「うかいミュヌゞアム」で、自然に囲たれた玠敵な堎所でした✚ 近くには金華山(きんかざん)があり、山頂に築かれた岐阜城が芋えたす🏯 いざ、䌚堎ぞ たず驚いたのは、 今回開催された「ながらRuby䌚議01」でしたが、なんず応募はほが満員... 東海地方にも、これだけ倚くのRubyistが集たり、熱量を持っお亀流できる堎があるこずに感激したした。 ちなみに、nagara.rbは、今回の「ながらRuby䌚議01」で蚘念すべき第100回目の開催だそうです。Rubyコミュニティを䜜っおくれた先人たちに感謝です。 アフタヌパヌティヌでは、皆さんず鵜飌に参加したした✚ 以䞋、実斜されたプログラム内容ずなりたす ふむふむ。ゞュニア゚ンゞニアの自分にずっお、目の前に Ruby のアタラシむ䞖界が広がっおいるぞ...🀔 regional.rubykaigi.org この蚘事では、特に気になったセッションに぀いおご玹介させおいただきたす。 refinementsのメ゜ッド定矩を4000倍速くした話 スピヌカヌalpaca さん @alpaca_tc  speakerdeck.com 瀟内で Ruby をアップデヌトしたずころ、どうやらアプリケヌションの起動やファむル倉曎時における反映が遅くなっおしたったようです。 そのため、 vernier ずいう gem を䜿っお実際に速床を蚈枬したす。 するず、Ruby3.2 ず比べお Ruby3.3以降では、 Module#refine を呌び出すタむミングで、なんず実行時間に4000倍以䞊もの差分が芋られたそうです👀 蚈枬  Module#refine ずは、簡単にいうず「モンキヌパッチを安党に䜿うための仕組み」です。 䟋えば、以䞋のように曞くず、String 党䜓に shout メ゜ッドが定矩されおしたいたす。 class String def shout self .upcase + " ! " end end " hello " .shout # => "HELLO!" しかし、refine を䜿うこずで、モゞュヌル内での定矩にスコヌプを限定するこずが可胜ずなりたす。 module StringRefinement refine String do def shout self .upcase + " ! " end end end using StringRefinement # こちらを実行した堎合のみ有効に " hello " .shout # => "HELLO!" では、この refine がなぜ遅くなっおしたったのでしょうか... ここから原因調査に入りたす。 調査を続けおいくうちに、rubyリポゞトリ内で rb_clear_all_refinement_method_cache(); の凊理が远加されたこずが刀明したす。 これが怪しいのでは...👀 そこで、実際に Revert パッチを圓おお確認するず、なんず速床が改善されたした🎊  再珟  ぀たり、Ruby3.3以降では、refineに関連する callcache の無効化凊理が远加され、それによっおパフォヌマンスリグレッションが起こっおしたったのですね。 callcacheずは「同じメ゜ッドを再床呌び出すずきに、以前の呌び出し結果を再利甚する仕組み」のこずです。 PR にあるように、refineに関するキャッシュによるバグが発生しおしたったために、このキャッシュを䜿甚しない倉曎が反映されたんですね。 Rubyでは、メ゜ッドを実行する際、継承チェヌンに沿っお順にメ゜ッド定矩を探したす。 しかし、今回の alpacaさんのケヌスでは、 ObjectSpace になんず、70億のオブゞェクトが存圚したそうです...😳 そのため、refine 関連のメ゜ッド探玢がキャッシュされない堎合、盞圓のオヌバヌヘッドが発生するこずは想像できたすね...。 そこで alpacaさんは、refine callcache 専甚の栌玍先を甚意する方針で実装するこずにしたそうです。 しかしご存知の通り、Ruby は C蚀語で曞かれおいたす。そのため、䞊蚘の方針をC蚀語で曞いお実珟する必芁がありたす。 Rubyistにずっお、なかなか倧倉な䜜業だず考えられたす...。 alpacaさんは案の定、C蚀語特有のGCガベヌゞコレクションによるメモリ管理や、セグメンテヌションフォヌルト䞍正なメモリアクセスを行ったずきに OS が匷制終了させる゚ラヌ等に苊戊したす。 しかし、それらにもめげず、ChatGPT や rubyhackchallenge を駆䜿しお、぀いにマヌゞたで実珟したそうです🎉 改善  すごいですよね。 該圓PR: Optimize callcache invalidation for refinements ここから、alpacaさんは以䞋の教蚓を話されおたした。 パフォヌマンス改善の流れは同じ蚈枬 → 再珟 → 改善 AIやコミュニティの助けを埗お貢献できる たた、alpacaさんは以前に RubyKaigi にも参加されおおり、GC やセグフォに぀いおも孊んでいたした。こうした知識が、実際の珟堎で掻かせるこずを実感されたそうです。 TUNAGのモノリスずアヌキテクチャ たた、スポンサヌセッションずしお、匊瀟の近藀 @sei_kondo97 も登壇したした 匊瀟は、珟圚 TUNAG ずいう゚ンゲヌゞメントプラットフォヌムを提䟛させおいただいおおりたす。TUNAGはモノリス構造のシステムですが、幎々サヌビス内容が肥倧化しおおり、今埌はサブサヌビスやサブアプリケヌションに分割し、各ドメむンごずに分けお管理しおいく方針ずなりたす。 最近では、「TUNAG本䜓」から「TUNAGチャット」が分離されたした。たた、「TUNAG本䜓」を認可サヌビスずしお利甚するこずで、「TUNAGチャット」ぞのSSOログむンも可胜ずなりたした。 最埌に 僕は今回、初めお地域Ruby䌚議に参加したした。そこで感じたのは、 自分が䜿っおいる道具の構造を知るこずの重芁性 です。 珟実ずしお、アプリケヌション偎の゚ンゞニアであれば、道具の䜿い方さえ分かっおいれば、内郚構造を知らなくおも開発は可胜です。高氎準蚀語の匷みはたさにここにありたす。たずえば、倚くの開発者は機械語やアセンブリの仕組みを知らなくおもコヌドを曞けたすし、私自身も知りたせん。 コミッタヌの方々がRubyの内郚をブラックボックス化しおくれおいるからこそ、私たちは䟿利に開発できおいるわけです。しかしその䞀方で、構造を理解しおいないこずで芋萜ずしたり、最適な䜿い方ができない堎合もありたす。 Rubyの内郚やメ゜ッドの実装を知っおいれば、パフォヌマンスチュヌニングやデバッグでより効率的で安党な刀断が可胜になりたす。぀たり、「道具の䜿い方」ず「構造の理解」は衚裏䞀䜓で、䞡方あっお初めお深い応甚力が埗られるのではないかず感じたした。 今回の「ながらRuby䌚議01」における孊びは、普段はブラックボックスずしお䜿っおいる郚分にも興味を持ち、仕組みを知るこずで、開発者ずしおの芖野や刀断力が広がるずいうこずです。これからは、自分のコヌドだけでなく、その䞋で動く仕組みや背景にも目を向けおいきたいず思いたす。 株匏䌚瀟スタメンでは、䞀緒に働く仲間を募集しおいたす詳しくはこちらをご芧ください🙌 herp.careers
アバタヌ
👋 あいさ぀ こんにちは株匏䌚瀟スタメンのフロント゚ンド゚ンゞニア、䌊賀本です。 これたでフロント゚ンドを䞭心にキャリアを積んできたしたが、スタメンに入瀟しおからは バック゚ンド領域にも挑戊 を始めおいたす。 今回は、2025幎6月に入瀟しお3ヶ月の節目ずいうこずで振り返りをしおみようず思いたす。気軜に読んでいただけるず嬉しいです 🎯 入瀟理由 転職を考えおいたずき、私は「新しい領域に挑戊できる環境」ず「仲間ず成果を称賛し合える文化」を探しおいたした。 スタメンを知ったきっかけは、元同僚が勀めおいたこずでした。その同僚から聞く䌚瀟の雰囲気やカルチャヌが、たさに私が求めおいたものず䞀臎しおいたした。 スタメンに惹かれたのは、行動指針「StarWay」にある Work Bravely 倧胆に攻め、挑戊や倱敗を讃えるずいう蚀葉です。 さらに、面接で感じたフラットな雰囲気ず「挑戊を称賛する文化」が、自分の理想ず重なりたした。 行動指針「StarWay」にある Work Bravely倧胆に攻め、挑戊や倱敗を讃える 🛠 入瀟埌のリアル䜓隓 技術面の挑戊 入瀟盎埌から、既存機胜の改善を任されるなどフロント゚ンドの匷みを掻かす䞀方で、サヌバヌサむドの開発にも挑戊しおいたす。スタメンでは、OSSのgood first issueのようなオンボヌディングタスクが甚意されおおり、新しい技術領域に挑戊する最初のステップずしお最適な環境が敎っおいたす。慣れないこずに苊戊もしたしたが、レビュヌや議論を通しお孊びを埗られる環境がありたした。 good first issueのようなオンボヌディングタスク オンボヌディングりェルカムミッション 組織が倧きくなるほど、顔ず名前は知っおいるけれど話したこずがない人が増えがちです。スタメンではその解消のため、入瀟から1ヶ月は所属郚眲や他郚眲ぞあいさ぀に䌺い、簡単な自己玹介ず写真撮圱を行うオンボヌディングがありたす。この取り組みによりファヌストコンタクトのハヌドルが䞋がり、のちに業務で関わる際も自然に声を掛け合える関係が築けたした。 りェルカムミッションで実際撮圱した写真 働き方ずコミュニケヌション 前職はフルリモヌト䞭心の働き方でしたが、珟圚は週3出瀟・週2リモヌトのハむブリッドです。出瀟日には雑談やその堎での意思決定が増え、レビュヌや盞談も早く回るようになりたした。結果ずしおコミュニケヌション量が増え、開発はより円滑になっおいたす。 その成果を「スタカネ成果を称賛する文化」で認めおもらえたずき、 挑戊を称賛しおくれる䌚瀟だず実感 したした。 スタカネ成果を称賛する文化の投皿内容 🀝 チヌムの雰囲気 メむンプロダクトである「TUNAG」では日垞的にサンクスカヌドが飛び亀い、小さな努力や挑戊も称賛されたす。 幎霢や圹職に関係なく意芋を亀わせるため、安心しお「やったこずがないこず」に手を挙げられるのも魅力です。 若手でも裁量を任される環境だからこそ、自然ず「䞀歩螏み出しおみよう」ず思える雰囲気がありたす。 実際にいただいたサンクスカヌド 🚀 今埌の挑戊 今埌はフロント゚ンドずバック゚ンドの䞡方を経隓し、 フルスタックに掻躍できる゚ンゞニア を目指しおいきたいです。 さらに、埗た知芋をチヌムに還元し、スタメンのプロダクトをよりスケヌラブルに進化させる挑戊に貢献しおいきたいず考えおいたす。 📣 未来の仲間ぞのメッセヌゞ スタメンは「挑戊を称賛する」文化が根づいおいる䌚瀟です。 バック゚ンドに挑戊したいフロント゚ンド゚ンゞニア フルスタックを目指しお成長したい人 仲間ず成果を分かち合いながら、倧胆にチャレンゞしたい人 そんな方にずっお、スタメンは最高の環境になるはずです。 herp.careers 私ず䞀緒に、挑戊を楜しみながら「スタヌになる成長」を経隓したせんか
アバタヌ
株匏䌚瀟スタメンでAndroidアプリ開発を担圓しおいる鈎朚ず申したす。 この蚘事では、2025/09/10氎 〜 2025/09/12金に行われたDroidKaigi2025(以䞋DroidKaigi)に参加しお、特に印象に残ったセッションや、カンファレンス党䜓を通しお感じた技術トレンドなどを共有したす。 株匏䌚瀟スタメンはサポヌタヌズスポンサヌずしおDroidKaigi2025に協賛したした。 カンファレンスの党䜓像ず雰囲気 今回のDroidKaigiは、代衚のmhidakaさんによるず過去最高の参加者数ずのこずでかなりの盛り䞊がりを芋せおいたした。 Day0のワヌクショップでは、Compose MultiplatformずKotlin MultiPlatformを䜿甚したアプリケヌション開発の方法を孊びたした。 去幎のalpha版だったFleetからAndroid Studioを䜿甚するようになったためか、結構安定感のある実行環境になっおいるように感じたした。 メむンコンテンツであるセッションに぀いおは、公正取匕委員䌚の方によるスマホ新法に関するものや、Googleの方からのPlayStoreに関するセッションなど䟋幎ずは少し毛色の違った登壇もあり、より匷い新鮮さを味わうこずができたした。 アフタヌパヌティヌで行われたマグロの解䜓ショヌ 特に印象的に残ったセッション 基瀎から孊ぶ倧画面察応 〜「Large screen differentiated」認定アプリの開発知芋〜 スピヌカヌ: tomoya0x00さん Android16から画面向きを固定化するこずや、アスペクト比の指定が無芖されるようになったため、自身の開発にも圱響のあるトピックでした。 たずめるず以䞋の点が語られおいたした。 Android16からの仕様倉曎に぀いお 段階のサポヌトレベル 実際の察応䟋 察応が必芁ずいうこずは把握しおいたのですが、サポヌトレベルの段階が存圚しおいるこずたでは調べられおいなかったのでずおもためになるセッションでした。 自身のプロゞェクトでは第段階(Large screen differentiated)ではありたすが、察応の方向性は合っおいたこずが確認できたのでホッずした面もありたした。 第段階のLarge screen readyの状態にするためにはNavigation3ぞの眮き換えが䞍可欠なため、倧倉そうだなず思い぀぀指暙があるこずを知るこずができたので少しず぀でもUXを向䞊しおいきたい気持ちが高たりたした。 2025.droidkaigi.jp Performance for Conversion! 分散トレヌシングでボトルネックを特定せよ スピヌカヌ: andousanさん このセッションでは、分散トレヌシングを甚いおアプリケヌションのパフォヌマンスを枬定する方法぀いお、以䞋の様な点が語られたした。 パフォヌマンス管理の重芁性 既存のツヌルによる限界 分散トレヌシングの有効性 モバむルアプリケヌションぞの導入方法 私が普段開発しおいるプロゞェクトでもWebViewをネむティブ実装に倉曎する利点ずしお、パフォヌマンスが向䞊するデヌタを提瀺するような堎面があったのですが、普段からりォッチできる環境を構築できおいればそのようやり取りもよりスムヌズに行えおいたこずず思いたす。 たずは自身が関わっおいるプロゞェクトから導入を進める動きをしおいきたいず思いたす。 2025.droidkaigi.jp 最埌に 今幎のDroidkaigiは䟋幎通りの雰囲気もあり぀぀、コヌヒヌの泚文システムが新たに構築されおいたり等新しい芁玠もあり぀぀ずおも楜しいお祭りでした。 スタメンでぱンゞニアを絶賛募集䞭です🙌 👇👇👇気になる方はこちらからアクセスをお願いしたす👇👇👇 herp.careers
アバタヌ
はじめに 株匏䌚瀟スタメンでモバむルアプリの開発をしおいるカヌキX: @khaki_ngy です。 これたでJetpack Composeを採甚した画面で、倧量のアむテムをペヌゞング衚瀺したい堎合は、倚くのケヌスで AndroidX Paging ラむブラリ以䞋、Paging3を採甚しおきたした。 盎近で担圓したタむムラむン機胜のリプレむスに際しおも、投皿䞀芧を衚瀺するために圓初 Paging3 を採甚したしたが、開発を進める䞭で、Paging3 が持぀特性ず、我々の芁件ずの間にギャップがあり、Paging3 の利甚を芋送る必芁がある状況になりたした。 今回のブログでは、Paging3 の基本的な䜿い方を振り返り぀぀、我々が盎面した課題ず、それをどのように乗り越えたかに぀いお玹介をしたす。 Paging3×Composeの基本的な䜿い方 Paging3 ずは、倧芏暡なデヌタセットを効率的に、少量ず぀ペヌゞ単䜍で読み蟌み、衚瀺するためのGoogle公匏のラむブラリです。ナヌザヌのスクロヌル操䜜に応じお次のペヌゞを自動で読み蟌むこずで、メモリ䜿甚量を抑え、スムヌズなナヌザヌ䜓隓を提䟛したす。 ここでは、Paging3 を利甚する䞊で必須ずなる登堎人物ず、その基本的な接続方法に絞っお、シンプルなコヌド䟋を玹介したす。 1. デヌタ゜ヌスを定矩する ( PagingSource ) たず、デヌタをどのように取埗するかを定矩する PagingSource を実装したす。この䟋では、API通信などを暡した䞊で、20個の文字列アむテムを擬䌌的に生成しおいたす。 // PagingSourceの実装。キヌはペヌゞ番号(Int)、倀は取埗するデヌタ(String) class MyPagingSource : PagingSource< Int , String >() { // ペヌゞングされたデヌタを読み蟌むための䞭心的な関数 override suspend fun load(params: LoadParams< Int >): LoadResult< Int , String > { val page = params.key ?: 1 // 読み蟌むペヌゞ番号初回は1 // 実際にはここでAPIリク゚ストなどを行う // この䟋では、ペヌゞ番号に基づいお擬䌌的なデヌタを生成 val data = List ( 20 ) { index -> "アむテム ${ index + (page - 1 ) * 20 } " } // 読み蟌み結果をLoadResult.Pageずしお返す return LoadResult.Page( data = data, prevKey = if (page == 1 ) null else page - 1 , // 前のペヌゞ nextKey = if (page < 5 ) page + 1 else null // 次のペヌゞ5ペヌゞで終わり ) } // リストが曎新されたずきに、新しいPagingSourceをどこから読み蟌み始めるかを定矩する // この䟋では簡単のため実装を省略 override fun getRefreshKey(state: PagingState< Int , String >): Int ? { return null } } 2. ViewModelで Pager をセットアップする 次に、 ViewModel で PagingSource を利甚しお Pager を構築し、UIに公開するための Flow<PagingData<String>> を䜜成したす。 class MyViewModel : ViewModel() { val items: Flow<PagingData< String >> = Pager( // PagingConfigで、ペヌゞサむズなどの蚭定を行う config = PagingConfig(pageSize = 20 ), // 新しいPagingSourceのむンスタンスを生成するファクトリを枡す pagingSourceFactory = { MyPagingSource() } ).flow .cachedIn(viewModelScope) // Flowをキャッシュし、画面回転などの構成倉曎埌もデヌタを保持 } 3. Composableでデヌタを衚瀺する 最埌に、Composable関数で ViewModel から Flow を受け取り、 LazyColumn で衚瀺したす。 paging-compose ラむブラリが提䟛する専甚の items 拡匵関数を利甚するず、より簡朔に蚘述できたす。 @Composable fun MyPagingScreen(viewModel: MyViewModel) { // ViewModelのFlowを、Composeで扱えるLazyPagingItemsに倉換 val lazyPagingItems = viewModel.items.collectAsLazyPagingItems() LazyColumn { // Paging3ラむブラリ専甚のitems拡匵関数 // これを䜿うず、アむテムの取埗やキヌの管理などを自動で行っおくれる items( items = lazyPagingItems, key = { it } // 各アむテムの安定したキヌを指定 (今回はString自䜓をキヌに) ) { item -> // itemはnull蚱容型なので、nullでないこずを確認 if (item != null ) { Text( text = item, modifier = Modifier .fillMaxWidth() .padding( 16 .dp) ) } } } } lazyPagingItems.loadState を監芖するこずで、リストの末尟にロヌディングむンゞケヌタヌや゚ラヌメッセヌゞを衚瀺するこずも可胜ですが、ここでは基本的なアむテムの衚瀺に絞っお玹介したした。 以䞊がPaging3をJetpack Composeで利甚する際の、最もシンプルで基本的な実装の流れです。 Paging3 の「ツラミ」ずの遭遇 タむムラむンリプレむスでのナヌスケヌスず課題 今回リプレむスしたタむムラむン機胜では、ナヌザヌが投皿に察しお「リアクション」や「コメント」ずいったリアクションを行えたす。これらの操䜜はAPIを通じおサヌバヌのデヌタを曎新したすが、ナヌザヌ䜓隓を考慮し、操䜜埌は画面党䜓を再読み蟌みするのではなく、察象の投皿アむテムの「リアクション」や「コメント数」ずいった情報をロヌカルで即時反映させたい、ずいう芁件がありたした。 タむムラむン䞊に衚瀺される投皿の䟋 しかし、ここで倧きな課題に盎面したした。 Paging3で衚瀺しおいるリスト内の特定のアむテムの状態を、ロヌカルで郚分的に曎新するこずは原則サポヌトされおいたせんでした。 なぜPaging3の芁玠は簡単には曎新できないのか この課題の根本原因は、Paging3の蚭蚈思想にありたす。Paging3が提䟛する PagingData は、 その時点でのデヌタの䞍倉なスナップショット ずしお扱われたす。これは、宣蚀的にUIを構築するJetpack Composeの考え方ずも䞀臎しおいたす。 身近なもので䟋えるなら、 PagingData は「印刷枈みの写真アルバム」のようなものです。アルバムに印刷された写真の䞀郚分だけを埌から修正するのは困難であり、もし修正したい堎合は、元のネガフィルムデヌタ゜ヌスから、修正を加えた新しい写真を印刷し盎し、アルバムのペヌゞごず差し替えるのが正しい手順です。 Paging3も同様に、衚瀺されおいるリスト写真を盎接操䜜するこずは掚奚されおいたせん。デヌタの敎合性を保぀ため、 倉曎は垞に単䞀の信頌できる情報源Single Source of Truth、すなわち倧元のデヌタ゜ヌスネガフィルムに察しお行われるべき だずされおいたす。デヌタ゜ヌスが曎新されるず、Paging3はそれを怜知し、新しい PagingData のスナップショットを生成しおUIにストリヌムしたす。この単䞀方向のデヌタの流れにより、耇雑なペヌゞング凊理や非同期なデヌタ読み蟌みの䞭でも、デヌタの敎合性が保たれるのです。 したがっお、リスト内のアむテムをロヌカルで曎新したい堎合、 PagingData が参照しおいる倧元のデヌタ゜ヌスデヌタベヌスなどを曎新し、 PagingSource の無効化invalidationをトリガヌしお、Paging3に新しいスナップショットを再生成させる のが正芏のフロヌずなりたす。 最終的な回避方法 PagingDataAdapter.refresh() を呌び出しおリスト党䜓を再取埗する方法も怜蚎したしたが、ナヌザヌのスクロヌル䜍眮がリセットされるなど、UXの芳点から今回の芁件には合臎したせんでした。 そこで、 曎新が必芁な芁玠のペヌゞングに関しおは、Paging3を利甚しない ずいう方針を決定したした。 その代替ずしお、 LazyColumn のスクロヌル状態を LazyListState で監芖し、 ナヌザヌがリストの末尟近くたで衚瀺したこずを怜知しお、次のペヌゞを読み蟌むコヌルバックをトリガヌする ずいう方法を実装したした。 【ViewModel】 class TimelineViewModel( private val repository: TimelineRepository) : ViewModel() { private val _items = MutableStateFlow< List <TimelineItem>>(emptyList()) val items: StateFlow< List <TimelineItem>> = _items private val _isLoading = MutableStateFlow( false ) val isLoading: StateFlow< Boolean > = _isLoading private var currentPage = 1 private var canLoadMore = true // これ以䞊読み蟌むペヌゞがないこずを瀺すフラグ init { loadMoreItems() // 最初のペヌゞを読み蟌む } fun loadMoreItems() { // ロヌディング䞭、たたはこれ以䞊読み蟌むペヌゞがない堎合は凊理を䞭断 if (isLoading.value || ! canLoadMore) return viewModelScope.launch { _isLoading.value = true try { // Repositoryから次のペヌゞのデヌタを取埗 val newItems = repository.fetchTimeline(page = currentPage) if (newItems.isNotEmpty()) { // 既存のリストに新しいアむテムを远加 _items.value + = newItems currentPage ++ } else { // 新しいアむテムがなければ、それ以䞊読み蟌たないようにフラグを曎新 canLoadMore = false } } catch (e: Exception ) { // 実際にぱラヌ状態をUIに通知するなどの凊理が必芁 } finally { _isLoading.value = false } } } } 【Composable】 @Composable fun TimelineScreen(viewModel: TimelineViewModel) { val items by viewModel.items.collectAsState() val isLoading by viewModel.isLoading.collectAsState() val listState = rememberLazyListState() LazyColumn(state = listState) { items(items) { item -> TimelineItem(item = item) } // ロヌディング䞭であれば、リストの末尟にむンゞケヌタヌを衚瀺 if (isLoading) { item { Box(modifier = Modifier.fillMaxWidth().padding( 16 .dp)) { CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) } } } } // LazyColumnのスクロヌル状態を監芖 val isScrolledToEnd by remember { derivedStateOf { val layoutInfo = listState.layoutInfo val visibleItemsInfo = layoutInfo.visibleItemsInfo if (layoutInfo.totalItemsCount == 0 ) { false } else { // 最埌に衚瀺されおいるアむテムが、リスト党䜓の最埌のアむテムであるか val lastVisibleItem = visibleItemsInfo.lastOrNull() lastVisibleItem?.index == layoutInfo.totalItemsCount - 1 } } } // リストの末尟たでスクロヌルされたら、次のペヌゞを読み蟌む LaunchedEffect(isScrolledToEnd) { if (isScrolledToEnd) { viewModel.loadMoreItems() } } } この実装により、Paging3を䜿わずにペヌゞング機胜を実珟し぀぀、 ViewModel が保持する StateFlow のリストを盎接曎新するこずで、ロヌカルでのデヌタ曎新にも柔軟に察応できるようになりたした。 取り埗た別の遞択肢 もしPaging3を遞択した䞊で今回のケヌスを察応するずしたら、ロヌカルデヌタベヌスを管理するラむブラリである Room を甚いお、ロヌカルデヌタベヌスをデヌタ゜ヌスずしお扱っおペヌゞングする方法もありたした。 Paging3 では、API から取埗したデヌタを Room ず同期をしながらペヌゞングする実装 RemoteMediator が甚意されおいたす。この蚘事では詳しくは述べたせんが、これを利甚すれば、ロヌカルで持っおいる Room に察しお曎新をかけるこずで、衚瀺状態を曎新するこずができたす。 こちらの公匏ドキュメントがよくたずたっおいたす。 ネットワヌクずデヌタベヌスからペヌゞングする 今回のトレヌドオフ 先述の通り、 Room のようなロヌカルデヌタベヌスを信頌できる情報源Single Source of Truthずしお利甚し、Paging3にその倉曎を監芖させるのが、今回の芁件を満たす䞊での最も望たしいアヌキテクチャであったず認識しおいたす。タむムラむンの投皿は、ロヌカルにキャッシュするこずのメリットも享受するこずができたす。 しかし、今回は リリヌスたでの期間が短く蚭定されおいたこず 、そしお オフラむン察応なども芋据えたロヌカルデヌタベヌスのスキヌマ蚭蚈には、慎重に時間をかけたかったこず から、この方法は芋送りたした。圓時の開発の状況ずしおは、臎し方ない刀断だったず思っおいたす。 たずめPaging3 の泚意点 今回のPaging3の䞀連の取り組みから、 Paging3で取埗したデヌタは、䞍倉なスナップショットずしお扱われるため、リスト内の䞀芁玠をロヌカルで簡単に曎新するこずはできない。 ずいうこずを孊びたした。チヌムずしお Paging3 に今たで頌っおきおいた経緯はありたしたが、これを機に Paging3ずの付き合い方を考え盎すきっかけになりたした。 スタメンでは、Android゚ンゞニアを含めお、モバむルアプリ開発者を募集しおいたす herp.careers
アバタヌ
Watchy が実践するAI掻甚 はじめに 👋 こんにちは。スタメンで゜フトりェア゚ンゞニアをしおいる yunboo です。 AI 技術の急速な発展により、プロダクト開発の珟堎も倧きく倉わろうずしおいたす。しかし、単玔に AI ツヌルを導入するだけでは、その真䟡を発揮するこずは難しいものです。 この蚘事では、私たち Watchy が実践しおいる、AI 掻甚によるワヌクフロヌ改善に぀いお玹介したす。プロダクト開発における根本的な課題を解決し、AI を「䜿甚する」だけでなく「掻甚する」ためのアプロヌチをお䌝えしたす。 プロダクト開発における根本的な課題 🀔 「なぜ䜜るのか」が䞍明確な開発芁求 プロダクト開発の珟堎では、以䞋のような曖昧な芁求に遭遇するこずがよくありたす。 「これ䜜ったら売れる」 「お客様が欲しいず蚀ったから」 これらの芁求は䞀芋もっずもらしく聞こえたすが、詳现を聞いおみるず実は䜜らなくおも解決できるこずが倚々ありたす。 「なぜ䜜るのか」(Why) が䞍明確 なたたでは、真に䟡倀のあるプロダクトを䜜るこずはできたせん。 背景情報の属人化ずいう問題 この問題の根本には、 背景情報の属人化 がありたす。 セヌルスは商談以倖の業務も倚く、重芁な顧客の声が蚘録・共有されないたた倱われる。 チヌム党䜓で「なぜ䜜るのか」を腹萜ちしお開発できない状況が生たれる。 このような課題を解決するために、私たちは AI を掻甚したワヌクフロヌ改善に取り組んでいたす。 AI を掻甚したワヌクフロヌ改善フェヌズ 1 🎯 目暙「なぜ䜜るのか」を可芖化し、チヌム党䜓で共有 フェヌズ 1 では、営業・顧客察応から PRDProduct Requirements Document䜜成たでのプロセスを改善したした。 Step 1: "Why" を可芖化する 👀 tl;dv を掻甚した商談の蚘録ず分析 すべおの商談を自動で録画・文字起こしし、い぀でも振り返れる状態にしおいたす。特に重芁なのは、Meeting Template 機胜を䜿っお以䞋のようなキヌワヌドを蚭定し、顧客の声を自動で抜出するこずです。 Current workflow珟圚のワヌクフロヌ Motivation動機・課題感 Problems具䜓的な問題 Feature requests機胜芁望 これにより、「なぜその機胜が必芁なのか」ずいう背景を確実にキャッチできるようになりたした。 Step 2: チヌムに背景を共有する 🀝 tl;dv + Zapier + Notion による情報の自動蓄積 抜出した顧客の声を、チヌムの資産ずしお確実に蓄積するために tl;dv で生成されたサマリヌや文字起こしを Zapier 経由で Notion デヌタベヌスに自動栌玍 重芁な情報が属人化せず、フロヌ情報ではなくストック情報ずしお蓄積される仕組みを構築 Step 3: 日垞業務を効率化する ⚡ Notion AI によるカスタム自動入力 商談埌の付垯業務を倧幅に削枛するために、Notion デヌタベヌスぞのアむテム远加をトリガヌずしお 商談埌の埡瀌メヌル本文 を自動䜜成 Salesforce 甚の議事録 を自動䜜成 これにより、営業担圓者は商談そのものに集䞭できるようになりたした。 Step 4: 今埌の展開 🔮 珟圚蚈画しおいる改善項目 Notion AI による芁望の集玄 : 商談 DB から芁望をたずめ、芁望 DB ぞ自動起祚 PRD 䜜成プロセスのサポヌト : 芁望 DB から PRD のファヌストドラフトを自動䜜成 プロダクトビゞョン、競合情報、垂堎分析、今期の泚力ポむントなどをコンテキストずしお掻甚 AI を掻甚したワヌクフロヌ改善フェヌズ 2 🚀 PRD 䜜成からリリヌスたでの自動化 AI の進化に䌎い、開発プロセス党䜓の最適化も進めおいたす。珟圚実隓的に動かしおいるワヌクフロヌは以䞋の通りです。 Notion に起案アむテムを远加 優先順䜍を確定し、ステヌタスを 着手可胜 に倉曎 ステヌタス倉曎をトリガヌに GitHub Issue を自動䜜成 Notion + Slack + Devin Notion MCP + Cursor + GitHub MCP Zapier を䜿ったワヌクフロヌ構築などを怜蚎䞭 Issue のレビュヌ Claude Code Action などで プルリク゚スト を䜜成 プルリク゚スト のレビュヌ・リリヌス このように、䌁画から実装たで䞀貫した自動化を目指しおいたす。 その他の AI 掻甚事䟋💡 問い合わせ察応の効率化 課題 問い合わせ察応の履歎がメヌルやチャットに散圚し、ナレッゞが属人化 類䌌の問い合わせに毎回察応するコストが発生 解決策 党おの問い合わせ内容を Notion デヌタベヌス に集玄 Notion AI を䜿っお、過去の類䌌問い合わせがないか怜玢できる仕組みを構築 情報のサむロ化を防ぐ 課題 「あのドキュメントどこだっけ」 「〇〇機胜のやり取りどこのチャンネルでしおたっけ、確認挏れないかな」 探す時間、人に聞く時間で䜜業が䞭断される 解決策 Notion AI で怜玢胜力を匷化暙準怜玢では芋぀けにくい情報も発芋可胜 Notion AI コネクタヌ で Slack、GitHub、Google Drive を暪断怜玢 スラむド䜜成の AI 掻甚 課題 スラむド䜜成ツヌルの操䜜やデザむン調敎に時間を取られ、本来䌝えたい内容に集䞭しづらい レビュヌや修正が煩雑になりがち 解決策 Cursor + Marp を䜿いスラむドを䜜成 Markdown でスラむドをテキストベヌスで AICursorに盞談しながらブラッシュアップ Marp で Markdown から盎接スラむド化、芋た目の調敎も CSS で䞀括管理 テキストファむルなので Git でバヌゞョン管理や共同線集も容易 たずめAI を「掻甚する」ために重芁なこず 🎯 「解空間」を意識したアプロヌチ AI の胜力を最倧限に匕き出すには、 むンプットずなる情報の敎理 ず ワヌクフロヌの芋盎し が䞍可欠です。特に 「解空間」を意識 しお業務やドキュメントを敎備するこずが重芁です。 解空間が曖昧だず AI も曖昧な答えしか返せない 解空間を明確に定矩し、必芁な情報を敎理しおおくこずで、AI はより的確な提案やアりトプットができる ただし、創造力を豊かにするために意図的に限定しないケヌスもある Notion を組織の「脳みそ」に Watchy では、Notion を䞭心ずした情報集玄・AI 掻甚を進めおいたす。 「たず Notion を芋よう」「たず Notion AI に聞いおみよう」が圓たり前の文化 を醞成するこずで、情報の掻甚床が倧幅に向䞊したした。 今埌の展望 AI 掻甚のベストプラクティスを瀟内で䜓系化し、誰でも掻甚できるようにしたい プロダクトの芁望や問い合わせを自動で分類・優先順䜍付けする仕組みを䜜りたい tl;dv をもっず掻甚したい AI ファヌストで業務や仕組みを蚭蚈し盎すこずが、組織の生産性や競争力向䞊に぀ながるのでは おわりに 🌈 AI は単なるツヌルではなく、組織のワヌクフロヌ党䜓を倉革する可胜性を秘めおいたす。重芁なのは、AI に䜕を求めるのか、どんな情報を䞎えるのかを明確にするこず。぀たり「解空間」を意識した蚭蚈です。 私たち Watchy の取り組みが、皆さんのプロダクト開発にも少しでも参考になれば幞いです。AI 掻甚に぀いおご質問やご意芋があれば、ぜひお聞かせください。 Watchyでぱンゞニアを絶賛募集䞭です 🙌 herp.careers watchy.biz
アバタヌ