株式会社スタメンのTUNAGプロダクト開発部で Android アプリを開発しているカーキ(X: @khaki_ngy )です。 自分はスタメンには2020年に新卒入社しており、6年目の春が始まりソワソワした気持ちを抱いています🌸 直近、TUNAGの機能開発で AlarmManager の API を利用し、指定した時間にローカル通知を発行する機能を開発しました。 AlarmManager 自体はかなり古くからある API ですが、権限周りで Android12 から変更が加えられるなど近年のセキュリティ強化の影響も受けています。 今回のブログでは、AlarmManager を利用する一連の流れと、プロダクションで運用するための注意事項を紹介します。 AlarmManager とは AlarmManager とは android.app API に存在するクラスであり、指定した時間に特定の処理を実行することができます。 アプリが起動していない状態(バックグラウンドにいる状態)でも、指定の時刻に処理を行うことができます。ユースケースとしては時計アプリのアラーム機能などでユーザーが指定した時刻にアラームや通知を発行するような時に利用されます。 今回 TUNAG では、指定された日時にローカル通知を発行するために採用しましたが、本当に AlarmManager を使うべきかどうかの見極めが必要です。 なぜならば、先述した通り AlarmManager は指定した時刻でバックグラウンドで強力な処理を実行できるポテンシャルがあるためです。正確な時刻にバックグラウンドで処理を起動できること自体が、バッテリーやリソースに影響を与える可能性があるため、AlarmManager を使って正確な時刻にアラームを設定するには後述する特別なアプリアクセス権の取得が必要になります。ユースケースに応じて、本当に AlarmManager を利用するべきかどうかを一度考えた方が良いでしょう。 代替手段との比較では、正確な時間指定が必要かどうかが軸になってきます。 正確な時間指定が必要でない場合、代替手段として公式ドキュメントでは Handler クラスの利用や、 WorkManager での定期実行のスケジュールなどが紹介されています。WorkManager はライフサイクルの考慮や、処理を開始する上でのシステム的な制約を指定することができるので、遅延実行して問題のないバックグラウンド処理であれば WorkManager を利用するのが良いでしょう。 AlarmManager と権限 権限の種別 AlarmManager を利用して正確な時間に処理をスケジュールするには、以下の権限のうちどちらか一つが必要になります。 USE_EXACT_ALARM SCHEDULE_EXACT_ALARM どちらの権限も AlarmManager を通して、正確な時間に処理をスケジュールするのに必要な権限になりますが、どのような機能を提供するアプリかに応じてどちらの権限を利用するかが変わります。 前者の USE_EXACT_ALARM は、 アラーム・カレンダー機能が主となるアプリ向け の権限になります。Android の APIレベル33(Android 13相当)から登場した権限です。 アラーム・カレンダーアプリが主の機能となっていれば、指定の時刻に処理を行なったり、通知を送ったりする機能はほとんど必須の機能となります。そのため、AndroidManifest で権限の利用を宣言していれば、ユーザーの許可なしで正確な時間の処理が可能になります。 ただし、前提となっている アラーム・カレンダーアプリがメインの機能かどうか という点がアプリの審査で判断されることになります。アラーム・カレンダー機能が主となるアプリでない場合は、こちらの権限を利用してもストアへの公開は難しいでしょう。 後者の SCHEDULE_EXACT_ALARM は、前者の対象となる「アラーム・カレンダー機能が主となる」アプリ 以外 を対象とした権限になります。こちらはAndroidのAPIレベル31(Android 12相当)から登場した権限です。 こちらの権限では、アラームやカレンダー機能を主としたアプリ以外での利用を想定されています。 こちらの権限は Android の API 34以降(Android 14相当)では、デフォルトで拒否されるようになっており、ユーザー自身がアプリに「アラームとリマインダー」の権限を許可する必要があります。 「アラームとリマインダー」は特別なアプリアクセス権に分類され、通常の権限リクエストとは若干方法が異なり、設定画面でユーザーに『許可』をしてもらう必要があります。 システムのアプリ設定内にある「アラームとリマインダー」 正確な時間のアラームであっても AlarmManager の OnAlarmListener オブジェクトを利用する場合は、 SCHEDULE_EXACT_ALARM は不要になります。ただ OnAlarmListener を利用したアラームの場合はアプリのプロセスが生きている期間の間は有効になりますが、アプリキルをされた場合などプロセスが終了している状態では、アラームを起動させることができません。この後の内容に関しても OnAlarmListener を利用せず、バックグラウンドでも機能するスケジューリング処理について紹介をしていきます。 権限のハンドリング 先述の通り、AlarmManager による(バックグラウンドで動作する)正確な時間での処理のスケジュールには、 SCHEDULE_EXACT_ALARM 権限が必要になります。 権限を獲得するフローは大体以下の流れです 1. ユーザーがすでに権限を持っているか確認する 2. 持っていなければ、権限のリクエストを要求する 1. 権限の確認 通常、権限の許可がされているかを確認する場合には ContextCompat.checkSelfPermission を利用して、対象のパーミッションが許可されているかどうかを確認します。ただ SCHEDULE_EXACT_ALARM は特別な権限となるため、AlarmManager に用意されている専用のメソッド canScheduleExactAlarms() を利用して確認する必要があります。 ( ContextCompat.checkSelfPermission で確認しても常に許可されていないと返ってきてしまいます) 具体的なコードのイメージとしては以下のようになります。 val alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager // Android 12 より前、もしくは権限が許可されている場合 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || alarmManager.canScheduleExactAlarms()) { // alarmManagerによるスケジューリングを実施 } else { // 権限をリクエストする } 2. 権限のリクエスト 権限が許可されていない場合は、ユーザーに権限をリクエストする必要があります。 一般的な権限のようにアプリ内のダイアログで権限リクエストをする仕組みが用意されていないため、設定画面に遷移させて、ユーザーに設定を変更してもらう必要があります。 以下のように『アラームとリマインダー』に関する設定ページに直接遷移するようなIntentを発行することで、ユーザーを設定画面に導くことができます。 val intent = Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM) startActivity(intent) 上記では単純な Intent 遷移の例を示していますが、Activity Result API による遷移を利用すれば、設定画面から戻ってきたタイミングをハンドルできるので、より状況に適した処理を実装できると思います。 権限リクエスト時の注意点 SCHEDULE_EXACT_ALARM はシステムでの権限付与のダイアログが提供されていないため、アプリからユーザーに対して権限リクエストの旨を伝えるのが良いでしょう。 権限の付与が必要なタイミングで突然システムの設定画面に飛ばされてもユーザーは困惑してしまうためです。 そのため、下記のようなダイアログを一つ挟んで、アラームの設定を行うかどうかをユーザーに事前に確認をすると良いです。 ユーザーに向けたダイアログの例 AlarmManager を利用する 指定した時間にアラームをスケジュールする AlarmManagerによりアラームをスケジュールする流れとしては、以下の2ステップです。 PendingIntent を作成 AlarmManager インスタンスからスケジューリングのメソッドを実行 それぞれについて解説していきます。 1. PendingIntent を作成 指定した時間にアラームを受け取る際に BroadcastReceiver を利用し、バックグラウンドでも BroadcastReceiver を受け取れるように PendingIntent を作成します。 この際、アラームのスケジュールを設定する上で考慮するべき点がいくつかあります。 val pendingIntent = PendingIntent.getBroadcast( context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE ) まず getBroadcast の第二引数になっている requestCode です。 これは予約するアラームを一意に識別する役割があります。そのため、例えば、同じ requestCode で複数アラームをスケジュールしても、最後にスケジュールした PendingIntent しか有効になりません。 また後からスケジュールしたアラームをキャンセルしたい場合にも同じ requestCode から作成された PendingIntent が必要になります。 次に第三引数として指定している intent についてです。 この Intent は、アラームが起動した時に実行させたい BroadcastReceiver に向けられた Intent を指定してください。 val intent = Intent(context, MyAlarmReceiver :: class .java).apply { putExtra(MESSAGE_KEY, "アラームです" ) } この intent に対して、 action や extra を指定することができるので、これらを指定することで、 BroadcastReceiver の中で処理に必要な情報を渡すことができます。 第4引数の PendingIntent のフラグに何を渡すのかでもアラームの挙動が少し変化します。 PendingIntent.FLAG_IMMUTABLE は、PendingIntentの中身が他のアプリによって変更されることを防ぐフラグになります。Android API 31以降では PendingIntent.FLAG_IMMUTABLE 、 PendingIntent.MUTABLE のどちらかが必須となっています。アプリによってどちらを選択するべきかは異なりますが、他のアプリによって遷移先が勝手に書き換えられてしまう可能性があるので、基本的には PendingIntent.FLAG_IMMUTABLE を設定しておいた方が良いでしょう。 また PendingIntent.FLAG_CANCEL_CURRENT は既に同じ requestCode で生成されたPendingIntentがある場合に前の内容をキャンセルして、新たなPendingIntentとして登録するために設定をします。 近いものとしては PendingIntent.FLAG_UPDATE_CURRENT というフラグも存在します。こちらは同じ requestCode で生成されたPendingIntentがある場合に、中のIntentだけを新しいものに更新するフラグになります。 requestCode を被らないように設定している場合であれば、どちらを選んでも結果は変わりませんが、同じ値が入る可能性があれば、どちらを選択するべきかをよく考える必要があります。 2. スケジューリングのメソッドを使う アラームをセットするメソッドは複数存在し、アラームが「繰り返しなのか」「正確な時刻が必要なのか」に応じて適切なメソッドを選択する必要があります。 今回は1回きりのアラーム set を中心に紹介をします。 一回きりのアラームの set をいくつか種類があります。 set : 最も効率の良い1回きりのアラームメソッド。効率は良いものの、端末の状態に大きく左右されるため、指定した時刻通りに発火することは保証されていません。 setExact : set メソッドよりは正確に発火することを目的としたメソッド。ただ端末がDozeモードに入ってしまうと発火しないので注意が必要。 setAndAllowWhileIdle : Dozeモードなど、端末がアイドル状態の場合でもスケジュール通りに発火するメソッド。端末の状態に関わらず実行させたい場合はこれを利用する。 また set メソッドの第一引数にはAlarmManagerのTypeを指定する必要があります。 こちらは4種類のタイプがあります。 ELAPSED_REALTIME : デバイスが起動してからの経過時間に基づいてPendingIntentを開始する、デバイスのスリープは解除しない。 ELAPSED_REALTIME_WAKEUP : デバイスが起動してから指定された時間が経過した後にデバイスのスリープを解除し、PendingIntentを開始する RTC : 指定された時間にPendingIntentを開始する。ただし、デバイスのスリープは解除しません。 RTC_WAKEUP : 指定された時刻にデバイスを復帰させてPendingIntentを開始する。 それぞれアラームの特性に合わせて実装をするのが良いと思います。 まとめると アラームを発行する流れをまとめると以下のようになります。 val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val alarmIntent = Intent(context, MyAlarmReceiver :: class .java) val pendingIntent = PendingIntent.getBroadcast( context, requestCode, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE ) alarmManager.setExactAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, notifiedDateTime.toInstant().toEpochMilli(), pendingIntent ) アラームされたタイミングで実行される処理 アラームされたタイミングで実行される処理は BroadcastReceiver で実施されるので、こちらの準備も必要になります。 class CalendarEventAlarmReceiver: BroadcastReceiver() { override fun onReceive(context: Context, intent : Intent) { // アラーム発火時に行う処理 } } BroadcastReceiver の利用には AndroidManifest での利用の宣言も必要になるので忘れずに行いましょう。 まとめ 今回は、AlarmManager を使った実装の紹介を行いました。 古くからあるAPIではあるものの、Android API 23 からの Doze モードの登場や、Android API 31 以降の権限の強化によって、ここ数年でも実装や扱い方が変わってきているAPIになります。 AlarmManagerのドキュメントには USE_EXACT_ALARM や SCHEDULE_EXACT_ALARM を利用する場合の注意点が書かれており、アプリケーションが提供したい機能に応じて、どのような方法でスケジュールをするのか(あるいは、AlarmManagerを使わないのか)を判断して利用する必要があります。 株式会社スタメンでは一緒に働く仲間を募集しています。少し気になる、話を聞いてみたい!という場合は以下のフォームからご連絡ください herp.careers
こんにちは、スタメンでエンジニアリングマネージャーをしているasashin(@asashin227)です。 近頃は暖かくなり、もうすっかり春の気候ですね。 最近、桜の盆栽を手に入れて、視覚的にも春を感じられるようになりました。 EMConfに参加してから1ヶ月ほど経過しましたが、日々の業務の中でもEMConfでの学びを振り返る事があり、自分の考えとして定着したものや腹落ちしたものなどありましたので、改めて登壇された方のスライドを見ながら振り返っていこうと思います。 2025.emconf.jp EMConf2025は2025/02/27に開催されました。(実は当日は誕生日でした) 参加レポートとしては、 @hisa が執筆した 非EMがEMConf JP 2025に参加して学んだこと 〜エンジニア視点で見るEMの役割と未来〜 をご覧ください。 tech.stmn.co.jp EMの役割 一般的にはEMの役割として以下の項目を挙げられることが多いです。 プロダクトマネジメント プロジェクトマネジメント テクノロジーマネジメント ピープルマネジメント これは、EMConfでキーノートを務められた広木大地さんが執筆した エンジニアリングマネージャー/プロダクトマネージャーのための知識体系と読書ガイド によって広く知られるようになりました。 qiita.com 今回、広木さん自らこれをアップデートし、テクノロジーマネジメントからプラットフォームマネジメントとなりました。 プロダクトマネジメント プロジェクトマネジメント プラットフォームマネジメント ピープルマネジメント hirokidaichi.github.io プラットフォームマネジメントという考え方 これまでの役割として提示されていたテクノロジーマネジメントとしては、技術負債のコントロールや、技術戦略、アーキテクチャ選定、モニタリングなど、エンジニアリングに対して直接的に関与するようなことが多かったように考えていますが、プラットフォームマネジメントという表現では、エンジニアリングはメンバーに任せつつ一歩引いたマネジメントを行う表現になったように感じています。 直接的に技術的負債を解消するための働きかけも必要ですが、技術的負債を生み出さないためのデリバリーフローの構築や、ツールの整備などを主戦場とすることと、これらが必要なタイミングでチームに提供できるように、定点観測したり、早期に失敗できる(Fail fast)できるように準備しておくことが必要となります。 また、スタメンではプラットフォーム部が存在し、プロダクト部全体に対して開発者体験の向上を行っていますが、EMの役割としても管掌組織に対しての、開発者体験と生産性の向上を担っていくとことが、プラットフォームマネジメントと捉えました。 開発者体験の向上のためのツールの導入支援やCI/CDの構築などが具体的な方法論としてはありますが、これらを戦略的に導入しつつ、メンバーにかかるコストを中長期で低下させるための技術基盤を構築、維持し続けることが、プラットフォームマネジメントと言えるのではないでしょうか。 現在の私の管掌チームでは、CI/CDの整備などのデリバリーフローの効率化を行えていますが、技術的負債のマネジメントまで踏み込むことができていないため、今後の課題となってきそうです。 エンジニアリングの価値をどう考えるか 開発生産性を語る上で、どのように経営指標と接続していくのか、例えば機能がどれほど売り上げに貢献したのかや、DXによってコスト削減し、利益率を上げるなどありますが、 エンジニアリング価値を黒字化する、バリューベース戦略を用いた技術戦略策定の道のり(by Kazuki Maeda) の中でも損益計算書(P/L)のように捉えて開発組織内で黒字化させるという手法について、以前から頭の中にはあったのですが、視覚化されることで改めて、気づきがありました。 speakerdeck.com 経営との接続を考えるとどうしても金額的なものに置き換えて語りたくなってしまうのですが、そうではなく価値提供速度を挙げていた点が、腹落ちしました。 価値のボリュームを計ろうとするとどうしても利益率や売り上げに紐付いてきてしまい、変数が多くエンジニアリングの貢献度合いが曖昧になってしまうため、この観点は非常に良いものだと感じました。 開発や運用コストを抑えつつ、早く早く価値を届けることがエンジニアリングの価値として定義してみるという試みがありそうと考えています。 サバイバルフェーズの心得 speakerdeck.com ここでの文脈でのサバイバルフェーズとはKPIの未達成や事業計画のビハインド、収益構造の悪化など事業面の事象やメンバーの疲弊と離職という状態を指しており、過去の似たような状況に遭遇したため思い出しながらセッションを聴いていました。 足元の数値改善は当然として、根本的なコスト構造改善のための方針を打ち出されていたとお話を聞くだけでかなりハードな状況だった事が伺えました。 その中でも大変参考になったのが、考える時間軸を伸ばすというお話でした。 目の前の課題に取り組み続けることのみに注力するとメンバーやマネージャー自身の目線が下がり、すべての施策が後手に回ってしまうという事が経験上ありました。 やるべきタスクが消化されず目先のわかりやすい問題に目がいってしまい、本質的な課題解決ができない状態となってしまいます。 こにふぁーさんの発表では1年半先に向けて組織とプロダクトの目線を合わせることでその中で必要な役割にチャレンジしてもらったり、重要度の高いが緊急性の低い問題に取り組む事ができるようになったと紹介されていました。 また、少し先のチャレンジングな目標が共有されることでメンバーの熱量が大きくなり、自らチャレンジしてくれるメンバーもいたとのことでした。 直近のプロジェクトが半年以内に終了するサイズ感のものが多く、1年以上先の話をメンバーとする機会が少なくなっているので(現状サバイバルモードというほどでもないですが、)私自身もっとメンバーと未来の話をせねばと思いました。 これからのエンジニアリングマネジメント キーノートの広木さん、岩瀬さんがお二人とも触れていたことでもありますが、昨今のAIの成長によってエンジニアリングマネジメントはEMだけが行うものではなくなっていくと感じました。 スタメン社内でもAIを用いた開発が徐々に浸透し始め、私自身も、ClaudeやGithub Copilotを活用しながら開発を行なっています。 チームの一部メンバーは Devin.ai を使い始めており、人間が指示して、AIが実装するということが現実になっています。 コミュニケーションしている様はまさに先輩エンジニアと後輩エンジニアのオンボーディグのように見えます。 このように、意図せずとも、AIに対しての教育やタスクの分解、指示だし、進捗管理など、マネジメントの要素は徐々にエンジニアメンバーの業務にも染み出してきています。 広木さんのキーノートにも記されている通り すべてのエンジニアは、AIをメンバーに持つエンジニアリングマネージャーになる。 ということが現実的にすでに起こっていると考えています EMでなくともEMっぽいことが求められるという未来がそう遠くない中で、我々、現在のEMはメンバーに対して、EMっぽいことをできるようになろうということを伝えていかなければなりません。 プロジェクトマネジメントやAI教育と指示出しのための言語化能力は必ず必須スキルになっていきますし、簡単な実装はAIに置き換わっていくため、より高度な技術を身につけなければなりません。 最後に テック系のカンファレンスに参加することはありますが、マネジメント系のカンファレンスは(現地参加としては)初めてだったため、他の参加者の方との交流ができたことが、最も良かったと感じる部分でした。 特に、スタメンでは専任のEMが私一人ということもあり、同じ立場だからこその悩みや具体的な取り組みの事例などのお話を聞くことができて、楽しい1日となりました。 スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers
この度、株式会社スタメンは昨年に引き続き、RubyKaigi 2025にPlatinumスポンサーとして協賛します。 昨年のRubyKaigiのレポートはこちらから👇 tech.stmn.co.jp スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「TUNAG(ツナグ)」を開発・提供しています。「TUNAG」はバックエンドの開発言語にRubyを使用しております。 事業と開発組織が成長できたのは RubyとRubyコミュニティの支えがあってこそであり、今後のさらなるコミュニティの発展に貢献するため「RubyKaigi 2025」へ協賛いたします。 本カンファレンスへの協賛を通して、これからのRubyコミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! RubyKaigi 2025 開催概要 名称 RubyKaigi 2025 開催日時 2025年4月16日(水) 〜 18日(金) 場所 愛媛県県⺠⽂化会館 (愛媛県松⼭市) 参加方法や詳細については、下記公式サイトをご覧ください 👇 rubykaigi.org 今年のブース企画について 昨年、好評だったスタメンのブースを今年も出します! 『 TUNAG 』の機能の一部を利用した、参加型ブースイベントとなっており、実際のプロダクト機能を使った抽選イベントで、来場者の皆さまにワクワクと楽しさをお届けします! 参加いただいた方には、参加賞や景品も用意しておりますので、ぜひ遊びにきてください!(数には限りがございます。) 皆さまのお越しを心よりお待ちしています! おわりに 最後まで読んでいただきありがとうございます。 弊社からはエンジニア、HR含め8名が現地参加します! ブースやイベント等でお話できることを楽しみにしています! 当日会場ではどうぞよろしくお願いいたします。 スタメンでは、RubyやRubyコミュニティが好きなエンジニアを絶賛募集中です。 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
はじめに こんにちは、プラットフォーム部の 近藤 です。 2018年に初期リリースしたチャット機能は、システムの拡張性と安定性の向上が課題となっていました。そこで、これらの課題を解決し、より快適なサービスを提供するために、2025年3月に「TUNAGチャット」をリリースしました。本記事では、このリプレースにおいて、マルチテナント型の SaaS アプリケーションをどのように構成したのかをご紹介します。 prtimes.jp 図1にアーキテクチャ全体の構成を示しました。Google Kubernetes Engine (GKE) を中心に構成しています。実際にはもっと多くのコンポーネントを用いていますが、この記事で取り上げたい内容に限定して図にしました。弊社ではこれまで、Amazon Elastic Container Service (Amazon ECS) を採用することがほとんどで、GKE の導入は今回が初めてです。 図1 全体の構成図 マルチテナントを構築する上で考慮すべきトピックは多岐にわたります。本記事では、インフラストラクチャの共有・占有という主にテナント分離の観点に焦点を当てて説明させていただきます。 ドメイン 図1で示したとおり、アプリケーションはテナントごとに分離されています。このようなサイロモデルにおいては、テナントルーティングが必要です。テナントルーティングの戦略として、(1)ドメイン駆動型ルーティング、(2)データ駆動型ルーティングの2つが考えられます *1 。図2に、それぞれの比較を簡単にまとめました。詳しくは、Amazon Web Services ブログなどもご参照ください *2 。 図2 テナントルーティング戦略の比較 今回は認証をアプリケーション側で実装する必要があったため、ドメイン駆動型ルーティングを選択しました。具体的には、各テナントに固有のサブドメインを作成し、テナントを識別しています。そしてサブドメインには、意味のない文字列ではなく、テナントごとにパーソナライズされたバニティサブドメインを使用しています。例えば、株式会社スタメンの場合、「stmn.example.com」のようなサブドメインとなります。バニティサブドメインはシステム側ではなく顧客が決定するため、運用や開発にコストが発生しますが、ユーザーエクスペリエンスを重視し、この方式を採用しました *3 。 ロードバランサー ロードバランサーは、全テナント共有のインフラストラクチャとなっています。インフラストラクチャを共有する理由は、主にコストの最適化のためです。Cloud Load Balancing は、受信・送信データ量に加えて、「転送ルール数 × 利用時間」に対する従量課金のため *4 、テナント間で共有することでコストは抑えられます。 Kubernetesクラスター内で実行されているサービスへの外部アクセスには、一般的に Ingress が使用されることが多いかもしれません。今回は図1に示すとおり、各テナントは Namespace で分離されています。Ingress は Namespace を跨いで利用することが単純にはできないため、このような場合には Gateway の使用が選択肢として考えられます *5 。Gateway は Ingress のスーパーセットとして提供されている点 *6 も、採用理由の一つです。ただし、GKE Gateway では Cloud CDN をサポートしていない点 *7 には留意が必要です。 アプリケーション 今回のアプリケーションの要件として、テナントごとに Pod を用意して、サーバーを立てる必要がありました。Pod を分離した主目的ではありませんが、テナントごとに最適なコンピューティングリソースが適用できたり、ノイジーネイバーの対策にも繋がっています。 また、各テナントの Pod は Namspace によって分離しています *8 。テナント専用 Namespace によるサイロ化には、いくつかのメリットがありました。 第一に、分離された環境により、セキュリティを強化できます。テナント間のデータ漏洩は、SaaS において非常に大きなビジネスリスクの一つです。 第二、モニタリングでの利便性です。Google Cloud のコンソール上で、Namespace 単位で各種メトリクスが確認でき、より柔軟かつ素早く分析することが可能です。 第三に、Kubernetes オブジェクトの名前の衝突を意識する必要がなくなるなど、オブジェクトの管理が容易になります。今回のアプリケーションでは、新規にテナントを追加する場合は、テナント専用の設定ファイルを追加してワークフローを実行します。解約に伴いテナントを削除する場合は、Namespace を削除することで、属するオブジェクトを一括で削除できます。こうした管理も、Namespace による分離が効果を発揮しています。 図3 ファイル管理のイメージ データベース マルチテナントにおけるデータベースの分離パターンはいくつか考えられます。(1)単一インスタンス共通データベース方式、(2)単一インスタンス個別データベース方式、(3)インスタンス分離方式などです *9 。また、RDB にとらわれず、マネージドなサービスも選択肢になり得るかもしれません *10 。今回は、アプリケーションの特性として、RDB の利用が前提となっていました。 データベースの分離パターン 単一インスタンス共通データベース方式は、インフラ費用や運用コストにメリットがあります。このパターンの場合、データ分離は PostgreSQL の Row Level Security を利用したり、アプリケーションレイヤーで対応することになります。これまで弊社のRailsアプリケーションでは、主にこのパターンを採用してきました。 今回は、アプリケーションレイヤーでデータ分離を対応することが困難だったため、単一インスタンス個別データベース方式を採用しました。テナントごとにデータベースユーザを作成し、各アプリケーションはそのユーザを利用して、データベースにアクセスします。各テナントは、別テナントのデータベースを参照することは、権限の制約によりできません。一方で、インスタンスを共有しているため、ノイジーネイバーなどはリスクとなり得ます。インスタンス分離方式は、インフラ費用や運用コストが高いため採用は現実的ではありませんでした。 図5 分離されたアクセスのイメージ 単一インスタンス共通データベース方式を採用している弊社の Rails アプリケーションでは、activerecord-multi-tenant *11 という Gem を用いて、アプリケーションレイヤーでデータ分離を実現しています。ただし、Gem による制約の適用を確実にするため、弊社では独自のテストコードを実装するといった様々な工夫が必要になっており、その対応は簡単ではありません。 単一インスタンス個別データベース方式にも課題はあり、1つのインスタンス内のデータベース数とテーブル数がスケールしたことで、マイグレーションにかかる時間の増加などの課題が生じた事例をSmartHR社が紹介しています *12 。今回はそこまでのスケールは不確実であり、懸念には考えていません。また、アプリケーションの特性として、テナントは明確に分離されており、今後は複数インスタンス構成も比較的容易に導入できると考えています。 図6 複数インスタンス構成 最後に 私にはGoogle Cloud と Kubernetes の経験がほとんどなかったのですが、さまざまな選択肢の Pros & Cons やトレードオフを整理して構築を進めていくことは非常に良い経験になりました。 9年目を迎えた弊社の TUNAG では、ありがたいことに導入企業数やユーザー数が着実に増えています。このようなスケールに伴い、今後の中長期的なスケーラブルなアーキテクチャのための取り組みを積極的に行っています。また、マルチプロダクト戦略にも本格的に取り組んでおり、0 → 1でアプリケーションを構築する機会も今後ますます増えていくはずです。 クラウドを中心としたアーキテクチャ構築に興味を持っているエンジニアにとっては、非常にやりがいのある環境だと感じています。少しでも興味を持っていただけたら、ぜひまずはカジュアル面談でお話しできればと思います。 herp.careers 参考 Golding Tod. (2024). Building Multi-Tenant Saas Architectures: Principles, Practices, and Patterns Using AWS . California: O'Reilly Media. (ゴールディング・トッド. 河原 哲也・櫻谷 広人(訳)(2025).マルチテナントSaaSアーキテクチャの構築―原則、ベストプラクティス、AWSアーキテクチャパターン) *1 : AWS における SaaS アプリケーションのテナントルーティング戦略 *2 : SaaS におけるテナントリソースへのリクエストルーティングを JWT を用いて実現する *3 : バニティサブドメインは、SlackやZoomなど広く採用されている。今回のアプリケーションの仕様では、ログイン時にサブドメインを入力するため、記憶しやすいバニティサブドメインを用いた方がユーザーエクスペリエンスは向上する。SmartHR社の スマートフォン向けアプリのログインにサブドメインの入力が必要になりました(03/21更新) のような体験に近い。 *4 : All networking pricing *5 : Cross namespace communication in GKE ingress *6 : About the Gateway API Comparison of Ingress and Gateway *7 : Deploying Gateways Restrictions and limitations *8 : Google Kubernetes Engine 上で SaaS プラットフォームを作成する *9 : Windows Azureエンタープライズアプリケーション開発技法 マルチテナント・アーキテクチャ を参考にした。"データベース"という単語が PostgreSQL で用いられる"データベース"との混同につながる。よって説明の便宜上、参考記事の語彙を、「データベース → インスタンス」、「スキーマ → データベース」に置き換えて本記事では表現をさせていただいた。 *10 : RDBを使わない究極のマルチテナント *11 : activerecord-multi-tenant *12 : SmartHR が定期メンテナンスを始めた理由とやめる理由
はじめに プロダクト開発部でTUNAGの開発をしている hisa です。最近、花粉の症状が出始めて悩まされています。目のかゆみと戦いながらも、先週EMConf JP 2025に参加してきました。 エンジニアリングマネジメント(EM)は、エンジニアのキャリアの中でも特に難易度が高い領域の一つだと感じています。私はEMではありませんが、「プロダクトに関わるすべての人が幸せになれば」という思いを持ち、そのためには「良いプロダクトを作るには良い組織が必要」と考えています。その延長として、EMについての理解を深めたいと思い、EMConf JP 2025に参加しました。 今回のカンファレンスを通じて、EMという役割の多様性と、その難しさを改めて実感しました。また、EMだけの問題ではなく、エンジニアとしても組織やプロジェクト運営に関わることの大切さを学びました。本記事では、非EMの立場から見たEMの役割や学びについて、特に印象に残ったポイントを紹介します。 エンジニアとしての学び 1. 不確実性との向き合い方 「エンジニアリングは不確実性との戦い」と言われることがありますが、EMにとっても同じであることが分かりました。 カンファレンスでは「フェイルファスト(Fail Fast)」という考え方が強調されていました。特に印象的だったのは、不確実性を無理に排除しようとするのではなく、向き合い、小さな成功体験を積み重ねていくことが重要だという話です。 エンジニアリングにおいても、技術選定や仕様策定の際に「最適解が分からないから決められない」と迷うことは多々あります。しかし、その状態を避けるのではなく、「とりあえず試す」「失敗してもすぐにリカバーできる環境を整える」といったアプローチが大切だと感じました。 2. タスク管理ではなくリスク管理 「プロジェクトマネジメントとはタスクを管理するのではなく、リスクを管理すること」という話がありました。 ソフトウェア開発は目に見えないことが多く、進捗の管理が難しいですが、そもそも「進捗を管理しようとする」こと自体が間違っているのかもしれません。 重要なのは、何がリスクになり得るかを見極め、それを最小化すること。 特に、以下のポイントが印象に残りました。 進捗共有を頻繁に行うこと プロダクトの完成形が見えにくいからこそ、こまめな共有が必要 チームメンバーだけでなく、ステークホルダーにとっても進捗が可視化されている状態を作る タスクよりもリスクを中心に考えること 「このタスクが終わるか?」ではなく、「どこでつまずく可能性があるか?」を考える これはプロジェクトマネージャーだけでなく、エンジニアとしても意識できるポイントだと感じました。 3. 技術的負債とエンジニアリングマネジメント 技術的負債に関する話も多く出てきました。「技術的負債とアーキテクチャは対の存在」という考え方はとても腑に落ちるものでした。技術的負債は見えてしまえば管理できる。逆に言えば、見えていないから管理が難しくなる。 エンジニアとしても、以下のような点を意識することで、EMや組織全体に貢献できるのではないかと感じました。 技術的負債の可視化 負債がどこにあるかを整理し、共有する ADR(Architecture Decision Record)の管理 どんな判断をしたのか記録を残し、振り返りやすくする 非機能要件の見える化 性能・運用コスト・可用性などの指標を数値化する EMは「エンジニアが働きやすい環境を作る」役割ですが、その環境づくりにエンジニア自身が協力することも重要だと感じています。 EMの役割とは? EMの役割について話を聞く中で、「EMとは価値を実現するためになんとかすること」という表現が印象に残りました。 これは単にチームの管理をするのではなく、「必要なことを理解し、それを実現するためにあらゆる手段を講じる」役割だということです。 「なんとかする」とは? 制約のある中で、目標を達成する手段を探す 必要なスキルがなければ、自ら学ぶか、適切な人をアサインする プロダクトの方向性が見えないときに、仮説を立て、検証のサイクルを回す 組織の成長に合わせて、マネジメントの仕組みそのものを変える つまり、EMは「何をすべきか」「どうすれば組織として目標を達成できるか」を考え、障害を取り除く仕事をしていると感じました。 これは、EMだけの話ではなく、エンジニアとしても「自分の仕事をどう価値につなげるか?」を考える上でヒントになる考え方だと思いました。 まとめ 今回のEMConf JP 2025を通じて、エンジニアリングマネジメントの奥深さを学ぶことができました。 EMという役割は「エンジニアが最大限の価値を発揮できる環境を作ること」にあると理解しましたが、そのためにはエンジニア自身も組織の在り方やマネジメントを意識することが重要だと感じました。 特に印象に残った学びは以下の3点です。 不確実性に向き合い、小さな成功体験を積み重ねること タスク管理ではなくリスク管理を重視すること EMだけでなく、エンジニア自身も組織の改善に関わること 良いプロダクトを作るためには、良い組織が必要。 そのためにEMが果たす役割は大きいですが、エンジニアとしても「組織やチームを良くするためにできることは何か?」を考えていきたいと思いました。 さいごに BuySell Technologiesさんのブースでガチャガチャがあり、硬貨が当たりました。 とても貴重そうなので大切にとっておきます✌️ BuySell Technologiesさんのブース スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers
TUNAGのプロダクト開発チームでiOSアプリを開発している おしん です。 SwiftUIの標準コンポーネントである List を使う機会があったのですが、List を使ってデザイン通りに画面を実装することは予想以上に困難でした。 このブログでは、Listのデフォルトの挙動と適切な対処法について紹介します。 List とは UIKitの UITableView に相当するSwiftUIのコンポーネントで、縦方向のスクロール可能なリストを作成できます。 Listを使用することで、データ配列を自動的にレイアウトし、パフォーマンスが最適化されたスクロール可能なUIを構築できます。 以下のコードでは、 items の配列をリストに変換し、各要素を Text で表示しています。 struct ContentView : View { let items = [ "Pacific" , "Atlantic" , "Indian" , "Southern" , "Arctic" ] var body : some View { List(items, id : \. self ) { item in Text(item) } } } Listの使い所 無限スクロールの実装が必要な画面では、配列の要素の(個数 - 1)番目が画面に表示されたら、次の要素を配列の末尾に足すという方法を取ることが多いと思います。 その際、(個数 - 1)番目の要素のViewの .onAppear を適切に制御する必要がありますが、 ScrollView + LazyVStack を用いた実装では、要素追加時の .onAppear の発火タイミングの調整が難く、実用的ではありません。 そのような場合においてはScrollView + LazyVStack ではなく、子要素の.onAppearを適切にハンドリングできるList を使うことが推奨されます。 List の何が大変か 高いパフォーマンスを発揮する List は便利なコンポーネントですが、Listのデフォルトの挙動を調整する際に、以下のような難しさがありました。 行・セクションの余白やセパレータの扱い List 内に埋め込んだボタンが意図しない挙動をする それぞれの課題と対処法を紹介します。 行・セクションの余白調整 デフォルトでは以下のように余白やセパレータが適用されているため、デザインに合わせて調整が必要です。 出典: https://developer.apple.com/documentation/swiftui/list List { Text( "Pacific" ) .listRowSeparator(.hidden) // セパレータを非表示にする .listRowInsets(EdgeInsets()) // 行の余白をなくす(四隅のpaddingを0にする) } .listStyle(.plain) // Listのデフォルトのスタイルを変更 セクションの余白については、iOS15 以降では行の余白を消す API が提供されていますが、セクションの余白を消す API は iOS17 以降でしか利用できません。 そのため、以下のように inset を余白分だけマイナス値で相殺することで回避しました。 if #available(iOS 17.0 , * ) { List { Text( "Pacific" ) } .listSectionSpacing(.leastNonzeroMagnitude) // iOS17以降でのみ使用可 } else { List { Text( "Pacific" ) .listRowInsets(EdgeInsets(top : - 20 , leading : 0 , bottom : 0 , trailing : 0 )) // セクションの余白を相殺 } } ボタンが意図しない挙動をする問題 List ではデフォルトでスワイプアクションやコンテキストメニューのようなボタンが用意されています。 そのため、行に対して追加でボタンを配置すると List 側のボタンと競合してしまうことがありました。 List のデフォルトのアクションを無効化するか、明示的にカスタムボタンの動作を定義することで意図しない動作を防ぎました。 List { Button(action : {}) { Text( "Pacific" ) } } .buttonStyle(.plain) // rowのデフォルトのタップアクションを無効にする ボタンが反応しなくなる問題 1行に複数のボタンを埋め込むと、特定のボタンがタップに反応しなくなることがありました。 Rectangle を shape に設定することで回避しました。 List { HStack { Button(action : {}) { Text( "button1" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 Button(action : {}) { Text( "button2" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 } } .buttonStyle(.plain) 全体像 以上を踏まえ、Listのデフォルトの見た目を最大限抑えた場合の全体像がこちらになります。 // セクション間の隙間の調整が必要な場合は // iOS 17以上 → `listSectionSpacing` // iOS 17未満 → `listRowInsets`の当て方を調整 List { Group { HStack(spacing : 0 ) { Button(action : {}) { Text( "button1" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 Button(action : {}) { Text( "button2" ) } .contentShape(Rectangle()) // タップ領域を明示的に確保 } let items = [ "Pacific" , "Atlantic" , "Indian" , "Southern" , "Arctic" ] ForEach(items, id : \. self ) { item in Text(item) } } .listRowBackground(Color.clear) // 背景透過 .listRowSeparator(.hidden) // セパレータを非表示にする .listRowInsets(EdgeInsets()) // 行の余白をなくす(四隅のpaddingを0にする) } .listStyle(.plain) // Listのデフォルトのスタイルを変更 .buttonStyle(.plain) // rowのデフォルトのタップアクションを無効にする .environment(\.defaultMinListRowHeight, .leastNonzeroMagnitude) // rowのデフォルトの高さを0にする プレビュー まとめ 無限スクロールを実現するために List を採用した結果、List のデフォルトの挙動について深く理解する機会となりました。 SwiftUI の List は便利ですが、デフォルトの挙動が多く、その挙動を最小限にするには多くのモディファイアが必要であるとともに、そのデフォルトの挙動を十分に理解する必要があると感じました。 本ブログが List を使う際の参考になれば幸いです。 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! herp.careers
スタメンのCTOの @tnir です。前回は 9年選手のTUNAG RailsアプリをRuby 3.4にアップデートした という記事を書きました。スタメンでは、従業員体験プラットフォーム「TUNAG」の開発にGitHub Copilotを導入し、特にCopilot WorkspaceとGitHub Copilot pull request summaries・GitHub Copilot code review(旧Copilot for Pull Request)を活用しています。 注)Copilot Workspaceは執筆時点(2025年2月)でpublic previewです。 先週末にOpenAI o3-miniがGitHub Copilot上でも利用可能になり利用を開始し1週間ほど経過したので、この記事では10年選手のモノリスアプリケーションを継続的に改善していく上で、GitHub Copilotがどのように役立っているかをご紹介します。previewである機能の利用は GitHub Pre-release License Terms - GitHub Docs に基づきます。 github.blog モノリスの課題と継続的改善 TUNAGは、10年以上の歴史を持つモノリスアプリケーションです。長年にわたって機能追加や改修を重ねてきた結果、コードベースが複雑化し、以下のような課題を抱えていました。 コードの可読性・保守性の低下 新機能開発・改修コストの増大 技術的負債の蓄積 これらの課題を解決し、TUNAGの成長を支えるためには、継続的な改善が不可欠です。 GitHub Copilotの導入 開発効率向上のため、2022年ごろよりGitHub Copilotを導入しました。当時のエンジニアからはこのような評価を得ており、その後現在に至るまでエンジニアには有償版Copilotアカウントを付与しています。 2022年時点での社内エンジニアの評価 先週末の以下のGitHub CopilotのOpenAI o3-mini (preview)サポートの発表を踏まえ、今回は、特にCopilot WorkspaceとGitHub Copilot pull request summaries・GitHub Copilot code review(旧Copilot for Pull Request)に注目し、モノリス改善への効果を期待しました。 GitHub Models users with a paid Copilot plan will also be able to leverage the o3-mini model to enhance their AI applications and projects later today. In the GitHub Models playground, you can explore o3-mini’s versatility as you experiment with sample prompts, refine your ideas, and iterate as you build. You can also try it alongside other models available on GitHub Models including models from Cohere, DeepSeek, Meta, and Mistral. OpenAI o3-mini now available in GitHub Copilot and GitHub Models (Public Preview) - GitHub Changelog Copilot Workspaceの活用 Copilot Workspaceは、IDE上でコードの補完や提案を行ってくれるため、開発効率を大幅に向上させることができます。筆者はVisual Studio Codeを利用していますが、そのエクステンション vscode:extension/GitHub.copilot?referrer=docs-copilot-ai-powered-suggestions を利用しています。 code.visualstudio.com Copilot Chat Copilot Edits TUNAGの開発では、Copilot Workspaceを活用することで、以下のような効果が得られています。 エラーハンドリングの抜け漏れの回避 類似コードの提案によるコーディング時間の短縮 API仕様の自動生成による開発効率化 特に、初期実装から時間が経過したコンポーネントにおいては、Copilot Workspaceがコードの理解を助け、開発スピードを向上させる上で非常に役立っています。 Copilot for Pull Request (GitHub Copilot pull request summaries・GitHub Copilot code review)の活用 Copilot for Pull Requestは、プルリクエストのレビューを支援してくれる機能です。2023年3月時点では GitHub NextでCopilot Enterpriseユーザーのみに提供されていた ため、利用を断念していた人・組織が多いのではないかと思います。GitHub Web上で利用しています。( Copilot for Pull Requestは2023年12月 に廃止されました) 現在は Copilot for pull requests という形で独立したドキュメントになっており、GitHub Copilot pull request summariesとGitHub Copilot code reviewが主な機能です。 TUNAGの開発では、 Copilot pull request summariesとCopilot code reviewを活用することで、以下のような効果が得られています。 変更箇所の説明文の自動生成 レビュー観点の提案 コード品質の向上 プルリクエストのレビューは、コード品質を維持する上で重要なプロセスですが、多くの時間と労力を必要します。Copilot for Pull Requestは、レビュープロセスを効率化し、より質の高いレビューを実現する上で貢献しています。 モノリス改善への貢献 GitHub Copilotの導入により、TUNAGの開発Developer Experience (DevEx) チームは、モノリスアプリケーションの継続的な改善を効率的に進めることができるようになりました。 コードの可読性・保守性の向上 新機能開発・改修コストの削減 技術的負債の解消 2025年に入ってから、DevExチームではバンドリングツールをwebpack 4/5からesbuildへのリプレースするプロジェクトを推進していたのですが、そちらでも活用ができています。 コミットメッセージも次のようになっていて、Copilotというエンジニアと開発している感覚にもなりました。 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> 新モデルの利用 先に書いた通り、1/31にo3-miniがリリースされると同時に、GitHub Copilotでも利用が可能になりました。特に GitHubを運営するMicrosoftグループとOpenAIの協力なパートナーシップ の元、高速なo3-mini対応が実現したと認識しています。これはシングルプロダクト・all-in-oneプロダクトの強みを最大限活かしたものであり、TUNAGが同様にシングルプロダクト・all-in-oneプロダクトであることのSaaS事業運営上の強みと通じるものがあると感じることができました。 blogs.microsoft.com o3-miniだけではなく、既にGemini for Google WorkspaceやGoogle AI Studioで活用できていた Gemini 2.0 も利用可能にしています(オプトインが必要でした)。 今後の展望 私たちは、以下の施策を通じてさらなる改善を目指しています。 本日発表された agent mode を活用した開発の深掘り 既に手元では利用できていましたが、公式に使えるようになったということもあり、深掘りして利用できればと思います。 テスト自動化の拡充 テストケースの自動生成を通じたテストカバレッジの向上ができそうだと感じています。 リグレッションテスト強化にも使えそうです。 ドキュメンテーションが不足しているケースがあるので、その解消にも役立ちそうです。 コードベースの自動ドキュメント生成 ADRの整備にも一役買いそうです。 Gemini 2.0の統合 これまではGeminiとGitHub Copilotでいったりきたりが必要でしたが、それらが統合されたことにより、IDEまたはWebブラウザで操作できるのは快適でした。同じ画面上で用途に応じて使い分けをしていこうと思います。 github.blog まとめ GitHub Copilot、特にCopilot WorkspaceとCopilot for Pull Requestは、モノリスアプリケーションの継続的改善を支援する強力なツールです。DevEx・プラットフォームエンジニアリングの領域においては、まだ適用できないケースもありましたが、それでも生産性向上への貢献は絶大だと感じました。 スタメンでは、GitHub Copilot以外のGenerative AI技術・プロダクトを活用を進めているため、そちらについても別途共有できればと思います。GitHub Copilotの導入は、複雑なアプリケーションを抱える開発チームにとっても非常に有効な手段なので、未導入で迷っているようでしたらぜひ試してもらえればと思います。 注)本記事の内容の執筆に関して、GitHub Copilot の利用規約 (GitHub Copilot プライバシーに関する声明など) を遵守しています。Copilot Workspaceを含む一部の製品機能においてプレビュー版が含まれているため、将来の仕様変更やサービス提供終了に注意が必要です。 この領域でアクセルを踏むため、以下のポジションでエンジニアを募集していますので、チェックいただけると幸いです。 herp.careers herp.careers herp.careers herp.careers 参考 Responsible use of GitHub Copilot pull request summaries - GitHub Docs Using GitHub Copilot code review - GitHub Docs
TUNAG with Ruby 3.4 昨年末12月25日にRubyの最新バージョン3.4がリリースされました。従業員体験プラットフォームTUNAG(ツナグ)を開発・運用している私たちのチームでは、この最新バージョンにいち早く追従。複数のRuby on Railsアプリケーションのバージョンを、すべて3.4.1にアップデートしました(2025年1月10日現在)。アップデート後1週間ほど問題なく運用できていますので、速報として記事化します。 移行前はRuby 3.3.6+YJIT、移行後はRuby 3.4.1+YJITとなります。 $ ruby -V ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +YJIT +PRISM [x86_64-linux] 過去のTUNAGにおいてRuby/Railsのアップデート実績については以下の記事もご覧ください。 tech.stmn.co.jp tech.stmn.co.jp tech.stmn.co.jp YJIT 3.4 今回はYJIT 3.3からYJIT 3.4への移行最終局面でMaxime Chevalier-Boisvertさんによる記事 https://railsatscale.com/2025-01-10-yjit-3-4-even-faster-and-more-memory-efficient/ が公開されたので、最終チェックとして、この情報を活用しました。 特に今回のアプリケーションでRubyの影響を受けるのはActiveRecordの箇所だと捉えると、その高速化は+2.6%と推測していました。 railsatscale.com --yjit-mem-sizeの調整 Ruby 3.1から提供されてきた --yjit-exec-mem-size オプションに加え、YJIT 3.4では --yjit-mem-size オプションが2024年10月に新たに導入されています( https://github.com/ruby/ruby/pull/11810 )。 --yjit-exec-mem-size オプションはこれまでRuby 3.3においてもデフォルト48 MiBのままで運用していたため、 --yjit-mem-size=128 (in MiB) で運用を開始し目立った問題は発生していません。 github.com 全体のメモリ消費量 メモリ使用量については過去のRuby 3.1-3.3周辺のアップデートの中でやや苦労した Ruby/YJITエコシステム的にもメモリの問題はある程度落ち着いてきており、チーム組織内でも特に新たな発見はなく、スムーズにリリースに至りました。 実際のパフォーマンス差 実際に移行前後でのRailsアプリ (puma サーバで実行)のレイテンシー差異は軽微で、有意な差がある高速化は全体平均値や主要な個別箇所では確認できませんでした。今回はcanaryリリースをしない選択をしており、production環境において同一ソースコードの実行結果の差を取得していません。 native gem システム内部通信にgRPCを使っていることもあり、native gemに依存している状況です。Rubyマイナーバージョンアップ時はnative gemの最新マイナーバージョンへの追従が例年遅れる傾向にあります。 Ruby 3.3リリース直後と同様に、Ruby 3.4リリース直後もこれらのgemではネイティブビルドが利用できなくなりました。DevExはやや低下しますが、最新技術の活用を優先しています。この制約は約1ヶ月程度で解消される見込みで、通常は毎年2月ごろに改善されています。 native gemはfat gemと呼ばれることもあり、廃止したいという意見もあるようです。が、RubyGemsのキャッシュの兼ね合いからnative build gemは開発・運用業務をする上ではまだ必須かなという認識です。 www.clear-code.com 特に grpc gem はローメモリでのビルドが難しくCI環境などでメモリ不足が起因でビルドに失敗するケースに遭遇しています。こちらの問題はRuby 3.4対応のgrpc native gem (grpc 1.70.0予定) で解消される見込みです。 Stacktraceにクラス名が含まれることでSentryでFingerprintが変わる 2024年2月に、stacktraceにメソッド名のみが含まれていたものがクラス名+メソッド名が出力されるようになりました。 github.com Ruby 3.3以前に「後回しにした」(*1)エラーが、再度新規エラーとして扱われるようになりました。幸い、該当するエラーは数件程度だったため、手動でグルーピングすることで問題なく対応することができました。 事前準備は大事 プレリリース版より検証することが重要です。今回のRuby 3.4シリーズのプレリリースのうちpreview2とrc1を利用して、2024年中より評価・検証を進めました。 Ruby 3.4.0-rc1 2024-12-12 Ruby 3.4.0-preview2 2024-10-07 オフラインで開催されるRuby/Rails勉強会も有用な情報として助かりました。特にFukuoka.rb / 株式会社Ruby開発共催の福岡 Rubyist会議 04への参加は内部構造を理解するのにとても参考になりました。 regional.rubykaigi.org 毎週のように都内ではRuby関連勉強会は実施されているので、タイミングが合えば今後も積極的に参加していこうと思います。また、年次カンファレンスRubyKaigiも最もRubyについて深い議論ができるため、参加したいと考えています。 今年もスタメンからRubyエンジニアを中心にプロダクトメンバー複数名で参加する予定です。 いつやるのかという意思決定 プロジェクト実施を意思決定する以前から利用していたRuby 3.3は、2027年3月にEOLを迎えることが確定していました。そのため、今回のバージョンアップはそれまでの約2年間で実施する必要がありました。組織・プロダクトの状況を考慮すると、最大2年間は後回しにすることも可能でしたが、2024年のコミュニティへのフィードバックという貢献を最大化するため、このタイミングでの実施に至りました(実際には12月末はホリデーシーズンでチームは稼働していなかったため、年明けからの開始となりました)。 2025年第1週には最終プロセスに入り、すべて完了しています。しかし、productionレベルでの投資は2024年10月頃から緩やかに開始していました。例年以上に、特に今年の1月はチームに多くの新入社員が参画したこともあり、最初の週の実施はハードスケジュールでした。個人的には、2週目の実施でもよかったのではないかと感じています。 早期に実施することにリスクを感じる方もいるかと思いますが、私たちのチームではプロダクト内でのリスク回避策を講じることで、リスクを限定的に抑えられています。このあたりについては、読者の皆様が技術選定をどのように行っているのか、今後お伝えできればと思っていますし、他社の事例についても情報交換したいと考えています(執筆時点では、一定規模以上でRuby 3.4にアップデートしたという報告事例はあまり見つけられませんでした)。 我々もRuby 3.4力をつけて4月に愛媛で開催されるRubyKaigi 2025に参加し、各社でのRuby 3.4利用状況について議論できることを楽しみにしています。 参考 noteにも詳細を載せた関連記事を掲載していますので、ご参照ください。 https://note.com/takuya_stmn/n/n673ed32f80fe?magazine_key=m3805182520ce
TUANGのプロダクト開発チームでAndroidアプリを開発している カーキ です。 最近は、ダンダダン のアニメ放送に毎週歓喜しています。 2024年の末に投稿しようと思っていたものの、気付いたら年を越して2025年になっていました。 スタメンのAndroidエンジニアは3-4人と、決して大きい組織ではありませんが、機能開発をしつつプラットフォームの改善にも並列で取り組んでいます。 今回のブログでは、2024年の1年間でのAndroidチームでの技術的な変化・挑戦をまとめて紹介します。 Compose のコード規約を作成 TUNAG の Android プロジェクトでは、2021年ごろから Jetpack Compose をUI作成のフレームワークとして導入していました。 これまでは Jetpack Compose について知見にあるメンバーが知見の浅いメンバーに対して教えたり、レビューを通じて知見を共有することで、Jetpack Compose の共通認識を作っていました。 ただ実際にComposeのコードを書くメンバーが増えたときに、複数の書き方があるときにどちらを選択したら良いかが分からないなどの問題が表出してきました。 そこで、これまで暗黙的に共有されていた記述方法を言語化したり、まだチームの中で方針が決まっていなかった部分を GitHub Issues などで議論を深めていきました。 また自社での Compose のコード規約を考える上で、 API Guidelines for Jetpack Compose を参考に作成をしました。 コード規約の一部 コード規約は GitHub の wiki にまとめています。 コード規約が策定されたことによって、実装者が安心してJetpack Composeを利用することができるようになりました。 また成果物としてのコード規約の影響だけでなく、チームのメンバーでコード規約を作る過程にも価値があったと感じています。 コード規約では、いくか記述法として方法がある中で「なぜその選択をしたのか」の背景が必要になります。GitHub Issues などで議論を深める中で、「一般的にそう書かれているから」ではなく、「なぜその書き方が良いのか」について話し合うことができました。 様々な方法がある中で、TUNAGというプロダクトでなぜその選択をするのかについて、話し合うことができたのが良かったと感じています。 lintを導入 コード規約の作成に加えて、Compose の記述方法に関する lint をプロジェクトに追加しました。 今まで TUNAG 全体でも linter は未導入だったのですが、プレビュー用のComposable関数のprivate 修飾子のつけ忘れなど、どうしても抜け漏れが発生していました。 Compose のコード規約をチームで守っていくために linter の導入を決めました。 linter としては、 detekt を採用しました。 外部から Compose の lint のルールセットを追加できる点であったり、潜在的なバグの検出などのルールが標準で用意されている点で detekt を選択しました。 採用したルールに関しては、自分たちで作成したコード規約をもとに、必要なものを取り入れる形で決めています。 また linter による指摘を GitHub Actions の reviewdog を使って、PRでコメントされるようにもしています。 reviewdogによるlintのワーニング通知 これによってレビュワーによるレビューの前から、問題を検知することができるようになりました。 マルチモジュールのアップデート TUNAGでは、2020年ごろからマルチモジュールの導入を行っていました。 しかし、この当時のマルチモジュール化は細かい責務分けができていなかったため、むしろ負債になっている状態でした。 そこで2023年ごろから、責務分けなどを考慮した上でモジュールを再編していました。2024年はそれをさらに進化させ、モジュールを介した画面遷移を行うためのNavigationモジュールの作成を行いました。 マルチモジュールのアプリ構成では、モジュールを横断した画面遷移は依存関係が循環してしまうため、機能ごとでモジュールを切ることができませんでした。 モジュールが膨大になってくるとそのままビルドの速度にも影響します。機能をモジュールで分割できずappで実装することになり、ビルドの速度やJetpack Composeのプレビューに時間がかかる状態になっていました。 Navigationという画面遷移の抽象のみを持つモジュールを用意し、遷移実装をappで持たせることで、モジュールの依存関係が循環しないような形で実装をすることができました。 この実装が用意されたことで、2024年からは機能ごとにモジュールを分けることが可能になり、新機能に関しては新しい機能モジュールとしてスムーズに開発を進めています。 アプリの起動のフローの整理 アプリ起動処理のフローの整理を行いました。 元々はタイムラインの機能を提供するMainActivityにすべての実装がありました。そのためMainActivityの実装が非常にファットになっており、本来のタイムラインのために実装したい処理との区別がつかないような状態になっていました。また新たに起動時に処理させたいことがあっても、現在の処理を理解することが障壁になっており、機能追加時の障害にもなっていました。 それらを解消するために、起動の処理を整理し、MainActivityからの引き剥がしを行いました。 これにより、起動時にはどのような順番で処理が行われて、処理に応じたユーザーへの表示が明確になりました。 アプリの起動フロー再構成時に利用したメモ Android15対応 2024年秋に安定版がリリースされ、提供されている Android15 の対応を実施しました。 TUNAGプロジェクトとしては、そこまで大きな対応はありませんでしたが、edge-to-edge の対応が全画面に対して必要となりました。 edge-to-edge 対応とはAndroidのシステム領域である「ステータスバー」や「ナビゲーションバー」まで画面の描画領域を広げることができる機能です。 edge-to-edge の提供自体は過去から提供されていましたが、Android15 以降を targetSDK に設定しているアプリでは、強制的に適用されるようになりました。 TUNAGのAndroidプロジェクトはほとんどの画面でActivityベースで開発が行われているため、すべての画面において edge-to-edge の対応を行う必要がありました。 今回の対応としては、edge-to-edge で利用できるようになった領域に関しては従来通り透過をしないという暫定的な対応をしました。 今後よりネイティブアプリとして真価を発揮できるよう、画面に応じてナビゲーションバーの領域を一部透過するなど適宜対応していく方針となっています。 Kotlin 2.0への更新 Kotlin2.0へとメジャーバージョンの更新を実施しました。 TUNAGでは通常Kotlinのリリースの1ヶ月以内でのプロジェクトへの導入・リリースを目指しています。ただ今回はメジャーバージョンの更新であったため、慎重に検証を行いました。 結果としては、TUNAGにはそこまでKotlinのバージョンに依存しているライブラリが少なかったため、大きな問題もなく上げることができました。 Kotlin 2.0 へのアップデートでの大きな目玉としては、K2コンパイラへ移行があります。 ただK2コンパイラが Android Studio で利用可能になった当時はアルファ版であり開発に支障をきたすレベルのバグが存在していました。年末時点でK2コンパイラーを普段の開発で利用しているメンバーはおらずその早さはまだ実感できていません。 今回チームで2024年を振り返ったタイミングで、改めてK2コンパイラを使ってみようとなり、K2コンパイラの性能についてはこれからチームで検証していくこととなります。 PicassoからCoilへの移行 2024年11月に Picasso が非推奨となり、 Coil への移行が推奨されることがアナウンスされました。 TUNAGアプリは2018年当時からPicassoを利用しており、かなりの部分でPicassoに依存していました。 2023年からは Jetpack Compose で実装している部分に関しては一部 Coil の利用していましたが、過去に AndroidView で実装された部分に関してはすべてPicassoが利用されていました。ただ現在は Jetpack Compose での実装がメインとなり、TUNAG においては Coil がデファクトスタンダードになりつつあることを踏まえて、AndroidView で実装された箇所に関してもこの機会に Coil に移行する措置を行いました。 元々 Jetpack Compose のために Coil を導入したときにシングルトンの ImageLoader インスタンスの実装を行っていたため、両ライブラリで多少の違いはあったものの単純な置き換え作業となりました。 Markdown の検証 TUNAGの投稿では、マークダウンを利用することができます。 今まではWebViewのHTML表示などを利用して騙し騙しにマークダウンを提供していましたが、アプリケーションとしてよりWebViewに依存しないような構成にするために、TextViewベースのマークダウン表示の技術検証を行いました。 こちらは Markwon というライブラリをカスタマイズして、TUNAGでのマークダウンの書式が適用されるようにしました。 現在は技術検証が終わった段階で未リリースですが、これから順次アプリ内のマークダウンの表示を、こちらのネイティブベースのものに置き換えていく方針です。 最後に2025年に向けて 今回は2024年にTUNAG Androidアプリにて行った技術的な変化と挑戦を紹介しました。 こうして並べてみると、結構様々なチャレンジを行ってきたんだなと感じます。 機能開発だけでなく、アプリ開発におけるプラットフォームの改善にもより一層力を入れて、機能開発のベースラインを向上し、生産性の向上を目指しています。 株式会社スタメンでは、2025年より一層開発部門のギアを上げていくために全方向で開発メンバーを募集しています。 herp.careers
みなさんこんにちは、プロダクト開発部でTUNAGの開発をしている 小松 です。 先日行った社内イベント「BKP(ベスト開発ピッチ)」について紹介します! 今回のイベントは、プロダクト組織(エンジニア、PdM、プロダクトデザイナー)とカスタマーサクセス部(以下、CS部)が一緒になって取り組んだ初めての試みでした。 普段の業務ではなかなか伝えきれない「プロダクト開発の裏側」や「日々の活動や成果」を共有する場として開催し、大いに盛り上がりました。 BKPとは? 「BKP(ベスト開発ピッチ)」は、プロダクト組織が日々の成果や活動をピッチ形式で発表し、共有し合うイベントです。 もともとは、CS部で毎月恒例の「BKP(ベスト更新ピッチ)」がきっかけとなりました。CS部では、BKPで共有された取り組みが他のメンバーに受け継がれ、成果につながるという好サイクルが生まれています。 今回はCS部のメンバーからの提案を受け、この良い文化をプロダクト組織でも取り入れようと、企画段階からCS部と一緒に進め、プロダクト組織でも初めて実施することとなりました! プロダクト組織のBKPでは日々の活動や成果を共有しながら、メンバー間や部署間の連携を深め、称賛の文化を育むことを目的としてます! 開催の背景と目的 目的 プロダクト組織のナレッジを可視化 隠れた貢献の表層化・称賛の文化を育む 部門間の相互理解を深め、より良いサービスを届ける プロダクトをより良いものにするには、CS部とプロダクト組織の協力が欠かせません。 CS部は日々お客様からのフィードバックを集め、プロダクト改善のヒントを提供してくれています。一方で、プロダクト組織もその声を受け、新しい機能の開発や改善に取り組んでいます。 ただ、プロダクト開発部とCS部間の活動内容が見えづらいという課題もありました。 そこで、「BKP」を通じて、プロダクト組織が普段どのように改善や新機能の開発に取り組んでいるかを共有し、部門間の連携を深める場を作りました。 CS部とプロダクト組織が密に連携することで、スピーディーかつユーザーに価値のあるプロダクトを届けることを目指しています。 (取り組みの詳細は スタメン公式note でご覧ください。) 当日の様子 当日は、オンラインで開催され、6名のメンバーがそれぞれのテーマでピッチを行いました。 発表では、プロダクト改善の裏側や、未来のビジョン、新しい機能開発に込めた思いなどが語られました。 タイトル 登壇者 よりアプリらしさを出すために おしん 自動化しませんか? まっきー 管理画面の情報設計を見直した話 森田かすみ きれいなコードと責務のお話 hisayuki_mori レガシーコードDestiny〜本音を論じたい〜 カーキ プラットフォーム部のとある一日 uuushiro CS部からは「改善の裏にこんなストーリーがあったんですね」「新しい機能の背景がわかって嬉しい」といったコメントが寄せられ、互いの活動への理解が深まる時間となりました。 また、投票によるピッチ優勝者の表彰も行いました。もっとも多く票を集めたのは、まっきーさんの「自動化しませんか?」でした! プロダクト運用の効率を大幅に向上させた自動化の取り組みについて、具体例を交えながら分かりやすく説明しており、参加者から高い評価を得ました。 優勝したまっきーさんを始め、登壇したメンバーを皆で賞賛し、楽しい雰囲気の中でイベントを締めくくることができました! 今回のイベントを実施して感じたこと 1人1人の手で高めるプロダクトの価値 プロダクト組織の業務は、単にソフトウェアを作るだけではありません。 私たちは、部門を超えた協力の中で、より良いプロダクトをスピーディーに実現することを目指しています。 今回の「BKP」では、各メンバーが自身の取り組みを発表し、普段の業務ではなかなか共有できない知見や経験を共有する場となりました。 発表の中で感じたのは、「プロダクトをより良くしたい」という思いに基づいた真剣さと情熱です。 一人ひとりが主体的に発表し、他のメンバーと意見を交わす中で、チーム全体の結束がさらに強まったと感じています。 部門を超えたコラボレーションと一体感 また、スタメンでは、部門間の距離が近く、気軽に話しやすい環境が整っているため、こうしたイベントが自然体で進むのも魅力の一つです。 部門を超えた取り組みを通じて、多角的な視点を得ながらプロダクトづくりを進められるのは、スタメンならではの特徴だと思います。 このような環境の中で、メンバー全員が一体感を持ってプロダクトを磨き上げる姿勢を改めて実感しました。 今回の「BKP」をきっかけに、CS部との連携をさらに強化し、TUNAGをご利用いただく皆さまに価値を届けることで、感動や幸せが感じられるプロダクトを目指していきます。 採用情報 スタメンでは、プロダクト開発に関わる全ての領域でプロダクト職種の採用をしています。 もしご興味を持っていただけたら、下記からご応募ください! herp.careers herp.careers
この度、株式会社スタメンは、2024年12月05日(木)〜06日(金)の2日間、オンライン & オンサイトで開催される「プロダクトマネージャーカンファレンス 2024(pmconf 2024)」に、Silverスポンサーとして協賛します! カンファレンス情報 名称 :プロダクトマネージャーカンファレンス 2024(pmconf 2024) 開催日時:2024年12月05日(木)〜12月06日(金) 場所 :DAY1(オンライン)、DAY2(オンサイト:東京都大田区羽田空港2丁目7−1羽田エアポートガーデン) 参加方法や詳細については、下記公式サイトをご覧ください。 2024.pmconf.jp 当社スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」を開発・提供しています。 2017年のサービス提供開始当初から、TUNAGは当社の成長を牽引してきたプロダクトです。 今回初めて、プロダクトマネージャーカンファレンスのスポンサーをさせていただきます。 当日のブース出展はありませんが、弊社からはPMの2名が現地参加します! オンサイト参加の方は、ぜひ現地で交流しましょう! おわりに プロダクトマネージャーカンファレンス 2024の2日間を通して、プロダクトマネジメントに対する学びを深め、よりよりプロダクトづくりに活かしていきたいと思っております。DAY2では、現地参加の皆様とお会いできることを心待ちにしております! 宣伝:直近の事業やプロダクト組織の取り組みもぜひご覧ください! 10→100フェーズを最前線で - デスクレスSaaS TUNAG(ツナグ)のProduct Managerをやる面白さ note.com スタメン技術ロードマップ 2025-2026 note.com 採用情報 スタメンでは、プロダクトマネージャーに限らず、全ての領域でプロダクト職種の採用をしています。 もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
はじめまして。TUNAGプロダクト開発部の勝間田です。2024年9月より株式会社スタメンにジョインしました。 2024/10/25 ~ 26で開催された Kaigi on Rails 2024 に当社からは、7名のメンバー(1人写真に入れず。。)で現地参加させていただきました。 Kaigi on Railsは「初学者から上級者までが楽しめるWeb系の技術カンファレンス」をコアコンセプトにしています。 普段Railsを使う中で感じた課題・困難とその解決策がセッションになることが多く、日々の開発に役立つような学びの多いカンファレンスです。 会場の様子 セッション会場は「Hall Red」と「Hall Blue」に分かれており、それぞれが視聴したいセッションを自由に選べる形式でした。 「Sponsor Booth Area」にはさまざまなブースが出展されており、楽しいコンテンツが豊富に用意されていました。 体験を通じて「このプロダクトをこの人数で運営しているのか」「意外とシンプルな構成だな」といった発見や驚きもありました。 また、「わいわい部屋」と「もくもく部屋」が用意されており、一息つきたい時や急な業務対応ができる環境もありました。 フロアマップ スタメンは Silver Sponsor として協賛させていただきました。 スポンサーボード 気になったセッション 約9000個の自動テストの時間を50分から10分に短縮、偽陽性率(Flakyテスト)を1%以下に抑えるまでの道のり speakerdeck.com テスト時間を短縮するためのさまざまな手法が、導入難易度も含めて丁寧に解説されており、とてもありがたい内容でした! 私自身もこの課題に向き合い、紹介された手法をいくつか試した経験があるため、勝手に親近感が湧いてしまいました(笑)。 Flakyテストも確実に減らされており、最終的にテスト時間やCI費用が大幅に改善されていました。 同じような課題に直面した際は、この内容を思い出してみようと思います。 推し活のハイトラフィックに立ち向かうRailsとアーキテクチャ speakerdeck.com ハイトラフィックなイベント物販サービスにおける在庫の確保と決済の対処方法についての内容でした。 具体的には、従来は「商品ID」と「在庫数」を1つのレコードで管理しており、ハイトラフィックな環境では行ロックによるデッドロックが頻発する問題がありました。 これを「1在庫1行」のデータ構造に変更することで、デッドロックを回避する手法が紹介されていました。 当時の状況や実際に起きた問題を、アイデアで解決していくお話が痛快で、とても楽しかったです! Data Migration on Rails speakerdeck.com Railsアプリでのデータマイグレーションについて、代表的な手法とそれぞれのメリット・デメリットをが紹介されていました。 これまで、手法についてあまり深く考えたことはなく、その時々のプロジェクトや状況に応じて選択していたことに気づかされました。 もしチームとして明確な方針が固まっていないのであれば、今回の内容を参考に話してみるのも良さそうです。 また、セッションで紹介されていた maintenance_tasks gemは権限管理や管理画面を提供しているみたいで気になるので今度実際に触ってみようかと思います! アーカイブ動画が公開されたら現地で視聴できなかったセッションも見てみようと思います! 同じくオフライン参戦したエンジニアの感想 まっきー : Kaigi on Railsは初参加だったのですが、実践的な内容のセッションが多くあり、持ち帰れる物の多い充実した2日間でした。 特に印象に残ったセッションは Identifying User Identity です。Railsアプリケーションをそれなりの期間運用しているとどうしてもユーザーモデル周辺が肥大化しがちなのですが、これに対するアプローチとして新たな視点を得ることができました。 また各企業のブースが面白く、お弁当も美味しかったりと、コミュニティとしての素晴らしさを体験することができました。機会があれば運営として参加もしてみたいと思えました。 speakerdeck.com 最後に 今回、個人として初めてオフラインのカンファレンスに参加しました。 福利厚生の一環として、参加費を負担していただき、業務としてこのような機会をいただけたことに感謝しています! Railsエンジニアの方々との交流や会場で感じた雰囲気は、オフラインでしか得られないもので、より一層研鑽への意欲が高まりました。 またカンファレンス開催にあたりご尽力いただいた運営スタッフの皆様に心より感謝申し上げます! 採用情報 スタメンでは、Ruby on Railsエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 herp.careers
みなさんこんにちは、プロダクト開発部でAndroidアプリを開発している カーキ です。 先週の10月25日に開催された mobile.stmn にて「Composeで敷き詰めるUIをどうやって作るか」というタイトルで発表をしました。登壇した資料自体はSpeakerDeckにも公開をしていますが、せっかくならと思いテックブログでも公開してみることにしました。 導入 タイトルに「敷き詰めるUI」と書いていますが、これは以下の画像のように水平・鉛直方向へ要素が敷き詰められるようなレイアウトを指しています。 敷き詰めるレイアウトの例 このようなレイアウトをJetpack Composeで実現する方法として、2つのレイアウト方法が提供されています。 Lazy〇〇Grid Flow〇〇 Lazy〇〇Gridとは、LazyVerticalGridやLazyHorizontalGridなどに代表されるレイアウトコンポーネントです。またFlow〇〇とは、FlowRowやFlowColumnなどに代表されるレイアウトコンポーネントです。それぞれのレイアウトコンポーネントに関して、以下で基本的な性質から紹介していきます。 Lazy〇〇Gridについて 基本性質 名前の通り Lazy〇〇Grid は格子状のレイアウトを遅延表示することができるレイアウトコンポーネントになります。LazyColumnやLazyRowと同じようにcontentブロック内では、 item や items などのメソッドが利用できます。 主にLazyVerticalGridとLazyHorizontalGridという2つのコンポーネントに分けられ、それぞれ以下のように要素が敷き詰められます。 Lazy〇〇Gridの並び方 LazyVerticalGridは垂直方向へ敷き詰めが行われ鉛直方向にスクロール可能になり、LazyHorizontalGridは鉛直方向へ敷き詰めが行われて垂直方向へのスクロールが行われるため、注意が必要です。 LazyStaggeredGridについて LazyVerticalGrid, LazyHorizontalGridでは、格子状のレイアウトになるため、要素の大きさは均一になります。ただこれらのレイアウトと近縁関係にある LazyStaggeredGrid を利用することで高さもしくは、横幅の大きさを可変なものとしてレイアウト可能になります。 公式ドキュメントより LazyStaggeredGrid の実装例 LazyStaggeredGrid は執筆時点(2024/11/01)で Experimental なレイアウトとなっています。 GridCells LazyHorizontalGridでの格子の敷き詰め方は colums というパラメータによって決まります。(LazyHorizontalGridの場合は rows というパラメータ) columns は GridCells を継承したクラスを要求しており、 compose.foundation では以下の3つのクラスが用意されています。 GridCells.Fixed GridCells.Adaptive GridCells.FixedSize 1. GridCells.Fixed Fixedでは、一列の中に配置する要素の個数を指定することができます。 GridCells.Fixedで指定した場合 指定された個数に従って要素の大きさが決まります。 2. GridCells.Adaptive Adaptiveでは、一列中の要素の幅の最小値を指定することができます。(LazyHorizontalGridの場合は高さの指定になります) GridCells.Adaptiveで指定した場合 指定された幅の最小値に従って表示することの可能な個数分配置されます。指定しているのはあくまで最小値になるため、親のレイアウトの幅が88.dpで、Adaptive(20.dp)と指定した場合は、一列中に4つの要素が配置され、その幅は22.dpとなります 3.GridCells.FixedSize FixedSizeでも、一列中の要素の幅(もしくは高さ)を指定することで配置を指定します。ただAdaptiveと異なっているのは、列中で余った領域に関してはArrangement.Horizontal の指定に従うようになっています。例えば以下の画像では、Arrangement.Horizontalの指定を Arrangement.spaceBy(8.dp) としているため、要素間の間隔を8.dpにするために余剰分に関しては、画面右に寄せられています。 GridCells.FixedSizeで指定した場合 ヘッダーの表示 LazyGridのitemとして、ヘッダー要素を表示させることができます。ただ普通にitemのブロックに要素を入れただけでは、下画像のようにグリッドの要素として組み込まれてしまいます。 item のブロックに単純にヘッダー要素を入れた場合 以下のように span を実装する必要があります。 @Composable fun LazyGridHeaderSample() { LazyVerticalGrid( columns = GridCells.Fixed( 3 ) ) { item( span = { GridItemSpan(maxCurrentLineSpan) } ) { Text(text = "Header" ) } items( 10 ) { index -> ... } } } span に maxCurrentLineSpan で指定すれば、空いているGridのスペース分の領域をコンテンツブロック内で確保することができます。上記のコードで並べた結果が以下のようになります。 GridItemSpanを利用してitem のブロックに単純にヘッダー要素を入れた場合 GridItemSpanを利用することでLazyVerticalGridを利用してヘッダーを表示することができます。 Flowレイアウト 基本性質 Flowレイアウトは 公式のドキュメント では、「ColumnやRowのコンテナのスペースが不足した時に、要素が次の行に流れ込む性質を持ったコンポーネント」と説明されています。次の行に流れ込む性質を持ったColumnやRowと説明されている通り、レイアウト方向に応じてFlowColumnやFlowRowなどが存在します。Flowレイアウトは執筆時点(2024/11/01)で、ExperimentalLayoutApi とされており、試験運用版という扱いになっています。 Flowを使うことで以下のようなタグの表示を実現することができます。 公式ドキュメントよりFlowレイアウトの例 Flowレイアウトでは、上記のタグのように要素を並べていく方向の幅を可変にすることができます。LazyVerticalGridでは基本的に並べる方向の幅は全て均一になります。格子状に並べる上ではLazyGridが適していますが、サイズの異なる要素を順に並べていくのはFlowレイアウトが適しています。 Arrangement Flowレイアウトの敷き詰め方は、 HorizontalArrangement と verticalArrangement という引数に何を渡すかによって決まります。これらのパラメータへの指定によって右寄せ・左寄せ・等間隔など様々な配置方法を指定することができます。 この辺りは 公式のドキュメント が詳しいので説明はそちらに譲ります。 2つの使い分け ここまでLazyGridとFlowレイアウトの性質について紹介してきました。ざっくりそれぞれのレイアウトコンポーネントの特徴をまとめると以下のようになります。 LazyGridは、格子状に要素を敷き詰めるのに適したレイアウトコンポーネント Flowレイアウトは、折り返しを考慮してものを敷き詰めたい時に適したコンポーネント この2つの比べると格子状の場合はLazyGridで、それ以外の場合はFlowを選択するのが良いように感じます。ただLazyVerticalGridはLazyなレイアウトになるので、同一方向のLazyのレイアウトを親や子に持てないなどといった、それぞれ採用判断に影響する差異が存在するので紹介します。 LazyGridが向いているケース スクロール方向と交差する方向のサイズが固定である 表示量が多いなど、遅延して表示したい要件がある Experimental な機能を利用できない Flowレイアウトが向いているケース 要素の大きさがものによって変わる 遅延して表示させる要件がない グリッドの部分のみ背景を変えたい要件がある 「Flowレイアウトが向いているケース」の最後の項目だけより具体的な事例を出していますが、TUNAGの開発中にこのパターンに当たり、Flowレイアウトを採用したという背景があります。 具体的には以下のような画面になります。(該当の画面を抽象化して示しています) 特殊な実装例 こちらの画面では均等に要素を並べるようなUIを想定していたため、LazyVerticalGridの採用を検討していましたが、グリッドの部分のみ背景色を変更することがLazyGridではできません。この画面はスクロールも要求していたので、LazyVerticalGridで実装する場合画面全体をLazyVerticalGridでレイアウトする必要がありました。ただ特定のitemsのブロックの中でのみパディングや背景色の変更を行うことが難しかったため、FlowRowを採用しました。 何か複雑に組み合わせることで、LazyVerticalGridの利用も可能だったかもしれませんが、今後のメンテナンス性も考えると、シンプルな利用で表現することができるFlowRowに寄せることとしました。 LazyGridとFlowレイアウトでは、それぞれ向いているレイアウト方法がありますが、どちらのレイアウト方法でも実現することができるのもまた事実です。基本的にはそれぞれのレイアウトコンポーネントの基本性質にあった方法を取れるのが良いですが、それでも実現することが難しい場合・実装があまりにも複雑になりすぎてしまう場合があります。それぞれのメリット・デメリットのトレードオフを考えて実装されるのが良いかと思います。 まとめ 今回のブログでは、LazyGridとFlowレイアウトの紹介と比較を行いました。 どちらでもできること・どちらかにしかできない表現があるため、それぞれの性質を理解した上で、どちらを利用するのかを要件に沿って選ぶのが良いと思います。 株式会社スタメンでは、チームで議論を深めながらJetpack Composeの利用の幅を広げています。Jetpack Composeが大好きなAndroidエンジニアの方はぜひ一度カジュアル面談からお話を聞いてみてはいかがでしょうか。 herp.careers herp.careers
こんにちは。 この度、株式会社スタメンは、2024年10月25日〜26日の2日間、有明セントラルタワーホール & カンファレンスにて開催される「Kaigi on Rails 2024」に、Silverスポンサーとして協賛します! カンファレンス情報 名称 : Kaigi on Rails 2024 開催日時 : 2024年10月25日(金)〜10月26日(土) 場所 : 有明セントラルタワーホール & カンファレンス + オンライン 参加方法や詳細については、下記公式サイトをご覧ください。 kaigionrails.org 当社スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」を開発・提供しています。 TUNAGの開発では 2017年のサービス提供開始当初から Ruby on Rails を採択してきました。 リリース当初から、開発を推し進めることができているのは、Rails関連の技術コミュニティの支えがあってこそであり、 昨年 に引き続き 今年も協賛させていただく運びとなりました。 当日のブース出展はありませんが、弊社からはエンジニア、HR含め7名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! おわりに Kaigi on Rails の2日間を通して、Railsエンジニアの皆様だけでなく、様々な技術領域のWebエンジニアの皆様とお会いできることを心待ちにしております! 宣伝:直近の事業やプロダクト組織の取り組みもぜひご覧ください! PIVOT:【日本の労働人口の約半分】飲食・小売・物流…ノンデスクワーカー業界を変える/低い労働生産性 解決のカギは組織エンゲージメントの向上/組織づくりを支援する「TUNAG」とは www.youtube.com スタメン技術ロードマップ 2025-2026 note.com 10→100フェーズを最前線で - デスクレスSaaS TUNAG(ツナグ)のProduct Managerをやる面白さ note.com 採用情報 スタメンでは、Railsエンジニアに限らず、全ての領域でエンジニアを募集しています。 もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers 参考:エンジニアのカジュアル面談Q&Aから見るスタメンの姿 note.com
TUNAG プロダクト開発部 第2グループの カーキ です。 先週9月11日から13日にわたって開催されたDroidKaigi2024にプロダクト開発部のメンバー4人で参加しました。 参加メンバーでパシャリ📸 今年はサポータースポンサーとしてスタメンもイベントにスポンサードしています。 DroidKaigiスポンサー紹介のスライド DroidKaigi振り返り Workshop Day 初日は JetBrains の方を講師に招いて、Kotlin Multiplatform(以下:KMP)を使ったAndroidアプリ・Webアプリ・デスクトップアプリをビルドするワークショップが開催されました。JetBrains の方に直接質問もできる貴重な機会でした。 ワークショップの様子 ワークショップでは Fleet という JetBrains が KMP のために開発した IDE を利用して行われました。Fleet という IDE は知っていたものの、思った以上にサクサクと開発できて感動しました。ビルド時間が長いなどの問題はありましたが、プレビュー版ゆえのものだと思っておきます🤫 またワークショップでは Compose Multiplatform(以下:CMP) のワークもありました。Android 開発での UI 作成のフレームワークがWebやデスクトップアプリでも全く同じ体験として実現できるのには驚きました。 今回ワークショップに参加をしてみて、KMPとCMP 思ったよりもいけるぞ!と感じました。CMP は一部アルファ版のものもありビルドターゲットによっては、まだ不安はありますが、CMPを使った開発の快適さを感じました。 のぼりの前で📸 2,3 日目のセッション 2日目以降では各ルームでセッションが開催されました。 今年もセッションルームには代々の Android Studio のバージョン名になった動物たちの名前がついていました(カワイイ-) 各ルームのキャラクター 2日間で本当にたくさんのセッションがあり、何を聞きに行くのかも毎回迷ってしまいました。気にはなっていたが渋々見ることができなかったセッションもあるので、それらは公式があげているYouTubeの動画をこれから見ていこうと思っています。 スタメンメンバーが見たセッションの中から印象に残ったセッションをいくつか紹介します。 Androidエンジニア カーキ(自分) 仕組みから理解する!Composeプレビューを様々なバリエーションでスクリーンショットテストしよう 自分が印象に残ったセッションは『 仕組みから理解する!Composeプレビューを様々なバリエーションでスクリーンショットテストしよう 』です。Compose によって作成されたビューはテストがしやすいということは知っていたものの、現状のプロダクトコードには Compose のテストは存在していなかったので、プレビューを利用してどのようなテストが行えるのかが気になっていました。様々なテストツールを利用することで複数プレビューのパターンに対応することができることが段階的に説明されており、中長期的な目線でスクリーンショットテストを導入するかどうかを検討する上での材料になりました。 Androidエンジニア ケンタ PDF Viewer作成の今までとこれから AndroidにおけるPDFビュワーの歴史から細かな実装まで、とても詳細に解説されていて良いセッションでした。 Androidエンジニア ヒビキ たすけて!ViewModel ViewModelの役割や説明を踏まえてよくある誤りから責務の分離がとてもわかりやすかったです。ComposeとViewModelの強い関係性からもこのセッションを聴いて再認識できてよかったです。 CTO 野口 昨年に続き、DroidKaigi 2024に参加し、Android開発のトレンドを肌で感じることができました。特に、Jetpack Composeが十分にデファクトスタンダードになってきている点や、Kotlin Multiplatformの他社導入状況について議論することができました。ビジネス的には競合であったりする会社に属しているエンジニアと会話し、新たなコミュニティに繋がることができたのも技術コミュニティあってのことだと認識しています。スタメンでは今後もより高品質なAndroidアプリ開発を目指していきます。 さいごに 初日のワークショップや、2日目からのセッションはもちろんですが、DroidKaigiには美味しいコーヒーの提供やネイル体験、プリクラなど、参加者が楽しめる仕組みが沢山ありました。 自分は今回のDroidKaigiがオフラインでは2度目の参加になりますが、本当に3日間ずっと充実していました。 セッションで得た情報をそのままにせず、チームで共有をして日々の開発に活かしていくために、チーム内で共有会を開催しようと思っています。 採用情報 株式会社スタメンではAndroid領域に限らず、様々な領域でエンジニアを募集しています。 herp.careers
こんにちは! 株式会社スタメンは、2024年9月11日〜13日の3日間、ベルサール渋谷ガーデンにて開催される「DroidKaigi 2024」に、サポータースポンサーとして協賛します! スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」の、Android向けアプリケーションを開発・提供しています。 より多くのユーザーが快適にTUNAGをご利用いただくため、当社エンジニア組織ではモバイル先行の開発体制や開発プロセスにシフトしています。 モバイル先行の開発を推し進めることができているのは、Android関連技術コミュニティの支えがあってこそであり、昨年に引き続き今年も協賛させていただく運びとなりました。 参考:これまでのスポンサーやAndroid関連のテックコミュニティでの取り組み DroidKaigi 2023にスポンサーとして参加しました! スタメンが主催で開催しているモバイル開発の勉強会「mobile.stmn」が1周年を迎えました DroidKaigi.collect { @Nagoya } ※会場提供のみ 本カンファレンスへの協賛を通して、これからのAndoridアプリ開発者コミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! カンファレンス概要 開催:2024年9月11日(水)~ 9月13日(金) 場所:東京都渋谷区南平台町16-17 住友不動産渋谷ガーデンタワー 1F・B1 主催:一般社団法人DroidKaigi 詳しくは公式サイトをご覧ください。 2024.droidkaigi.jp 当日のブース出展はありませんが、弊社からはエンジニア4名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! 採用情報 スタメンでは、Andoridエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers
こんにちは!TUNAG iOSアプリ開発担当のおしん ( @38Punkd )です。 スタメンは今年はシルバースポンサー枠での協賛なのでブース出展はありませんが、 モバイルチームの朝倉( @asashin227 )、プロダクトHRと私の3名で会場に現地参加してきました。 昨年の参加報告はこちら 👇 tech.stmn.co.jp 今回はブースをまわるだけでなく、セッションを聴く時間も多く確保できたので、色々なセッションを聴いて周りました。 その中でも私個人として印象に残ったセッションをピックアップしました。 Day 0 - 前夜祭 8/22 App Clipの魔法: iOSデザイン開発の新時代 by log5 App Clipを使った、アプリデザインの共有方法の紹介がありました。 App Clipとは、iOS 14から搭載された機能で、特定のタスク等を素早く行うためのミニアプリのことです。 完全版のアプリをインストールせずに使用できるので、レストランでの注文などに使われることが多い印象です。 developer.apple.com 本セッションでは、この手軽さを利用してプロトタイピングツールとしての利用を紹介されていました。 新規に実装したUIコンポーネントをApp Clipで表示することで、デザイナーは、実際にiPhone端末上で、そのUIコンポーネントに集中して、触ることができます。 画面より小さい単位のUIに対して特にフィードバックを得やすく、とても斬新なアイデアだと感じました。 fortee.jp Day 1 - 8/23 iOS/iPadOSの多様な「ViewController」の徹底解説と実装例 by haseken iOSのViewを実装する際には必ずどこかしらでお世話になる UIViewController にまつわるお話でした。 UIKitだけでなくMapKit等の他のiOS向けUIフレームワークも合わせると、なんと80種類以上のViewControllerのサブクラスが存在していて驚きました。 私はiOS開発を始めてまだ2年半でまだまだiOS開発の歴史に疎かったので、とても勉強になりました。 fortee.jp Day 2 - 8/24 Swift 6のTyped throwsとSwiftにおけるエラーハンドリングの全体像を学ぶ by koher スタメンもSwift 6への移行準備を進めていますが、Strict Concurrencyへの対応だけでなく、Swift 6から使えるようになる新しい言語機能も、積極的に取り入れていこうと考えています。 その上で、Error型に準拠した型のエラーを投げる「Typed throws」は、どのタイミングで使用すべきか気になっていました。 koherさんのセッションでその疑問が解消されただけでなく、エラーハンドリングの基本的な考え方を学ぶことができました。 早速、今後のモバイルアプリ開発に活かせられそうです! fortee.jp 最後に 今年のiOSDCはSwift 6やクロスプラットフォームの話題が例年より多く感じ、iOS開発の時代の流れを感じました。 LT大会はユニークな発表ばかりで、終始目を丸くして見ていました。 懇親会では、昨年のiOSDCでお会いした方と今年もお会いしてお互いの近況をお話することができ、楽しく過ごすことができました。 昨年とは違った形で参加した今年も、暑い夏に負けないパワーを会場から頂きました!! 運営の皆さま、本当にお疲れ様でした! (LT用のサイリウムを配られ、待てずに点灯させちゃう筆者) 参加メンバーの感想 朝倉( @asashin227 ) 今年もiOSDCに参加できて非常に嬉しく思います。 今年はSwift 6対応やクロスプラットフォームの発表が目につき、直近の弊社の開発状況と似た課題を抱えた方が多い印象を受けました。 普段の開発の割合が多くはないため、必死に食らいつきながら発表を聞いていました。 昨年はブース運営を行なっていましたが、今年はフルで参加できたため久々のお祭り感を存分に楽しむことができました。 また来年、お会いできることを楽しみにしています。 プロダクトHR 個人的には初iOSDC参戦、かつ今回はブース運営がなかったので、純粋に参加者の目線でも楽しむことができました。 私はエンジニアではないので、非エンジニアでも楽しめそうなセッションを選びながら参加していました! 技術的な知見がないとちょっと厳しいかなと思っていたのですが、4ラインのセッションのうち少なくとも1セッションは、技術的な知見の少ない私でも楽しめるものであり、普通に楽しめました。 スポンサー側の体験としても、運営の方が丁寧なコミュニケーションを取ってくださり、事前準備は決して多くありませんでしたが、スムーズに不安なく当日を迎えることができました。 改めてありがとうございました!来年もぜひ参加したいと思います。 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers
こんにちは! この度株式会社スタメンは、2024年08月22日-24日の3日間、早稲田大学理工学部西早稲田キャンパスにて開催される「iOSDC Japan 2024」に、シルバースポンサーとして協賛します! スタメンは、企業や組織の業務DX、エンゲージメント向上を支援するクラウド型プラットフォーム「 TUNAG(ツナグ) 」の、iOS向けアプリケーションを開発・提供しています。 より多くのユーザーが快適にTUNAGをご利用いただくため、当社エンジニア組織ではモバイル先行の開発体制や開発プロセスにシフトしています。 モバイル先行の開発を推し進めることができているのはiOS関連技術コミュニティの支えがあってこそであり、 昨年に引き続き 今年も協賛させていただく運びとなりました。 本カンファレンスへの協賛を通して、これからのiOSアプリ開発者コミュニティの発展を後押ししていきます! イベントを一緒に盛り上げていきます! カンファレンス概要 開催:2024年8月22日(木)~ 8月24日(土) 場所:早稲田大学理工学部西早稲田キャンパス+ニコニコ生放送 対象:iOS関連技術およびすべてのソフトウェア技術者 主催:主催: iOSDC Japan 2024 実行委員会 詳しくは公式サイトをご覧ください。 iosdc.jp 当日のブース出展はありませんが、弊社からはモバイルチームの朝倉( @asashin227 )、青木( @38Punkd )、プロダクトHRの3名が現地参加します! オフライン参加の方は、ぜひ現地で交流しましょう! ノベルティについて 創業以来、約8年続いたコーポレートロゴを刷新し、ロゴが新しくなりました。 今回はその新ロゴを印刷したクリアファイルをノベルティとして用意しました。 ぜひ普段のお仕事や、勉強等でご活用いただけると嬉しいです! コーポレートロゴリニューアルの詳細はこちら stmn.co.jp おわりに、チャレンジトークンはこちら! iOSDCの3日間を通して、iOSエンジニアの皆様だけでなく、様々な技術領域のエンジニアの皆様とお会いできることを心待ちにしております! 現地でお会いした際はぜひお話ししましょう! チャレンジトークンは、下記です! #iOSDC_stmn 宣伝:モバイル開発のオフライン勉強会「mobile.stmn」をほぼ各月で定期開催中!次回、9/6(金)の参加者&LT登壇者募集してます! 「mobile.stmn」は、スタメン モバイルアプリエンジニアが主催するモバイルアプリ開発に関する勉強会です。 モバイルネイティブアプリやクロスプラットフォーム開発など、モバイルデバイス向けの開発や周辺の技術を中心に扱っています。 本イベントはオフライン(会場参加)のLT会を開催しています! モバイルアプリエンジニアの方やその領域に興味がある方であれば、どなたでも参加いただけます。 交流会も予定していますので、日頃のアプリ開発のあれこれなどについてお話ししましょう! https://stmn.connpass.com/event/323509/ stmn.connpass.com 採用情報 スタメンでは、iOSエンジニアに限らず、全ての領域でエンジニアを募集しています。もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers
はじめに 株式会社スタメン、プロダクト開発部モバイルアプリGでAndroidアプリを開発しているカーキ( @khaki_ngy )です。最近は、Google Gemini API ディベロッパーコンペに出すアプリを個人開発しており、賞品のデロリアンを狙っています🤩 スタメンでは名古屋のモバイルアプリ開発メンバーが主体となって mobile.stmn というモバイルアプリ開発のオフラインの勉強会を主催しています。mobile.stmnは隔月で開催しており、前回の開催でちょうど1年が経ちました。 イベントのバナー画像 今回のブログでは、mobile.stmn の1年間の振り返りと今後の展望について紹介をしていきます。 mobile.stmnとは この勉強会は、モバイルアプリ開発に携わる人・関心のある人を対象としたLT会です。社員1名と一般公募4名の計5人がLTを行い、モバイルアプリ開発に関する経験や知見を共有しています。LTのテーマはモバイルアプリ開発に関わることであれば自由です。過去にはモバイルアプリ開発の言語やフレームワーク、CI/CD、開発ツールに関することなど様々な発表がありました。 LT後は懇親会も設け、参加者同士が交流できる場を用意しています。お菓子やドリンクなどを用意し、和気藹々とした雰囲気で交流を楽しんでいます。 イベントの様子 イベントはスタメン名古屋本社のイベントスペースを利用して開催しています。 これまでのイベントについて 過去の登壇内容に関してはこちらのConnpassのイベントページをどうぞ mobile.stmn #1 mobile.stmn #2 mobile.stmn #3 mobile.stmn #4 mobile.stmn #5 mobile.stmn #6 スタメン名古屋本社のイベントスペースは無料で貸し出しも行っており、毎日何かしらのイベントが開催されています。 スタメンイベントスペースの様子 イベントスペースの利用に関心のある方は、こちらの資料もご覧ください。 株式会社スタメン イベントスペース貸し出しについて 開催の背景 mobile.stmnを開始しようとしたきっかけは 名古屋のモバイルアプリ開発を盛り上げたい と思ったからです。 まずmobile.stmnを開始した2023年には名古屋でモバイルアプリ開発に特化した勉強会がほとんど無い状態でした。またちょうどその時期はコロナによって勉強会が中止になっている勉強会も多々ある状況でした。 勉強会は社外の開発者のLTを聞いたり、交流する絶好の機会です。社外の開発者との技術交流などを通じて得た新たな知見を普段の開発に活かしたり、交流によって開発へのモチベーションも得ることができます。自分もオンライン・オフライン問わず様々な勉強会に参加して、学びを業務に活かすことはもちろん、交流という点でも楽しんでいます。 また勉強会をコミュニティとして考えると、地域に活発なコミュニティがあることも重要だと思っています。勉強会という場があることで、モチベーションが上がるだけでなく、同じ技術を学んでいる人が周りにいるんだ!ということも力になると思っています。自分個人の経験としても、学生の時に名古屋のモバイル開発の勉強会に参加をして、たくさんの勇気をもらったという経験が今のエンジニアとしてのキャリアに大きく寄与しています。 1年間開催してきた振り返り 1年間 mobile.stmn を運営してみて、いくつか気付きがあったので紹介していきます。 参加者を集めるのは大変 名古屋でモバイル開発の勉強会を始めて、一番最初に壁にぶつかったのは、参加者集めでした。 名古屋にもモバイル開発に携わるエンジニアの方はいらっしゃいますが、やはり東京や大阪といった大都市圏に比べると数は少なく、イベントの参加者集めには苦労しました。 イベントの初期段階では、他の勉強会に登壇し、自分の主催する勉強会を紹介したり、X(旧Twitter)などのSNSで積極的に情報発信したりするなど、イベントを知ってもらうための活動に力を入れていました。 これらの経験から、イベント告知の重要性を改めて実感しました。 チームでの勉強会の運営 mobile.stmnは自分個人ではなく所属しているモバイルアプリ開発チームの名古屋メンバー全員で運営をしています。 自分がやりたいです!と始めた勉強会ですが、一緒に主催しているチームのメンバー全員で取り組むことができたからこそ、ここまで継続して開催することができたと思っています。 勉強会1回をとっても当日の司会や受付、connpassページの作成、飲食物の購入など様々な準備が必要であり、1人の力で運営することは難しく、ましてや継続していくことは困難です。 きっかけ自体は自分だったものの、運営をチーム全員で取り組むことができたからこそ、ここまで継続できたと思っています。 定期的に登壇の機会を作ることができる このイベントでは、毎回社員がローテーションで登壇し、日頃の業務で得た知見や、新しい技術についての調査結果などを発表しています。発表したいテーマを持ち寄ることもあれば、チームでローテーションを組んで発表の機会を均等に与えることもあります。 この仕組みのおかげで、社員一人ひとりが定期的にプレゼンテーションの機会を得られるようになり、自然と『次は何を発表しようか』と、日々の業務や技術調査の際に発表ネタを探し始めるようになりました。 また、登壇経験が少ないメンバーにとっても、このイベントは貴重な機会となっています。主催イベントということもあり、外部のイベントに比べて参加のハードルが低く、リラックスした雰囲気の中で発表できるため、プレゼンテーションスキル向上のための良いトレーニングの場となっています。 継続は力なり mobile.stmnは、この7月に1周年を迎えました。1年という月日が経ち、リピーターの方も増え、少しずつコミュニティが形成されてきたことを実感しています。 定期的な勉強会を通して、参加者が継続的なつながりを確認する場としても機能していることに気付いてきました。 継続的に交流を行うことのできる場があると、2回目、3回目に参加した時に「前話してたあれどうなったんですか?」という会話など継続的なものとして交流を行うことができます。 技術的なスキルアップはもちろん、同じ目標を持つ仲間と交流することで、開発に対するモチベーションが向上し、日々の業務にも良い影響を与えていると感じています 今後に関して 今後も、隔月で開催しているLT形式のイベントを継続しつつ、新たな試みとしてワークショップ形式のイベントを企画検討中です。名古屋のモバイルアプリ開発コミュニティの拡大を目指し、モバイルアプリ開発に興味のある初心者の方々にも参加しやすい工夫を考えています。 mobile.stmnの次回の開催は、9月6日を予定しています。 次回イベント 下記のコンパスページで募集を開始していますので、参加をお待ちしています。 stmn.connpass.com
こんにちは。 株式会社スタメンです。 今回は RubyKaigi 2024 の参加レポート記事です。 昨年の RubyKaigi 2023 から引き続き、2024年5月15日~17日の3日間、那覇文化芸術劇場なはーとにて開催された、RubyKaigi 2024 にスポンサーとして協賛し、ブース出展をしました。 当社からは、6名のメンバーで現地参戦させていただきました! カンファレンス当日や、ブースの様子をご紹介できればと思います! 今回のスポンサーブースについて RubyKaigi 2024では、Platinumスポンサーとブース出展をさせていただきました。 これまでもテックカンファレンスでブース出展は何度か行なってきましたが、今回は、ノンデスクワーカーの方をメインターゲットとしたデスクレスSaaS『 TUNAG 』で、昨年10月にリリースした新機能『 TUNAG ベネフィット 』の機能の一部をブースコンテンツに用いました。 実際のプロダクトの一部機能を利用し、参加者のみなさまに景品の当たる抽選にトライいただきました。RubyKaigi 2024のために、オーダーしたクッピーラムネが想像以上に好評いただき嬉しかったです。 参加者の皆さまに楽しんでいただけたので、良かったです! Mazさんも遊びに来てくださいました!ありがとうございました!(VP of Engineering 松谷と写真撮影いただきました。) スタメンブースにMatzさん @yukihiro_matz が遊びに来てくれました! TUNAGの抽選機能にもチャレンジしていただきました!ありがとうございます! #rubykaigi pic.twitter.com/H4fssgfGaQ — stmn, inc. Developers (@stmn_eng) 2024年5月16日 RubyKaigi初参戦のエンジニアメンバー感想 スタメンでエンジニアをしている近藤( @sei_kondo97 )です。 今回、初めてRubyKaigiに参加しました。 どのセッションも非常に興味深く感じましたが、特に関心を持っていたのは、Ruby 3.0に導入されたRBSについてです。全てのセッションに参加できたわけではありませんが、2024年はRBSに関する以下のセッションがありました。 Let's use LLMs from Ruby 〜 Refine RBS types using LLM 〜 Community-driven RBS repository Embedding it into Ruby code Good first issues of TypeProf 弊社ではRBSの採用はしておりませんが、型検査によるバグ検出の恩恵は非常に魅力的です。 一方で、Rubyの型に関してはまだコミュニティの方向性が定まっていない部分もあり、現時点で積極的に導入するのは難しいとも感じています。またRubyKaigiを通して、「Rubyに型は必要ない」というネガティブな意見も一定数見受けられ、これも今後の型導入を検討する際の参考になりそうです。 最も面白かったセッションは、 Ruby Committers and the World でした。 例えば、Ruby 3.4からfrozen_string_literalがデフォルトで有効になる対応が開始されますが、この議論も非常に盛り上がっていました。 Immutable String literal in Ruby 3 のようなやり取りがリアルタイムで展開されるのは非常に新鮮な体験であり、私にとってRubyコミュニティをより身近に感じられる時間となりました。 3日間の大盛況だったブースをやり切った翌日はVP of Engineeringの松谷( @uuushiro )の運転のもと、アメリカンビレッジと首里城を観光しました。沖縄を堪能しつつ、社内の参加メンバーともじっくり会話することができ、有意義な時間を過ごしました。 現在は名古屋に戻り、また普段通りに日々の開発に勤しんでいます。今後ますますRubyを盛り上げていけるように、Rubyをメイン言語の1つとしている弊社の TUNAG の成長やOSSへの貢献に励んでいきたいと思います。 最後に 今回はスタメンからもRubyKaigiに初参戦のメンバーが複数いましたが、国籍問わず、 多くのRubyistの方々が来場されており、改めて世界中で長く愛されている言語なのだと肌で感じました。 また、Rubyコミュニティならではの熱量を強く感じることができ、とても良い3日間を過ごすことができました。 毎日、朝早くから、夜遅くまでRubyKaigiがずっと続いているような感覚になり、とても幸せな時間でした。 Rubyを主要言語にプロダクト開発をしている私達にとって、世界中のRuby愛のあるエンジニアの方とお話ができたのはとても貴重な機会でした。開催中、ブースや交流会等でお話しいただいた皆さんありがとうございました! 来年は、ブースのコンテンツや、より多くの国籍の方と一緒に楽しめるよう英語力も磨き上げ、さらに各国の方と交流できるように準備していきたいと思います。 それでは、来年2025年は、松山でぜひお会いしましょう!! 採用情報 スタメンでは、Rubyエンジニアに限らず全技術領域で、プロダクトを成長させていくエンジニア、デザイナー、プロダクトマネージャーの方を募集しています。 もし興味を持っていただけたら、下記からご応募ください! https://herp.careers/v1/stmn/requisition-groups/8d5d0858-2bda-4167-80f2-2401d8fb1891 herp.careers