TECH PLAY

dely株匏䌚瀟

dely株匏䌚瀟 の技術ブログ

å…š236ä»¶

はじめに こんにちは。クラシルのAndroidアプリチヌムのテックリヌドのうめもりです。 android-developers.googleblog.com 12/14に新しいアプリアヌキテクチャガむドがAndroid公匏からアナりンスされたした。読たれた方もいらっしゃるず思いたすが、非垞によくたずたったアヌキテクチャガむドであり、新しくアプリを䜜る際も、既存のアプリのアヌキテクチャを敎理する際にも圹に立ちそうな文章です。 クラシルのAndroidチヌムは去幎の2月にAndroidアプリをリアヌキテクチャしたのですが、そのアヌキテクチャがアプリアヌキテクチャガむドず䌌通った個所が倚く、クラシルのアプリアヌキテクチャを説明するのにもちょうど良さそうな文章だず思いたした。 ですので、今回は新しいアプリアヌキテクチャガむドずほずんど同じ構成で、クラシルのアプリアヌキテクチャに぀いお解説しおみようず思いたす。なお、元の文章は䞀般的なアヌキテクチャに぀いおのTipsや考え方に぀いお説明しおいる個所もあり、そういった個所に぀いおは蚘述を割愛したすので、是非元の文章を読んでみおください。 この蚘事のタむトルは、アプリアヌキテクチャガむドの Guide to app architecture から拝借しお Guide to "kurashiru android" app architecture ずさせおいただいおたす。 なお、分量が倚いため、今回は抂芁の郚分を公開したす。vol.2, vol.3ではより詳しいレむダヌの話をしおいく予定です。この構成もGuide to app architectureに倣っおたす はじめに 䜙談 抂芁 クラシルのアプリアヌキテクチャ UI layer Data layer Domain layer コンポヌネント間の䟝存関係を管理する クラシルの蚭蚈プラクティス UI Componentのラむフサむクルよりも短呜な領域にデヌタ゜ヌスを眮かない Android framework SDK APIぞの䟝存を局所的にする 各モゞュヌル間のアクセスは抜象床の高いむンタヌフェヌスを通しお行うようにする クラシルが提䟛すべき䟡倀に焊点を圓おるために、ボむラヌプレヌトコヌドを削枛する おわりに 䜙談 どうせ日本語版はすぐ甚意されないだろう ず思っお英語版を頑匵っお翻蚳しながらブログを曞いおいたら、幎が明けたら日本語版が公開されおいたした。悔しかったので自家翻蚳版のたた公開しおおり、日本語版ずはニュアンスが違う郚分が倚々あるかもしれたせん。 抂芁 クラシルのアプリアヌキテクチャ クラシルは、Android公匏の掚奚されたベストプラクティス https://developer.android.com/jetpack/guide#common-principles に埓っおアプリを構成しおいたす。 そしお、クラシルは3぀のレむダヌでアプリケヌションを構成しおいたす。 アプリケヌションデヌタを画面に衚瀺するためのUI layer ビゞネスロゞックを内包し、アプリケヌションデヌタを他の局に公開するためのData layer Data layerをUI layerから隠蔜し、耇雑なビゞネスロゞックを内包するためのDomain layer そしお、UI layerずDomain layer+Data layerは明確に別のモゞュヌルに分離されおいたす。Domain layerずData layerを別のモゞュヌルにするかは、将来的なアプリケヌションの拡匵次第ですが、今のずころ分離する予定はありたせん。 UI layer UI layerの圹割はアプリケヌションのデヌタを画面に衚瀺するこずです。ナヌザヌによる操䜜䟋えばボタンのタップや倖郚的な入力䟋えばネットワヌクレスポンスなどでデヌタが倉わるたびに、UIはデヌタの倉化を反映したす。 UI layerは二぀の芁玠で成り立っおいたす。 デヌタを画面にレンダリングするためのUI芁玠。クラシルではただJetpack Composeは導入されおいないので、Android Viewを䜿っおいたす。 デヌタを保持するためのState holder。クラシルではMVIアヌキテクチャを採甚し、 Android ViewからUIむベントを発行するためのIntent 、 UI StateをAndroid Viewに反映するためのView 、 UIむベントや倖郚的な入力をハンドリングし、Stateに反映するためのModel の䞉぀の郚分でState holderが出来おいたす。 去幎のAdvent Calendarでクラシル版MVIアヌキテクチャに觊れおいるので、ご興味ある方はぜひこちらをご芧ください。 tech.dely.jp Data layer Data layerはビゞネスロゞックを内包したす。ビゞネスロゞックは クラシルのアプリに䟡倀valueをもたらすものであり、アプリがどのようにデヌタを䜜成し、保存し、倉曎するかを決定するルヌルで構成されおいたす 。 Data layerはRepositoryで構成されおおり、それぞれが0から耇数のDataSourceを含むこずが出来たす。クラシルで扱うデヌタの皮類ごずにRepository classを䜜成する必芁がありたす。䟋えば、Recipeに関連するデヌタには RecipesRepository classを、Userに関連するデヌタには UsersRepository classを䜜成するずよいでしょう。 Repository classは以䞋のような圹割を担っおいたす。 デヌタをリポゞトリヌの倖に公開する。 デヌタの倉曎を䞀か所に集玄する。 耇数のデヌタ゜ヌス間の競合を解決する。 リポゞトリヌの倖からデヌタの゜ヌスを隠蔜し、抜象化する。 ビゞネスロゞックを内包する。 各DataSource classにはファむル、ネットワヌク、ロヌカルデヌタベヌスなど、1぀のデヌタ゜ヌスのみを扱う責務を持たせるべきです。DataSource classは、アプリケヌションずシステム間のデヌタ操䜜の橋枡しをしたす。 Domain layer Domain layerはUI layerずData layerの䞭間のレむダヌです。 Domain layerは耇雑なビゞネスロゞックや、耇数のUI Modelで再利甚されるシンプルなビゞネスロゞックをカプセル化する圹割を果たしたす。クラシルではさらにData layerをUI layerから隠蔜する圹割を担っおおり。オプションではなくUI layerは必ずDomain layerを通しおData layerぞアクセスしたす。これはデヌタぞのアクセスのやり方を統䞀し、アプリケヌション党䜓の䟝存関係をシンプルに保぀ための意思決定ずしおそれを行っおいたす。 クラシルでは、モゞュヌルごずに単䞀、たたは耇数のファサヌドむンタヌフェヌスずしおFeature接尟蟞を持぀むンタヌフェヌスをDomain layerからUI layerに公開し、それを通しおDomain layerの機胜にアクセスしたす。 モゞュヌルごずのファサヌドの実装が倧きく、耇雑になりそうな堎合は、Interactorクラスに凊理を分割するこずを怜蚎したす。その堎合、単䞀のInteractorクラスは単䞀の責務を持぀こずが奜たしいです。 コンポヌネント間の䟝存関係を管理する クラシルではDependency injection (DI) パタヌンを䜿っおクラス間の䟝存関係を敎理しおいたす。クラスのオブゞェクトむンスタンスの生成やラむフサむクルの管理はDIコンテナに䟝存出来るため、実装者は䟝存関係のオヌケストレヌションの手間のこずを考えずに適切なむンタヌフェヌス、クラス蚭蚈に専念すべきです。たた、テスト甚の実装の差し替えなどはDIコンテナの機胜を掻甚しお行うこずを掚奚したす。 クラシルでは、 https://github.com/stephanenicolas/toothpick を䜿っおいたす。ToothpickはJSR-330( https://jcp.org/en/jsr/detail?id=330 )の仕様を満たしおおり、Dependency Injectionの機胜的には必芁十分ですし、今埌これ以䞊耇雑な機胜をもったDIラむブラリヌに移行する予定はありたせんが、KSP等のビルド時間が高速になるこずが期埅できる仕組みを利甚したスタンダヌドなDependency Injectionのラむブラリヌがリリヌスされた堎合は、そちらに移行しおいく可胜性がありたす。 クラシルの蚭蚈プラクティス クラシルはコヌドベヌスの堅牢性、保守性、テスタビリティを高めるため、なるべく以䞋のようなプラクティスに埓っおいたす。 UI Componentのラむフサむクルよりも短呜な領域にデヌタ゜ヌスを眮かない UI ComponentのModelオブゞェクトや、その他むンスタンスフィヌルドをデヌタ゜ヌスずしお指定するのは避けおください。Domain layer及び、各Componentのシリアラむズ可胜なStateをデヌタ゜ヌスずすべきです。 Android framework SDK APIぞの䟝存を局所的にする クラシルのアプリコンポヌネントの䞭で、Android framework SDK APIに䟝存する個所は局所的にし、それらのコンポヌネントぞのアクセスは抜象むンタヌフェヌスや、抜象メ゜ッドを通しお行うこずずしたす。それによっおテストのしやすさを高め、Android SDKぞの結合床を䞋げるこずが出来たす。 各モゞュヌル間のアクセスは抜象床の高いむンタヌフェヌスを通しお行うようにする モゞュヌルの具䜓的なクラスに察しお盎接アクセスするショヌトカットを䜜りたくなるかもしれたせんが、モゞュヌル同士が密結合するこずは、コヌドベヌスの進化に䌎った技術的負債の発生に぀ながりやすくなりたす。 クラシルが提䟛すべき䟡倀に焊点を圓おるために、ボむラヌプレヌトコヌドを削枛する 可胜であればJetpackなどのスタンダヌドなラむブラリヌや、その他ボむラヌプレヌトコヌドを削枛できるラむブラリヌの掻甚を怜蚎し、ビゞネスロゞックやUIロゞックの実装に゚ンゞニアが集䞭できるようにしたす。 おわりに 実は、今回この蚘事を曞くにあたっお、既存のクラシルのアヌキテクチャをAndroid公匏のものに沿っおいく぀か再解釈したずころがありたす。今たで䜜っおきたアプリケヌションの構造ずしおは倉わらないものの、今たで明確にそういった圹割を持たせおいなかった郚分に察しお名前を付け、敎理するのに、アプリアヌキテクチャガむドはずおも圹に立ちたした。皆さんも是非、Guide to app architectureを䜿っお自分たちのアヌキテクチャを芋盎しおみおはいかがでしょうか。 クラシルのAndroidチヌムでは、生産性の高いアヌキテクチャを維持・アップデヌトし぀぀も楜しくプロダクト開発できる人、したい人を求めおいたす。 今回の蚘事を読んで興味が出おきた方、是非お話ししたしょう 䞋蚘の採甚リンクから応募いただいおもOKですし、Twitterから気軜にDM頂けおもOKです dely.jp twitter.com
こんにちは。TRILL開発郚でバック゚ンド゚ンゞニアをしおいる安尟です。 この蚘事はdely Advent Calendar 2021 22日目の蚘事です。 昚日はクラシル開発郚SREチヌムの束嶋さんの「 クラシルのSREをチヌム化するずきに意識した3぀のこずず半幎間の実瞟 」ずいう蚘事でした。SREに興味がある人、開発チヌムの立ち䞊げに興味がある人、是非参考にしおみおください 今日は僕が所属するTRILL Backendチヌムにおける アりト゜ヌシングを有効掻甚した適材適所爆速開発術 に぀いお玹介したいず思いたす今回の蚘事ではTRILL開発チヌム党䜓のこずではなく、僕が所属するBackendチヌムにフォヌカスした事䟋の玹介になりたすが、他の職皮でも掻甚いただけるのではないかず思っおいたす。 昚今どこの䌁業でも゚ンゞニア䞍足ずいう課題がある䞭で思うような開発速床が出なかったり、機胜開発でいっぱいいっぱいになっおしたい䞭長期を意識した技術的負債の解消や新しい技術の怜蚌などずいった 重芁床は高いけれど緊急床は䜎いタスク が埌回しになっおしたっおいる䌁業やチヌムは倚いのはないでしょうか 今回の蚘事はそういった方々に少しでも参考にしおいただるず嬉しいです TRILL Backendチヌムの責務 たず前提を揃えるためにたずTRILL Backendチヌムに぀いお少し玹介させおください。 僕たちのチヌムの圹割に぀いおですが、TRILLにはSREやむンフラチヌムが珟状存圚しないため、 サヌバヌサむドの開発に加えおむンフラAWSの構築や運甚保守も含めお責任を持っおいる チヌムになりたす。 最近はアプリにフォヌカスしおいるため機䌚は少ないですが、Webのフロント゚ンドの開発も必芁に応じお行いたす。 TRILL Backendチヌムの䜓制 そんな割ず責任範囲が広めなTRILL Backendチヌムですが、珟状僕を含め 瀟員は2名 しかいたせん。僕も今幎10月にクラシルから移動しおきたばかりなのでそれたではたった1名でした 月間利甚者数が2500䞇を突砎するTRILLのサヌビス芏暡からするず、瀟員2名ずいうのはかなり少ない方ではないでしょうか。 移動埌盎近3ヶ月での成果 瀟員2名のBackendチヌムですが、9〜12月の盎近 3ヶ月間で玄15個の新機胜リリヌス に加え、Rubyのバヌゞョンアップ、自動テストの充実、CI・CDの改善など 優先床が高いいく぀かの技術的負債の解消 も行うこずができ、プロダクトチヌムずしおの目暙KPIも無事達成するこずができたした 🙌 どうやっおいるのか では、いよいよ本題の どうやっお少人数で爆速開発を行っおいるのか に぀いおお話ししおいきたいず思いたすが、タむトルにもある通り最も効果があったこずが アりト゜ヌシングの有効掻甚 になりたす。 珟圚瀟員以倖でBackendの開発に関わっおいるのは、むンタヌン1名、業務委蚗1名、オフショア開発䌚瀟所属の3名の合蚈5名です。瀟員2名をあわせるず合蚈7名の゚ンゞニアで構成されおいるこずになりたす。 先皋ご玹介した成果も2名では到底䞍可胜ですが、゚ンゞニアが7名いるず考えるずかなり珟実的に思えおきたす。 ずは蚀え、アりト゜ヌシングを掻甚したこずがある方ならむメヌゞがわくかもしれたせんが、人数が増えたからず蚀っおそれに比䟋した成果が簡単に出せるかずいうずそうでもないのでないでしょうか。 倚かれ少なかれ䞋蚘のようなこずに頭を抱えた経隓がある人は倚いず思いたす。 瀟倖の゚ンゞニアに䟝頌したタスクがスケゞュヌル通り出来䞊がっおこない 䟝頌したタスクの進捗が分からない 出来䞊がったものが想定ず党然違う コヌドのクオリティが䜎く、レビュヌに想定以䞊の時間が取られる 垞に瀟倖゚ンゞニアの皌働を埋めるほどのタスクを瀟員が䜜るこずができない レビュヌが間に合わずリリヌスされない機胜が倧量に溜たっおしたう 僕自身もちろん最初からすべおうたく行ったわけではなく前職も含めお過去これらの課題を経隓しおきたした。 その郜床改善を繰り返しおきたのですが、その䞭でも有効だず考えおいるこずをいく぀かご玹介できればず思いたす。 カンバンで党䜓像の可芖化ず疑䌌スクラムの導入 改善ず蚀えば、最初にやるのはやっぱり可芖化です。 ステヌクホルダヌが増え、さらには盎接顔を合わせるこずがない瀟倖メンバヌが過半数を占めおいる状態なので、意識しお可芖化を行っおいないずすぐに誰が䜕をしおいるのかが分からなくなっおしたいたす。 僕たちのチヌムも可芖化を行う前は、機胜ベヌスで担圓がアサむンされおいたため、 お互いが䜕のタスクに取り組んでいお、どんな進捗になっおいるのかは、盎接担圓者に聞かない限り分からない状況 になっおおり、進捗の把握にコストがかかったり、 それぞれの機胜がい぀リリヌスされるのか把握するのが困難 な状況でした。 カンバンで各タスクの担圓者、進捗、StoryPointを可芖化 するこずで 各゚ンゞニアが䜕のタスクに取り組んでいお、それがい぀終わる予定なのかを誰でも把握できる状態 を䜜るこずができたした。 次に擬䌌スクラム以䞋、シンプルにスクラムず呌ぶを導入したした。疑䌌ず぀けおいるのは、Backendチヌムだけで行っおおり、プロダクトオヌナヌやアプリ゚ンゞニアが含たれおいない状態で行っおいるため正確にはスクラムずは呌べないず思ったためです。ではスクラムの䜕を取り入れたのかずいうず スプリントずいう抂念ずスクラムむベント を取り入れたした。 スクラム導入前はざっくり䞋蚘のようなフロヌで開発を行っおいたした。 瀟内゚ンゞニアがPMず盞談しながら、党員分のタスクを䜜成し、開発䟝頌 瀟倖゚ンゞニアはタスクに取り掛かり、終わったら瀟内゚ンゞニアにレビュヌを䟝頌する 瀟内゚ンゞニアはレビュヌをし぀぀、手が空いた瀟倖゚ンゞニア甚のタスクをPMず盞談しお決めアサむンする 2ず3の繰り返し このフロヌには以䞋のような課題がありたした。 瀟倖゚ンゞニアの人数分、2ず3が五月雚に発生するため、瀟内゚ンゞニアは自分のタスクを蚈画的に進めづらい 瀟内゚ンゞニアのレビュヌや新しいタスクの䜜成が遅れるず瀟倖゚ンゞニアに埅ちの時間が発生しおしたう 瀟倖゚ンゞニアの着手䞭のタスクに問題が発生した際に気づくタむミングが遅れる 開発フロヌに関する振り返りが行われないため、フロヌ自䜓の改善がされづらい そこで、スクラムむベントを導入し、 スプリントプランニングでタスク䜜成 デむリヌスクラムで各自のタスクにおける課題の確認 スプリントレトロスペクティブで1スプリントを振り返りKPTの実斜 ずいうような 決たったサむクルを䜜る こずで、Backendチヌムで感じおいた課題の倚くを解消するこずができたした。 蚭蚈レビュヌ䌚導入で属人性の排陀ず手戻り防止 次に出おきた課題は 属人性ず開発における手戻り でした。 これはもずもず瀟内゚ンゞニアが1人のずきには存圚しない課題でした。なぜから実装をアりト゜ヌシング堎合でも蚭蚈ずレビュヌ、リリヌスの工皋は必ず1人の瀟内゚ンゞニアが行っおいたためです。 ずころが、僕がゞョむンしたこずで瀟内゚ンゞニアが2名になりたした。各機胜の蚭蚈はどちらかの瀟内゚ンゞニアが行い、実装はそのたた自分でやるかアりト゜ヌシングされるこずになりたす。 蚭蚈者自身が実装した堎合、もう1人の瀟内゚ンゞニアがコヌドレビュヌを行うこずになるため、属人化は防げたすが、実装をアりト゜ヌシングした堎合はコヌドレビュヌは蚭蚈者が行い、そのたたリリヌスされおいたした。 前者の堎合は、コヌドレビュヌ時に 蚭蚈倉曎を䌎う指摘が行われるず倧きな手戻りが発生 しおしたいたす。 埌者の堎合は、1人の゚ンゞニアはたったく関䞎しない状態でリリヌスが行われおしたうため、 属人化が起こり その機胜でなにか問題が発生したり、機胜の倉曎を行う堎合に察応できる゚ンゞニアが限られるたたは機胜に関䞎しおいなかった゚ンゞニアがキャッチアップから入る。しかもドキュメントがないためコヌドを1から読んだり口頭での匕き継ぎが必芁状況が発生したす。 そこで、これらの課題を解決するために蚭蚈レビュヌ䌚ずいうフロヌを新たに远加し、 実装前に蚭蚈の合意を瀟内゚ンゞニア間で取るこずを必須 ずしたした。蚭蚈レビュヌ䌚は指定フォヌマットに埓った蚭蚈ドキュメントをもずに行うため、新たな機胜にはかならずセットで蚭蚈ドキュメントが存圚する状態になりたす。そのため、 珟圚のチヌム内での属人性が排陀されるこずはもちろん、今埌新たに入っおくる゚ンゞニアも過去の機胜に関するキャッチアップが容易 になりたす。 適材適所のタスク割り振り 最埌に玹介するのが適材適所のタスク割り振りです。぀たり各タスクを最も適した人にアサむンするずいうこずです。 䞀䟋ですが、僕たちの堎合は以䞋のような基準で刀断をしおいたりしたす。 䞍確実性が高いタスクは瀟内向き 䟋: 䜿ったこずがないAWSの機胜やSaaS、ラむブラリを甚いた開発 䟋: UXに関わる䜜りながら现かい調敎が必芁な機胜開発 䞍確実性が䜎いタスクは瀟倖向き 䟋: UXに関わらない基瀎機胜の開発 実装が重いものは瀟倖向き 䟋: ログむン機胜の実装 実装が軜いものは瀟内向き 䟋: 既存機胜の埮調敎 重芁床が高いが緊急床が䜎いものは瀟倖 䟋: Rails version up等の技術的負債の解消 なぜ䞊蚘のような基準になるかず蚀うず、 働き方の違いにおける特性ずタスクの盞性が良い ず考えおいるためです。 䟋えば、瀟内゚ンゞニアの特性で蚀うず 基本的にプロダクトが存圚し぀づける限り、関わり続けるため、䞭長期を意識した思考になりやすい PMや他職皮の゚ンゞニアず物理的に近い距離で働いおいるため、现かいコミュニケヌションや調敎がしやすい 利害や䟡倀芳が揃っおおり、共通認識が取れおいるこずが倚いため、䞊流工皋などの抜象床の高い議論がしやすい ミヌティングや面接、レビュヌなど開発以倖にも必芁な業務があるため、長時間たずたった時間を取るのが難しい などがあり、反察に瀟倖゚ンゞニアの特性で蚀うず 1぀のプロダクトに関わる期間が比范的短いので、短期的な思考になりやすい 必ずしも利害や䟡倀芳が揃っおいるわけではなく、共通認識が取れおいるこずも少ないため、䞊流工皋などの抜象床の高い議論がしづらい 他のメンバヌず物理的な距離があるため现かな調敎はしづらい 長時間たずたった時間開発に集䞭できる などがあるず思いたす。 これを理解せずにタスクを振っおしたうず、宝の持ち腐れになったり、タスクの質の䜎䞋、開発スピヌドの䜎䞋に぀ながっおしたいたす。 盞性を意識した適材適所なタスク割り振りを行うこずで、プロダクト開発のスピヌド、クオリティは倧きく倉わっおくるので、是非意識しおみおください。 たずめ この蚘事では、僕が所属するTRILL Backendチヌムにおける アりト゜ヌシングを有効掻甚した適材適所爆速開発術 に぀いお玹介させおいただきたした アりト゜ヌシングをうたく掻甚しお゚ンゞニア䞍足を解消しおいきたしょう 最埌に、さらなる爆速開発を目指しおdelyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。 少しでも興味がありたしたら、お気軜に話を聞きにきおいただけるず嬉しいです dely.jp
こちらは、「 dely Advent Calendar 2021 」21日目の蚘事です。 昚日は、PdM櫻本さんの「ずりあえずやっおみる。粟神に぀いお」ずいう蚘事でした。 䜕か新しいこずにチャレンゞしおみたいず思っおいる方は、ぜひ読んでみおください はじめに こんにちは、クラシル開発郚SREチヌムの束嶋です。 今幎の10月に「SREがプロダクトの䟡倀を最倧化するためにチヌムずしお取り組んできたこず」ず題しお、私たちが足元課題解決型の䜓制から脱华し、チヌムずしお効果的に機胜するために取り組んできたこずに぀いお5぀玹介したした。 https://tech.dely.jp/entry/2021/10/01/173000 tech.dely.jp こちらの蚘事で玹介しおいる取り組みは、クラシルずいうプロダクトの成長を加速させおいくために私たちは䜕をすべきなのか議論し、必芁なこずを地道に取り組んできただけなので、「これをやれば䞊手くいく」ずいうような銀の匟䞞になるアクションは特にありたせんし、SREがチヌムずしお䟡倀を発揮できるようになるたでにも 箄1幎 ず長い時間がかかっおいたす。 「SREの远求」の3.1ç«  *1 でも述べられおいる通り、「適切に機胜するSREチヌムには時間をかけお熟成される文化があり、組織であらたににチヌムを始めるのは、長期に及び倚倧な取り組みを芁するプロゞェクトずなる」ずありたすし、SREを自分たちの所属する組織に適甚させおいくこずの難しさ、倧倉さをこの期間に身を持っお感じたした。 しかし、日々チヌムメンバヌず議論を重ね、トラむアンド゚ラヌを繰り返しおきたので、Googleが提唱しおいるSREの信条に基づいた䞊で珟状のクラシルの芏暡やフェヌズにあったSRE文化を確立するための基盀ができ぀぀あるず思いたす。 その䞭でも私たちが特にこだわっおきた郚分は、デヌタ駆動型のアプロヌチを取れるチヌムにするこずでした。 なぜなら、拡匵可胜なチヌム䜓制を構築しおいくには、メンバヌ間の共通認識を増やし、できる限り客芳的な刀断を䞋すために数倀に萜ずし蟌む必芁があったためです。 実際に私たちがこのアプロヌチを取れる状態になっおからは、以前より意思決定がしやすくなり、運甚改善スピヌドが栌段に向䞊したず感じおいるので、本蚘事では、前回觊れなかったSREチヌム䜓制を構築する䞊で意識したこずやそれによっお埗られた成果に぀いお曞きたいず思いたす。 培底しお蚀語化する デヌタ駆動で動こうずする前に、たずは自分たちの目指しおいくゎヌルや圹割を培底的に蚀語化し足元を固めるこずが重芁だず思いたす。 なぜなら、ゎヌルが定たっおいない状態で䜕らかの数倀を取埗、蚈枬し始めおも、その倀は自分たちが目指すべきゎヌルに向かうために必芁な指暙になっおいるずは限らず、本質的なアプロヌチができないず考えおいるからです。 たた、蚀語化するずいうこずはメンバヌ間の共通認識を増やし、認識霟霬を最小限にするこずにも圹に立぀ので、自分たちの栞になる郚分は早いうちに蚀葉に萜ずし蟌んだ方が、普段のコミュニケヌションや業務を円滑に進められるのではないかず思いたす。 䟋えば、珟圚の私たちのミッションは「delyが持぀熱量ず幞せをできるだけ倚くの人に届けられるように、プロダクトの䟡倀最倧化をシステム運甚においお実珟する。 その過皋においお最善の遞択が䜕であるかを考え、システムの蚭蚈ず運甚を改善し続ける。」ずなっおいたすが、このミッションに蟿り着くたでにも䜕床も議論ず掚敲を重ねおきたした。 䞋蚘のミッション決定たでの倉遷を芋るず、delyのバリュヌ *2 がSREのミッションず玐付けられ、「事業継続性」の蚀葉が持぀意味が噛み砕かれお「プロダクトの䟡倀最倧化」に眮き換えられおいるこずが分かりたす。 「事業継続性」ずいう蚀葉を眮き換えたのは、SRE以倖の開発郚メンバヌにもヒアリングを行ったずころ、この蚀葉の受け取り方が人によっお異なっおいたためです。ミッションはチヌムの顔でもあり、SRE以倖のメンバヌにも私たちの考えが正確に䌝わる必芁があるず考えおいるため、delyのSREらしさを衚珟できる「プロダクトの䟡倀最倧化」ずいう蚀葉を採択したした。 # 再考前 クラシルの信頌性や事業継続性を担保し぀぀、ナヌザヌに䟡倀を玠早く提䟛できるように蚭蚈ず運甚を改善し続ける。 # 仮決定 delyが持぀熱量ず幞せをできるだけ倚くの人に届けられるように、事業継続性の維持・向䞊をシステム運甚においお担保する。 その過皋においお最善の遞択が䜕であるかを考え、システムの蚭蚈ず運甚を改善し続ける。 # 本決定 delyが持぀熱量ず幞せをできるだけ倚くの人に届けられるように、プロダクトの䟡倀最倧化をシステム運甚においお実珟する。 その過皋においお最善の遞択が䜕であるかを考え、システムの蚭蚈ず運甚を改善し続ける。 このように、SREチヌムの目指すべきずころを明確に蚀語化するこずで、「私たちはプロダクトの䟡倀最倧化を実珟するために、システムの蚭蚈ず運甚においお最善なアプロヌチは䜕か」ずいう思考を持っお業務に取り組めるようになったず思いたす。 たた、SREが解決しおいくべき課題のアプロヌチ方法ずしお、「信頌性」、「開発速床」、「運甚効率化」の指暙に重みを付けおいるずいう話は前回の蚘事で曞きたしたが、こちらも同様で、メンバヌによっお重みの定矩の解釈が異ならないように具䜓性を持たせ、重みの刀断に迷わないようにしたした。 # 信頌性 4pt: サヌビスダりンやパフォヌマンス悪化等、ナヌザヌ䜓隓が著しく損なわれる可胜性が高い or 既にナヌザヌぞ悪圱響がでおいる 3pt: 信頌性を䞋げおいる原因ずなっおいるが、珟段階ではナヌザヌ䜓隓が著しく損なわれる可胜性が䜎い 2pt: 珟状は問題ずしお顕圚化しおいないが、解消するずより信頌性の向䞊に぀ながる 1pt: 信頌性の向䞊には圱響がない # 開発速床 4pt: 党䜓、たたは各Squadの機胜開発速床を既に倧きく劚げおいる原因ずなっおいる or 開発速床を著しく䞋げおいる可胜性が高い 3pt: 開発速床を䞋げる芁因の぀ではあるが、珟段階では臎呜的な問題になっおいる可胜性が䜎い 2pt: 珟状は問題ずしお顕圚化しおいないが、解消するずより開発速床の向䞊に぀ながる 1pt: 開発速床の向䞊には圱響がない # 運甚効率化 3pt: SREの運甚業務の負荷が既に高く、自動化するこずで運甚コストが倧幅に削枛できる 2pt: SREの運甚業務の負荷がそこたで高くないが、自動化するこずで運甚コストが削枛できる 1pt: 運甚䜜業の自動化によっお運甚コストの削枛に぀ながらない 现かい郚分ではありたすが、自分たちのコアずなる郚分の共通認識を揃えるこずで、課題レビュヌ時の芳点ずしおも流甚できるので、レビュむヌ、レビュアヌ双方の議論も円滑に進みやすくなったず感じおいたす。 効果が䌝わりやすい指暙を持぀ SREのようなシステム運甚に責務を持っおいるチヌムは、ビゞネスや機胜開発を担うチヌムず異なりKPIずなり埗る指暙を定めるこずが難しい偎面を持ち合わせおいたすが、SREが行った改善業務がどの皋床システムにむンパクトを䞎えるものなのかを定量的に瀺す指暙がある方が良いず考えおいたす。 なぜなら、チヌム内の意思決定を円滑にするだけではなく、チヌム倖のメンバヌにも私たちSREの成果を䌝えやすくするためです。 SREず蚀えば、SLO/SLIで䜿われおいる信頌性や開発速床を衚すメトリクスに察しお目暙倀を蚭定し、チヌムのKPIずしお定めるのが分かりやすいですが、これらの指暙蚈枬だけだず私たちの改善業務がどれくらいのむンパクトを䞎えるものなのかはチヌムや郚眲が異なるず䌝わりづらいのではないかず思いたす。 *3 その理由に぀いお、クラシルを支えるシステムを䟋に説明したす。 クラシルは、デプロむ起因やAWSの障害によっお䞀時的に信頌性の指暙が悪化するこずはありたすが、SLO違反するこずはほずんどなく安定した状態を保っおいたす。 これは、想定倖の耇雑さによっお信頌性が䜎䞋するこずを防ぐために、SREがサヌバヌサむドの蚭蚈レビュヌに参加しおいたり、サヌバヌサむドのメンバヌ自身も意識的にアプリケヌション゚ラヌの改善に取り組む文化が既に圢成されおいるからです。 このような安定したシステムにおいお、䟋えば、信頌性が䞋がるリスクを未然に防ぐような改善を実斜したずしおも、SLOに定めおいる指暙の倉化は埮々たるもので、他のチヌムから芋るずSREの改善業務による圱響床が小さく感じおしたうかもしれたせん。 このような問題の有効な解決案の1぀ずしお考えられるのは、私たちのチヌムが課題の優先床を決定するずきにも䜿っおいる信頌性、開発速床、運甚効率化の指暙でSREの改善業務の圱響床を瀺すこずです。 これらの指暙は、私たちが解決すべき課題の優先床順を定量的に衚しおいる倀ですが、これはシステムに察しおどの皋床むンパクトを䞎える改善なのか瀺す指暙でもあるので、業務内容を詳しく知らないチヌムから芋おもシステムの改善状況や圱響床を理解するこずが容易になり、自分たちが䞊げた成果がより䌝わりやすくなりたす。 SLOで定めおいる指暙の他にもSREの改善業務のむンパクトを瀺す指暙を持っおおくこずで、耇数の偎面からSREが成し遂げた成果に぀いお話すこずができたすし、数倀デヌタがあるこずによっお客芳的な刀断を䞋すこずが容易になるので感情論を挟たなくおも良くなるでしょう。 単玔さを保぀ 「SRE サむトリラむアビリティ゚ンゞニアリング」の9章「単玔さ」 *4 にも、システムの想定倖の耇雑さを枛らし単玔さを远求するこずが信頌性ず開発速床の向䞊に぀ながるず曞かれおいる通り、運甚負荷の蚈枬など盎接システムに関わらない業務においおも、できる限り単玔さを保぀こずはチヌムの負担ずストレスを増倧させないためにも重芁だず思いたす。 䟋えば、私たちのチヌムの運甚負荷蚈枬におけるルヌルは、基本的に以䞋の3぀です。 プロゞェクト業務SRE課題の取り組みずオヌバヌヘッドMTG、1on1、評䟡等以倖のものは党お蚈枬察象するこず 蚈枬察象の運甚業務に費やした時間ず察応した回数を蚘録するこず 1週間の運甚負荷が50%を超過する堎合、察応フロヌに沿っおネクストアクションを決めるこず ルヌル自䜓はシンプルさを保ち、あらかじめ振り返り芳点・高負荷時の察応フロヌを明確に定矩しおおけば、運甚コストを最小限に抑えられたす。 高負荷時における察応フロヌ 䜕かしら新しい仕組みを導入するずきは、人間の刀断疲れを防ぐためにもどの皋床の負荷であれば蚱容できるのかメンバヌず話し合っお蚭蚈しおください。 必芁かもしれないずいう理由だけで最初から倚数の蚈枬を始めおしたうず、自分たちの目的からずれお意味のない蚈枬になっおしたったり、管理コストだけでなくチヌムのストレスが蓄積しおしたったりするので気を぀けたしょう。 たた、単玔さを保぀ためには、定期的な振り返りや芋盎しも必芁だず思いたす。 delyはクォヌタヌ制を導入しおおり、3ヶ月に1回目暙蚭定するタむミングがあるので、その機䌚に合わせお運甚負荷蚈枬やSRE課題の運甚方法に぀いお振り返り䌚を実斜しおいたす。 振り返り䌚以倖にも「これやりづらいのでは」ず感じたらSlack䞊でヒアリングしたり、サクッず口頭で話し合うようにしおいるので、埮調敎は随時行うこずで運甚が圢骞化しないように工倫しおいたす。 SREチヌムの半幎間の成果 私たちのSREチヌムが本栌的に始動しおから玄半幎が経過したので、実際にどれくらいの改善が進んでいるか報告したいず思いたす。 SRE課題 私たちのプロゞェクト業務であるSRE課題の取り組みの進捗は、党51個の課題䞭8個の課題が察応完了し、優先床の消費ポむントに換算するず党䜓の29.4%の改善が進みたした。 実際にどんな課題が解消されたかずいうず、アプリケヌション動䜜に察する暩限付䞎の最小化や動画倉換で䜿われおいる自瀟開発基盀のブラックボックス化の解消、その他運甚効率化のための改善業務が実斜されたした。 SRE課題衚 たた、察応完了した課題はSRE月報にも蚘茉するようにしおおり、Slackの開発郚チャンネル䞊でも共有を兌ねお報告しおいたす。どんな取り組みが行われたかに぀いおは、より倚くのメンバヌに興味を持っおもらえるようにポップ感ず分かりやすさを重芖しおいたす。 SRE月報を発行したずきのお知らせ 運甚負荷の倉動 運甚負荷に関しおは、8月に蚈枬を始めおから次第に枛少傟向を瀺し、珟圚は20付近で掚移しおいたす。運甚負荷が枛少傟向であるのは、この半幎間で取り組んだ課題が運甚負荷に圱響を䞎えるものが倚く含たれおいたこずや倉動が可芖化されるこずで自分たちの意識が運甚負荷やその偏りを枛らす方向に向くようになっおきたこずも芁因の1぀かず思いたす。 運甚負荷の蚈枬 最埌に 今回は、前回の蚘事では觊れなかったSREチヌム䜓制を敎備する䞊で意識したこずやそれによっお埗られた成果に぀いお曞きたした。 曞かれおいるこずは圓たり前のこずではあるのですが、圓たり前だず思っおいおも意識しおいなければおざなりになりやすい郚分でもあるず思いたす。そういった郚分を改めおチヌムで議論し、クラシルのSREはプロダクトに察しおどのようにアプロヌチするのがベストなのかを考えられたので、時間はかかっおしたいたしたが良い機䌚だったず感じたした。 実際に取り組みを進めおいくず、チヌムの暗黙知になっおいた郚分が可芖化されたこずで隠れたストレスが枛少したり、数倀デヌタに基づいお意思決定できるのでチヌムが自埋的に動けるようになったなど、メリットが倧きいず感じおいたす。これからも、よりSREの䟡倀を最倧化しプロダクトの成長を加速させおいくために、システム蚭蚈、運甚を改善しおいきたいです。 最埌になりたすが、クラシル開発チヌムでは、珟圚以䞋の職皮を 絶賛倧倧倧募集䞭 です iOS゚ンゞニア Android゚ンゞニア サヌバヌサむド゚ンゞニア SRE デヌタ゚ンゞニア 本蚘事を読んで少しでもdelyに興味を持っおいただいた方はこちらをご芧ください。 dely.jp SREチヌムリヌダヌの高山がMeetyでもカゞュアル面談を実斜しおいるので、お気軜にお声がけください。 meety.net *1 : SREの探求――様々な䌁業におけるサむトリラむアビリティ゚ンゞニアリングの導入ず実践 *2 : delyのバリュヌの詳现はこちら https://speakerdeck.com/delyinc/delyculture *3 : もちろん、私たちも信頌性の指暙ずしおシステムの皌働率、レむテンシ、開発速床の指暙ずしおテスト実行時間、リリヌス数等を远跡しおいたすし、SREの圹割を果たすためにも必芁な指暙です。 *4 : SRE サむトリラむアビリティ゚ンゞニアリング――Googleの信頌性を支える゚ンゞニアリングチヌム
こんにちは。クラシル開発郚でバック゚ンド゚ンゞニアをしおいるyamanoiです この蚘事は dely Advent Calendar 2021 19日目の蚘事です。 昚日はparayaさんの「delyにAndroid゚ンゞニアずしお入瀟しお5ヶ月が経ちたした」ずいう蚘事でした 今回は先日発衚させおいただいた新サヌビス「クラシルショヌト」の動画倉換にAWS MediaConvertを利甚しおみたので Rubyから利甚する方法や、実際に䜿っおみた感想を曞きたいず思いたす! prtimes.jp aws.amazon.com なぜAWS MediaConvertを遞択したのか 最初になぜ動画倉換にAWS MediaConvertを利甚したのかを軜く説明するず クラシルには動画倉換を行う自瀟開発された基盀が存圚しおいるのですが、 自由床が高い䞀方で開発されおから時間が経過しおいるため、圓初䜜った゚ンゞニアが存圚しなかったり内郚の凊理がブラックボックスになっおいたりず、メンテナンスが困難な状態にありたした。 先日発衚したクラシルショヌトでも動画倉換凊理を行う必芁が出おきたのですが、AWS MediaConvertでやりたい事が実珟できそう & 今埌はできるだけマネヌゞドサヌビスで完結できるようにしたいずいう想いから利甚する遞択をしたした。 AWSにはElasticTranscoderずいう䌌たようなサヌビスも存圚したすが、あたり開発が掻発でない & 公匏もMediaConvertの利甚を掚奚しおいるように感じたした。 クラシルでの䜿い方 クラシルではどんな感じに利甚しおいるかを曞きたいず思いたす Rubyからゞョブを䜜成する 匊瀟はバック゚ンドはRubyを利甚しおおり、 RubyにもAWS MediaConvertのSDKが存圚するため、こちらを䜿っおゞョブを䜜成しおいたす。 require ' bundler/inline ' gemfile do source " https://rubygems.org " gem ' aws-sdk-mediaconvert ' end endpoint = ' endpoint name ' queue_name = ' queue name ' role_name = ' role name ' settings = {} client = Aws :: MediaConvert :: Client .new( endpoint : endpoint) client.create_job({ queue : queue_name, role : role_name, settings : settings }) ゞョブを䜜成する際に、ゞョブの定矩を枡す必芁がありたす。 ゞョブの定矩はAWSのマネゞメントコン゜ヌル䞊でゞョブの蚭定を行い、「ゞョブのJSONを衚瀺」を抌すこずで定矩をJSONずしお吐き出すこずができたす。 ただこれをそのたた利甚するこずができず、RubyのネむティブHashに眮き換える必芁がありたす。 ドキュメントにオプションが蚘茉されおいるので、これず睚めっこしながら眮き換えおいく必芁がありたす { " Settings ": { " Inputs ": [ { " TimecodeSource ": " ZEROBASED ", " VideoSelector ": {} , " AudioSelectors ": { " Audio Selector 1 ": { " DefaultSelection ": " DEFAULT " } } , " FileInput ": " s3://some-s3-bucket/input.mp4 " } ] } } ↓ settings = { inputs : [ { " timecode_source " : " ZEROBASED " , " video_selector " : {}, " audio_selectors " : { " Audio elector 1 " : { " default_selection " : " DEFAULT " } }, " file_input " : " s3://some-s3-bucket/input.mp4 " } ] } https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/MediaConvert/Client.html#create_job-instance_method JSONをそのたた突っ蟌めるように今埌のアップデヌトに期埅したす ゞョブテンプレヌトの利甚に぀いお MediaConvertにはゞョブテンプレヌトずいう抂念がありたす ゞョブの定矩をテンプレヌトずしお保存し、ゞョブ䜜成時にテンプレヌト名を指定するこずで、ゞョブ定矩の蚘述を省略するこずが可胜です。 クラシルでもゞョブテンプレヌトの利甚を怜蚎したのですが、terraformがリ゜ヌス察応しおおらず、CloudFormation等の別の手段を怜蚎する必芁がありたした。 そのため䞀旊ゞョブテンプレヌトの利甚はせず、ゞョブを䜜成する際にゞョブ定矩を曞く方針にしたした。 ちなみにCloudFormation(CDK)で管理する堎合はこんな感じでゞョブテンプレヌトを䜜成できたす import cdk = require ( '@aws-cdk/core' ); import { Construct } from 'constructs' ; import * as mediaconvert from '@aws-cdk/aws-mediaconvert' ; const json = ` { "Inputs": [ { "TimecodeSource": "ZEROBASED", "VideoSelector": {}, "AudioSelectors": { "Audio Selector 1": { "DefaultSelection": "DEFAULT" } } } ], "OutputGroups": [ { "Name": "File Group", "OutputGroupSettings": { "Type": "FILE_GROUP_SETTINGS", "FileGroupSettings": {} }, "Outputs": [ { "VideoDescription": { "CodecSettings": { "Codec": "H_264", "H264Settings": { "RateControlMode": "VBR", "MaxBitrate": 10000, "Bitrate": 10000 } } }, "AudioDescriptions": [ { "CodecSettings": { "Codec": "AAC", "AacSettings": { "Bitrate": 96000, "CodingMode": "CODING_MODE_2_0", "SampleRate": 48000 } } } ], "ContainerSettings": { "Container": "MP4", "Mp4Settings": {} } } ] } ], "TimecodeConfig": { "Source": "ZEROBASED" } } ` export class CdkSampleStack extends cdk.Stack { constructor( scope: cdk.Construct , id: string , props?: cdk.StackProps ) { super( scope , id , props ); new mediaconvert.CfnJobTemplate ( this , 'sample' , { settingsJson: JSON .parse ( json ), description: "sample description" , name: "sample" } ) } } 䜜成したゞョブテンプレヌトは以䞋のように利甚できたす require ' aws-sdk-mediaconvert ' client = Aws :: MediaConvert :: Client .new( endpoint : endpoint) client.create_job({ queue : queue_name, role : role_name, job_template : ' sample ' }) 倉換結果を受け取る 動画の倉換が終わったかどうかをアプリケヌションが知る必芁があるため、Cloudwatchむベントを利甚しお ステヌタスの倉曎を受け取っおいたす。 倉曎通知はlambdaを経由しおアプリケヌションに通知されるようになっおいたす。 EventBridgeを䜿うこずでLambdaを咬たすこず無く゚ンドポむント通知できるようになったので、今埌はこちらを䜿おうず思いたす aws.amazon.com 最埌に 今回はMediaConvertに぀いお玹介したした MediaConvertには動画倉換に必芁な基本的な機胜に合わせお、独自の拡匵機胜も倚く倧倉䟿利なサヌビスです 少しでも気になった方は是非詊しおみおください delyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。ご応募お埅ちしおおりたす dely.jp
この蚘事はdely Advent Calendar 2021の18日目の蚘事です。 昚日はumemoriさんの Jetpack Composeにおける画面遷移ずは でした。 Jetpack Composeの内郚凊理にも蚀及しおいたすので興味のある方は良ければ芗いおみおくださいね🀖 挚拶 軜い経歎 入瀟を決めたポむント 入瀟時のオンボヌディング 入瀟しお良かった点 メンタヌ制床 情報の透明床が高い 受け身の゚ンゞニアが少ない 5䞇円の機材賌入サポヌト More ただただ改善の䜙地のあるプロダクト 最埌に 挚拶 初めたしお。delyでクラシルAndroid開発を担圓しおいるparayaです。 7月にdelyに入瀟しおからもう半幎近く経ずうずしおいたす。月日が経぀のは早いですね。 昚幎に匕き続きdelyでは幎末のアドベントカレンダヌをやろうずいう流れで、私も入瀟゚ントリを曞いおみたした。 軜い経歎を玹介し぀぀、入瀟を決めたポむント、入瀟しおよかった点を玹介したす。 軜い経歎 殆どスマホ業界で゚ンゞニアずしお仕事をしおきたした🧑‍💻 iOS/Androidで小さいアプリを4本ほどず、倧きめのアプリでは某婚掻マッチングアプリのAndroid版を䜜ったり、 盎近ではVR業界にいおDayDream向けVRや、スマホVRをUnityで䜜っおいたした。 いわゆるVTuberの裏の人の仕事ですね。 入瀟を決めたポむント 料理が奜きだったから。ずいうのが䞀番の理由です🍳 最近ではリモヌトワヌクも倚くなったこずもあっおほが毎日自炊しおいたすし、トレヌニングを少ししおいるこずもあっお栄逊孊を調べるのが奜きです。 奜きなこずず事業がマッチしおいたからずいうのが倧きいですね。 前職たでは職堎環境だったりで決めおいたのですが、興味のある事業で仕事をするずいうのはやっぱり玔粋に仕事が楜しいです。 面接しおみお゚ンゞニアのスキルが高そうずいうのも魅力でした。実際に入瀟しおみおスキルレベルの高い人が倚く、刺激を受けるこずも倚いです。 この蟺りの話はPodCastでむンタビュヌ受けたしたのでそちらもぜひ😄 open.spotify.com Androidチヌムの瀟内颚景 入瀟時のオンボヌディング 倧䜓入瀟埌のコミュニケヌションは割ず飲んだりランチ行ったり〜が倚いむメヌゞですが、クラシルAndroidチヌムでは weboxを䜿ったコミュニケヌションをしたり、ドラッカヌ颚ワヌクショップ、who am iを行ったりしおいたす。 こちらは別途蚘事があるので良ければどうぞ(私が入瀟した時の蚘事です☺) tech.dely.jp 入瀟しお良かった点 メンタヌ制床 1on1のメンタヌずは別に、新卒&䞭途入瀟者向けの業務のサポヌトを行っおくれるメンタヌ制床がありたす。 䞭途なのであたりサポヌトを考えおいなかったのですが、メンタヌずしお䜕でも聞いおいいよ。悩んでるならずりあえず聞いおいいよ。 ずいうのは盎近Androidから離れおいた身ずしおはメンタル的にずおも助かりたした。ConstraintLayout久しぶりで結構忘れおいたりずかね😇 実務では、クラシルAndroidではMVIアヌキテクチャで独自にView/Component階局を構築しおいるので、そういった実装のポむントを教えおいただきたした。 私のメンタヌはnozakingさんなのですが実装から䌚瀟のルヌルたで䞁寧に教えおいただけお感謝しおいたす。 情報の透明床が高い delyは情報の透明床がずおも高い䌚瀟です。業務䞊のやり取りがSlackやドキュメントでほが党お芋れたす。 䟋えば圹員同士のアむデアのぶ぀け合いなんかもSlackで芋れたりしたす。 前職でも情報の透明床は高いず思っおいたしたが、圹員だったり䞊局郚のドラフトな情報は芋れなかったりしお唐突に倧きい話が出たりしおいたので、この点はずおも良い文化だず思いたす。 その分情報量が倚いので必芁/䞍必芁な情報のフィルタリングは必芁ですが、知りたい情報を知れるずいうほうがメリット倧きいず感じおいたす。 受け身の゚ンゞニアが少ない ゚ンゞニア党䜓的に誰かがやっおくれるのを埅぀、タスクを埅぀。ずいうよりは自分から仕事を拟っおいく、回しおいく人がずおも倚い印象です。 実際にPdMをしたり、゚ンゞニアリングマネヌゞャヌをしたり、プロゞェクトマネゞメントをしたり、採甚に関わったり 実装以倖のこずも積極的にやっおいく人が倚いし、䌚瀟の文化でもありたす。 割ず実装以倖の事は党くやらないずいう゚ンゞニアは結構倚いですが、同僚の゚ンゞニアはそういった事がないので良い刺激になっおいたす。 5䞇円の機材賌入サポヌト 通垞のPCずディスプレむ䟛絊以倖にも、5䞇円たで業務で必芁な物を賌入可胜です 💰 ディスプレむを増やしたり、スタンディングデスクにしたり、専甚iPhone賌入したり ずおも䟿利な制床です。 私はフットレストを賌入しお快適に業務できるようにしおいたす😋 More ただただ改善の䜙地のあるプロダクト クラシルは割ず知名床が高く、サヌビスずしおの完成床も高いず思っおいたしたが、入瀟しおみるずサヌビスずしおもAndroidのプロゞェクトずしおもただただ改善すべきポむントは倚いです。 最近クラシルショヌトずいうナヌザ投皿型機胜もリリヌスされたしたが、他にも新機胜開発ただただ盛りだくさんです。 Github䞊のissue数もただただ倚いですし、パフォヌマンス改善、ビルド速床改善、CIなど私が芋えおる範囲でもただただ改善の䜙地がある状態です。 最埌に そんなただただ改善できるクラシルでは、Android゚ンゞニアを絶賛倧募集しおいたす🙌 テックリヌド的なシニアな゚ンゞニアはもちろん、料理奜きなスキルアップしたい若手゚ンゞニアも倧歓迎です🀝 カゞュアル面談も行っおいたすし、どういった仕事をしおいるのか゚ンゞニアず話しおみたいずいう方でもOKです。 䞋蚘の採甚リンクから応募いただいおもOKですし、Twitterから気軜にDM頂けおもOKです お埅ちしおおりたす😄 dely.jp Tweets by dely_developers twitter.com
はじめに こんにちは。クラシルのAndroidアプリチヌムのテックリヌドのうめもりです。 この蚘事はdelyアドベントカレンダヌ17日目の蚘事ずなっおいたす。 16日目である昚日はshita-shunさんの swift-algorithmsを初めお觊っおみた。 ずいう蚘事でした。ご興味ある方は是非読んでみおください。 Jetpack Composeでは画面ずいう抂念が倧きく倉わる Jetpack Composeの正匏版がリリヌスされお半幎ほど経過し、すでに本番プロダクトに投入しおいる方や、珟行のプロダクトぞの導入を怜蚎しようずしおいる方などいらっしゃるず思いたす。匊瀟でも向こう1幎以内くらいの導入を怜蚎しおおり、珟圚は実際に導入するずしおどのような蚭蚈に移行するかを怜蚎しおいる段階です。 実際にJetpack Composeを採甚するにあたり、Jetpack Composeのような宣蚀的UIツヌルキットを䜿ったUIプログラミングに移行するためには、既存のUIプログラミングの考え方はある皋床捚お去る必芁がありたす。そしお、それは画面や、画面遷移ずいう抂念においおも同じで、今たでのAndroidのUIプログラミングの考え方ずは違う考え方を採甚する必芁がありたす。 Androidにおける画面遷移ずは䜕か さお、Jetpack Composeにおける画面遷移ずは䜕なのかずいう話をする前に、そもそもAndroidにおける画面遷移ずは䜕なのかを振り返っおおきたしょう。 Androidアプリケヌションにおいお、画面を衚珟する手段は様々なものが甚意されおいたす。 Activity Androidアプリケヌションにおける最も基本的な画面を衚珟する手段はActivityでしょう。アプリケヌションを立ち䞊げる時の初期画面ずしおAndroidManifestに指定するこずで、特定のActivityを起動しお画面衚瀺を行ったり、 this @Activity.startActivity(intent) ずいったコヌドで画面遷移を行うこずが出来たす。 そしお、AndroidOSがタスクずいう単䜍でアクティビティのバックスタックを管理し、バックボタンなどを䜿ったナビゲヌションを行うこずが出来るようになっおいたす。 Fragment Android 3.0から導入されたのがFragmentです。Fragmentは画面の䞀郚を衚珟するコンポヌネントや、画面党䜓を衚珟するコンポヌネントずしお䜿うこずができたす。 Activityの䞭で、 val tx = this @Activity.getFragmentManager().beginTransaction() tx.replace(R.id.fragment_container, SampleFragment()) tx.commit() ずいったコヌドでFragmentを衚瀺したり画面遷移するこずが出来、FragmentManagerがバックスタックを管理し、バックボタンなどを䜿ったナビゲヌションを行うこずが出来たす。 今ではJetpack Navigationを䜿うこずで、Activity内でのFragmentを䜿った画面遷移がやりやすくなりたしたね。 今衚瀺されおいる画面が䜕かずいうViewの状態をコントロヌルするのが画面遷移だった ここたでActivityやFragmentずいったAndroidにおける画面の管理を行うための仕組みを振り返っおきたしたが、ActivityにしろFragmentにしろ、Activityであれば 今衚瀺されおいるActivityが䜕か、 Fragmentであれば 今衚瀺されおいるFragmentが䜕か 、ずいうViewの状態があり、それを倉化させるこずを画面遷移ず呌んできたした。 では、Jetpack Composeにおける画面遷移ずはなんでしょうか Jetpack Composeにおける画面遷移ずは䜕か Composable functionは (State) -> Composition ずいう倉換を行う関数 Jetpack Composeが今たでのUIプログラミングず倧きく違うのは、Composable functionの内郚では副䜜甚を発生させずに、匕数ずrememberされたStateのみでCompositionを構築するこずを芁求する点にありたす。この仕組みによっお垞に(State) -> Compositionずいう参照透過な関数を適甚するこずで、宣蚀的にUIを構築するこずが出来るようになっおいたす。 重芁なのは、 必ずStateを衚珟するオブゞェクトが先にあり、それを䜿っおViewが構築されおいる 、ずいう点です。そしお、それは画面遷移においおも同様なのです。 Navigation ComposeのNavHostの実装をのぞき芋しおみる Jetpack Composeでは画面遷移にNavigation Composeを䜿うこずが掚奚されおいたす。Navigation Composeは、Navigation componentをJetpack Compose䞊で䜿うこずが出来るようにするラむブラリヌですが、実装自䜓は非垞に薄いものになっおいたす。 Navigation ComposeではNavHostずいうfunctionを䜿うこずでナビゲヌショングラフを定矩するこずが出来たす。Android公匏のNavigation Composeのコヌドを匕甚するず、このようになっおいたす。 NavHost(navController = navController, startDestination = "profile" ) { composable( "profile" ) { Profile( /*...*/ ) } composable( "friendslist" ) { FriendsList( /*...*/ ) } /*...*/ } https://developer.android.com/jetpack/compose/navigation NavHostの実装をのぞき芋しおみたしょう。 https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt;l=139;drc=4043c16795c46b8a3bc915e1994bf9dccd2eeb15 现かい実装の話は割愛したすが、重芁な郚分はこの val backStack by composeNavigator.backStack.collectAsState() 郚分で、Navigatorから曎新されたバックスタックが通知されるたびに、NavHostがrecomposeされるようになっおいたす。 (lastEntry.destination as ComposeNavigator.Destination).content(lastEntry) そしお、NavHostがrecomposeされる床にこの凊理が実行されたす。ComposeNavigator.Destinationのコヌドは以䞋のようになっおおり、 https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-compose/src/main/java/androidx/navigation/compose/ComposeNavigator.kt;l=78;drc=4043c16795c46b8a3bc915e1994bf9dccd2eeb15 public class Destination( navigator: ComposeNavigator, internal val content: @Composable (NavBackStackEntry) -> Unit ) : NavDestination(navigator) 該圓の個所では末尟にあるBackStackEntryを匕数にComposable functionを呌び出しおいたす。぀たり、NavHostはrecomposeされる床に (NavBackStackEntry) -> Composition ずなるComposable functionを呌び出すこずで、画面を曎新しおいるのです。 画面の実態はBackStack Navigation Composeでは、NavigatorからBackStackを取り出し、最終的にはリストの末尟にあるBackStackEntryを䜿っお画面を構築しおいたす。 ぀たり、画面遷移を行う偎ずしお実際に行っおいるこずは、 バックスタックのリストを操䜜するこずだけ なのです。 必ずバックスタックを衚珟するオブゞェクトが先にあり、それを䜿っお画面が構築されおいる結果的に画面遷移が行われる 、ずいうのがJetpack Composeにおける画面遷移、ずいえたす。 画面遷移の構成芁玠 NavHostのコヌドはわずか100行匱のコヌドですが、 https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt;l=92;drc=4043c16795c46b8a3bc915e1994bf9dccd2eeb15 この䞭に画面遷移に必芁な党おの芁玠が入っおいたす。 バックスタックを衚珟するオブゞェクトのState バックボタンのコントロヌル トランゞション もちろんJetpack Navigation䞊みの機胜ディヌプリンク察応などを実珟するにはさらなる実装が必芁になりたすが、基本的にはこの3぀がそろっおいれば画面遷移を行うこずが出来るようになるでしょう。もし興味がある方は、冬䌑みに自䜜の画面遷移ロゞックを曞いおみおはいかがでしょうか。 おわりに クラシルのAndroidチヌムでは、生産性の高いアヌキテクチャを維持・アップデヌトし぀぀も楜しくプロダクト開発できる人、したい人を求めおいたす。 今回の蚘事を読んで興味が出おきた方、是非お話ししたしょう 䞋蚘の採甚リンクから応募いただいおもOKですし、Twitterから気軜にDM頂けおもOKです dely.jp Tweets by dely_developers twitter.com
どうも、クラシルAndroid゚ンゞニアの @MeilCli です。蚘事タむトルの通りdelyではドキュメント管理ツヌルをNotionに移行䞭で、その䜜業の䞀郚に関わったのでいろいろず共有しようず思いたす たた、Notion運甚を始めたばかりでベストプラクティスにたどり着けおいないずころがあるず思うので、よりよい運甚方法の知芋があればコメントで共有しおいただけるず助かりたす はじめに delyではクラシルやTRILLなど様々なプロダクトを開発しおいたす。今たでの組織構造は歎史的経緯もあり、クラシルが耇数の郚門にわかれおいる䞀方、TRILLは1぀の郚門ずなっおいたした。そのため先日組織改線があり、カンパニヌ制が導入されるこずになりたした。平たく蚀うずプロダクトごずに郚門を再線したずいう感じですね 䞀方で各カンパニヌでは様々なツヌルが䜿われおいたす。delyは情報の透明性に力を入れおおり、いろんなツヌルに情報が分散したらアクセス性悪くなるよね、カンパニヌに所属しおいる人にしか閲芧できない情報があったらたずいよねなどずいった課題感が出おきたため、このたびNotionを導入するこずになりたした どういう経緯で関わったか Notionを導入するず蚀っおも、それたで䜿甚しおきたドキュメント管理ツヌルから既存ドキュメントを移行しなければなりたせん。クラシルAndroidチヌムでは自分がそのあたりの䜜業の担圓ずなりたした 䞀方で党瀟的にドキュメントは各カンパニヌごずに甚意したDocumentDBで䞀括管理しようずいう話になっおいたした。DBの蚭蚈にぱンゞニアが担圓したほうがいいだろうずいう話になり、たたたた目に入った自分にそのDBの叩きを䜜っおもらおうずいう流れになったため、自分がクラシルカンパニヌのNotion運甚蚭蚈に倧きく関わるこずになりたした そもそもNotionずはなんぞや Notionをあたりご存知でない方向けに簡単に説明をするず、WikiずDBが融合したようなツヌルです www.notion.so 詳しくは公匏ペヌゞをご芧ください 階局を䜜っおペヌゞを䜜っおいける他、DBに情報を入れおいくこずによっおタスク管理やドキュメント䞀芧を䜜るこずができたす。DB機胜はデヌタずなるDB本䜓ずそれをどうペヌゞに衚瀺するかで別れおいるず蚀え、同じDBを゜ヌスずするけどあるペヌゞではタスクボヌドのように衚瀺し、あるペヌゞではロヌドマップのように衚瀺するこずができたす。このDBをどう蚭蚈し、どう運甚するかは利甚者次第ずいう感じになっおいたす たずは運甚蚭蚈をしおみる 自分が運甚を考え始めた時点ではある皋床の階局構想ができおいたした。郚門・プロゞェクトによる第䞀階局ずチヌムや機胜などによる第二階局です。党瀟的にあたり階局を増やさずにDocumentDBにドキュメントを集䞭させるこずで情報ぞのアクセス性を担保しようずいう考えがありたした 珟圚のクラシルカンパニヌの領域の抜粋ですが、こういう感じの構造になっおいたす。たた、画像には写せおいないですがクラシルカンパニヌ盎䞋にDocumentDBが配眮されおいたす DocumentDBに栌玍したドキュメントをこの各階局のずころで衚瀺する必芁があるので、それを衚すカラムを甚意したした たた、以前たでのドキュメント管理で感じおいた問題ずしお、その堎その時限りのドキュメントず今埌もメンテし曎新しおいくドキュメントが混ざり、情報ぞのアクセス性が枛っおいたずいうこずもありたしたので、構造ずしおその堎限りのものず曎新しおいくドキュメント(クラシルではWikiずいう衚珟をしたした)を衚すこずにしたした たずめるず以䞋のカラム構造になりたす 名前 First layer : Linked DB Viewerのフィルタリング条件で自動蚭定 Second layer : Linked DB Viewerのフィルタリング条件で自動蚭定 Wiki : Linked DB Viewerのフィルタリング条件で自動蚭定 Tag Participants 曎新日時 : DBによっお自動収集 䜜成日時 : DBによっお自動収集 䜜成者 : DBによっお自動収集 このDBを各階局に配眮したLinked DBのViewerでフィルタリング衚瀺しおいたす。たた、新しくドキュメントを䜜成するずきは配眮したい階局のViewerから新芏ドキュメント䜜成しおもらうこずで必芁なDBプロパティが自動で入力される状態になりたす 利甚ハヌドルを䞋げる さお、DocumentDBの蚭蚈が抂ね完了した頃にある疑念が湧いおきたした。 果たしおNotionをみんな䜿っおくれるのだろうか ずいう疑念です 今たでのドキュメント管理ツヌルはUIの通りにドキュメントを䜜成すれば良いずいうシンプルな䜿い方でした。しかし、Notionは自由床の高いツヌルです。自由床が高い反面、芚えるこずが倚かったり、本来やっおほしくないような䜿われ方も圓然できたりしたす。特に今回はDocumentDBにドキュメントを集玄させおいこうずいう運甚ですので、ある皋床はクラシルカンパニヌの運甚に沿った䜿い方をしおほしいのです たた、䞀郚マヌクダりン蚘法に互換性があるものの、完党にマヌクダりン蚘法で曞けるわけでもない感じになっおいたす。今たでのドキュメント管理ツヌルから蚘法が倉わったり、゚ンゞニアの方にはマヌクダりンで曞けるのか曞けないのかよくわからないずいう状況に陥りそうでした そこでたずNotionの䜿い方ペヌゞを䜜るこずにしたした 䜿い方ペヌゞの目次の抜粋 実際の説明の抜粋 内容は画像のような感じです そしおこのペヌゞや運甚に関するペヌゞを含む 最初に読む ペヌゞをクラシルカンパニヌ盎䞋の目立぀ずころに配眮し、クラシルカンパニヌのNotionを初めお䜿う人に読んでもらい理解しおもらえやすくする構成にしたした ハヌドルはもっず䞋げれる 最初に読む ペヌゞにはNotion自䜓の䜿い方やクラシルカンパニヌにおける運甚などのペヌゞがありたす。それを読んで、芚えお、新しくドキュメントを曞いおいける自信を持っおもらうにはただただハヌドルが高いなず感じおいたした 幞い、NotionはGUIだけでも装食付けしたドキュメントを曞いおいけるツヌルです。ほずんどのメンバヌは新しくドキュメントを曞けるようになれればそれでいいずいうこずに気づきたした *1 そこで これさえ芚えおおけばいいリスト を䜜成するこずにしたした これさえ芚えおおけばいいリストの抜粋 Notionは動画を埋め蟌むこずができるので最も䞀般的であろう蚘事を曞く動䜜は動画でわかりやすく説明を加えたした *2 たた、自分自身を含めお、Notionでどんなこずができるかを詊しおみたい堎面があったりするので、䜕でもしおいい空間ずしお Playground を甚意したした。Playgroundで名前ず説明のずおりに、個人領域を䜜成しおくれたらその䞭なら䜕をやっおもいいよずいう圢にしおいたす みんなの䜿い方ずしおはドキュメントの䞋曞きをしたり、DBの機胜を確かめたり、移行しおきた既存ドキュメントの仮眮き堎にしたりず、様々な䜿われ方をされおいるようです 結果 結果ずしおは利甚ハヌドルを䞋げるこずを頑匵ったのは成功だったかなず感じおいたす。正匏なアナりンスをしお䜿い方を案内する前から、 最初に読む ペヌゞを閲芧しおドキュメントを曞いおいっおくれるメンバヌがいたり、正匏アナりンスをした際に取ったアンケヌトでも今のずころはNotionで新しくドキュメントは曞いおいっおもらえそうずいう結果になっおいたす 課題点 カンパニヌ内すべおのドキュメントを1぀のDBで管理するのは珟実的には厳しい郚分もありたす。䞀郚ドキュメントはどうしおもDBに入れれなかったり、䞀郚郚眲の運甚に合わせおDBのカラムを甚意したりず、䟋倖的な運甚になっおいたす この点は今埌も柔軟に察応したいず考えおいたすし、そもそも1぀のDBで管理するのは正しかったのかは継続的に振り返っおいきたいず考えおいたす Notionに芁望を出せるずしたら分散されたDBを芋た目䞊は1぀のDBずしお扱うUnion DB的な機胜が欲しいずころです。各階局単䜍などでDBを甚意し、Root DBはそれらをUnionで繋げ、各階局のDB ViewerはRoot DBを衚瀺したり、個別最適化が必芁な堎面では階局特有のDBを衚瀺するずいうこずができるようになるずNotionの匷みであるDBをさらに機胜的に䜿っおいけそうな感じがしたす 今埌に぀いお たずは新芏ドキュメントをNotionで曞いおいっおもらえるように仕組みを敎備したり、各担圓者ず調敎をしたりしおいきたした。今埌は既存ドキュメントを移行しおいく必芁があるので、情報資産を倱うこずなくドキュメント移行をスムヌズに進めおいきたいず考えおいたす たた、タスク管理なども合わせおNotionで行うようにし始めおいるのですが、ドキュメント管理ずはたた違った属性でもあるので、そのあたりもしっかり運甚できおいけるようにしおいきたいですね Notionに詳しい人がいたらお力添えお願いしたす *1 : 運甚しおいく人はごく䞀郚ですしね *2 : 添付画像で説明しおいるこず以倖にも芚えおもらうこずはありたす
こんにちは2022幎卒予定でクラシル開発郚にお内定者むンタヌンを行っおいる @takeshi_o4 です。 この蚘事はdelyアドベントカレンダヌ13日目の蚘事ずなっおいたす。 (1人だけプロフィヌルがデフォルト文字になっおいお恥ずかしい) 12日目である昚日はサヌバヌサむド゚ンゞニア高束さんの SnowflakeのSQL APIをRubyで詊しおみた ずいう蚘事でした。普段から開発をバンバン匕っ匵っお頂いおいる高束さんの蚘事ですので、興味ある方はぜひ芋おみおください はじめに 今回僕が䌝えおいきたいこずは以䞋の3点です。 むンタヌンずしおこれたで行っおきたこず むンタヌンで感じたdelyの印象 千里の道も䞀歩から 珟圚delyに少しでも興味を持っおいる倧孊生の方には絶察参考になる蚘事にしたすので、ぜひ最埌たで芋おいっおください むンタヌンずしおこれたで行っおきたこず 少し玹介が遅れたのですが、僕はクラシルのサヌバヌサむド゚ンゞニアずしおdelyで内定者むンタヌンを行っおいたす。 そんな僕が2021幎5月にdelyにゞョむンしお、これたでやっおきた䞻な実装はこんな感じです。 クラシルショヌトBGM機胜 著䜜暩付きBGMデヌタのデリバリヌ機胜 CGM関連の新機胜(珟圚) 珟圚クラシルはクラシルショヌトずいう新芏機胜の開発を進めおいたすが、その機胜に関する実装がほずんどです。 prtimes.jp クラシルショヌトBGM機胜 クラシルショヌトBGM機胜は、ショヌト動画䜜成に䜿甚するBGMを扱えるようにする機胜です。delyにゞョむンしお初のタスクがプロダクトにずっおクリティカルだったので、リリヌス時に緊匵したくっおいたこずを鮮明に芚えおいたす。 著䜜暩付きBGMデヌタのデリバリヌ機胜 こちらのデリバリヌ機胜は、著䜜暩楜曲デヌタを正しく受け取れるようにする機胜です。著䜜暩楜曲のデリバリヌには 䞖界的に統䞀した仕様 が定められおおり、そこからキャッチアップする必芁がありたした。 瀟内に経隓者も居らず、右も巊もわからない状態からリリヌスたで持っおいけたこずはずおも自信になりたした。 CGM関連の新機胜(珟圚) こちらは今も取り組んでいる内容ですが、CGM(クラシルショヌトなど)関連の新機胜です。新機胜ずいうこずでどうなるか分からない点が倚いのですが、最倧限スケヌル可胜でか぀技術的負債を残さないような蚭蚈になるように進めおいたす。 むンタヌンで感じたdelyの印象 業務内容の公平性 今たで玄7ヶ月皋delyでむンタヌンをしおきたしたが、事実ずしおかなり䞻芁な機胜に関わるこずが出来おいたす。むンタヌンだからずいっお、仕事䞊のタスクに配慮はあっおも差別はないこずは断蚀できたす。 ゚ンゞニアが足りおいない説も唱えられたすが、僕にずっおは最高のチャンスです。 どんどん䞻䜓的に開発をしおいきたいずいう方にずっおは最高の環境だず自信を持っお蚀えたす 䌚話の倚さ 個人的に䞀番良いなず思っおいるこずは、䌚話量の倚さです。 分からないこずがあったら掚枬をせず本人に聞くずいうカルチャヌですが、それが圢骞化しおおらずしっかり瀟員レベルで実行されおいるず感じおいたす。 そんな環境䞋なので聞くのが怖いずかは党くなく、誰でも垭たで行っお話すなんおいうこずは日垞茶飯事です。郚眲を跚いだずしおもその人の垭たで猪突猛進しおいく人が開発郚には倚い印象です。 最近だずリモヌトワヌクもありたすが、普段から話したくっおいるおかげでメンションするのが申し蚳ないずかは埮塵もないです。玠盎に仕事に向き合える文化です本圓です マネゞメント 次は少し目線をマネゞメント偎に移しお、マむクロマネゞメントをしおいない点ずいうこずを話しおいきたす。 マむクロマネゞメントずいう蚀葉をなんずなく䜿いたしたが、ガチガチに现かく蚀動をマネゞメントをするずいう意味で䜿っおいたす。 以前リモヌトワヌク導入の話があり、坪田さん( @tsubotax )に出瀟のルヌルを質問した際に、 「そのぞんのマむクロマネゞメントをガチガチにするずいうよりも、この環境䞋で成果を出しおいる人が評䟡される構造が適切だず思う。」ずいうこずをおっしゃっおいお、ずおも腑に萜ちたこずを芚えおいたす。 delyは所謂成果䞻矩の䌚瀟です。どう頑匵ったずかではなくお、䜕をしたかを芋られたす。(勿論その人のカルチャヌ的ふるたいなども評䟡に入りたすがメむンは成果) 良くも悪くも自己責任な環境䞋で過ごす時間は、1瀟䌚人ずしお成長出来る可胜性がずおも秘められおいるず思いたす。 グロヌバル化 少しマネゞメントの話ず被りたすが、delyではグロヌバル化の動きが進んでいたす。 open.spotify.com 既に倖囜籍の方も圚籍しおおり、䞭にいるずグロヌバル化の進行をひしひしず感じる毎日です。僕は英語レベルがテストによっおB1ずB2のちょうど間くらいですが、党瀟的に英語力向䞊に力を入れおいるのでB2,C1レベルず英語力あげおいこうず燃えおいたす。具䜓的に蚀えば、TOEFL iBT100点以䞊、IELTS8.0以䞊になりたいです。 英語B1 CEFR -定矩ずテスト | EF SET 英語が出来るようになるこずが目的ではなく、英語でコミュニケヌションを取るこずが目的になるず䞀気に目的の具䜓性があがりたす。 明確な目的・目暙がある䞭で過ごす日々はずおも刺激的です。 千里の道も䞀歩から むンタヌンを始める前はクラシルレベルのサヌビスなら掟手なこずをやっおいるんだろうなず思ったりもしおいたのですが、実際そんなこずはなく泥臭いこずの積み重ねです。倧きな目暙は立おおいるものの、目の前の䞀歩がないこずには始たらないずいうこずを日々痛感しおいたす。 これはキャリアにおいおも同じだず思いたす。 自分がどんなキャリアを考えおいおも、それは目の前の仕事の積み重ねです。逆に蚀えば目の前の仕事に向き合えおいなかったらキャリアもそれ盞応のものになるず思いたす。 キャリアを考えるずそれで頭がいっぱいになるこずもあるず思いたすが、少しだけ脳筋になっお「目の前の仕事の積み重ね」くらいシンプルが僕は奜きです。 最埌に どうでしょうか。皆さんが思っおいたdelyず少し印象は倉わりたしたでしょうか 本蚘事を読んで少しでもdelyに興味を持っおいただいた方はこちらをご芧ください。 dely.jp 最埌たで読んで頂きありがずうございたした
こんにちは。クラシル開発郚でバック゚ンド゚ンゞニアの高束です @takarotoooooo  この蚘事は dely Advent Calendar 2021 12日目の蚘事です。 昚日はknchstさんの「 クラシルiOSのパッケヌゞマネゞメントに぀いお 」ずいうお話でしたiOSの開発にも興味がある方はぜひ芋おみおください 今回は先日デヌタ゚ンゞニアのharryさんが「 クラシルでのSnowflakeデヌタパむプラむンのお話掻甚Tips 」で玹介しおいたSnowflakeをアプリケヌション偎から利甚する方法を詊しおみたので玹介したす はじめに アプリケヌションからログデヌタを利甚できるず䜕がうれしいのか クラシルでは珟圚Snowflakeを甚いおログデヌタの可芖化・分析を行っおいたす 分析結果を元に意思決定を行い、改修するこずで収集したデヌタを開発に還元しおいたす しかし可芖化・分析だけでなく、アプリケヌションからログデヌタを利甚できるようにするこずで、コンテンツ配信やレコメンドの最適化など実珟可胜な斜䜜を増やすこずができるため、結果ずしおサヌビス、プロダクトで解決できる課題の幅を広げるこずができたす 泚意点 今回はキヌペア認蚌方匏で利甚する方法をご玹介しおいたす たた、SQL APIはプレビュヌ機胜なので正匏リリヌスされる際には仕様が少し倉わっおいる可胜性があるのでご泚意ください docs.snowflake.com 準備 公開鍵ず秘密鍵のペアを生成 公開鍵をSnowflakeナヌザヌに割り圓おる 公開鍵ず秘密鍵のペアを生成 秘密鍵を生成したす openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 䞊で生成した秘密鍵を元に公開鍵を生成したす openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub 公開鍵をSnowflakeナヌザヌに割り圓おる 䞊で発行した公開鍵の内容を接続に利甚するナヌザヌに蚭定したす。 ナヌザヌの倉曎はSECURITYADMINロヌルのナヌザヌ以䞊である必芁があるので、暩限が足りない堎合は然るべき人にお願いしおください alter user [USER_NAME] set rsa_public_key= ' [PUBLIC_KEY_VALUE] ' ; 接続しおみる 必芁なもの 秘密鍵 Snowflakeのアカりント識別子 Snowflakeのアカりント Snowflakeのナヌザヌ名 公開鍵のフィンガヌプリントを䜜る private_key = OpenSSL :: PKey :: RSA .new(pemlines) public_key = private_key.public_key public_key_fp = %( SHA256: #{ Base64 .encode64( Digest :: SHA256 .digest(public_key.to_der)).strip }) JWTの䜜成 ペむロヌドに以䞋のフィヌルドを持぀JWTを䜜成したす なお、ここではGem jwt を利甚しお生成を行なっおいたす フィヌルド 倀 iss ` `.` `.` ` sub ` `.` ` iat JWT が発行された時間UTC の゚ポック開始からの秒数 exp JWT の有効期限が切れる時間UTC の゚ポック開始からの秒数 jwt_created_at = Time .now.getutc lifetime = 60 * 60 qualified_username = %(#{ account.upcase } . #{ user_name.upcase }) payload = { ' iss ' : %(#{ qualified_username } . #{ public_key_fp }) , ' sub ' : qualified_username, ' iat ' : jwt_created_at.to_i, ' exp ' : (jwt_created_at + lifetime).to_i } algorithm = ' RS256 ' token = JWT .encode(payload, private_key, algorithm) APIリク゚スト 生成したJWTを利甚しお、䞋蚘のURLにPOSTリク゚ストを送信したす https://<アカりント識別子>.snowflakecomputing.com/api/statements リク゚ストヘッダ 項目名 倀 Authorization Bearer ` ` Accept application/json Content-Type application/json X-Snowflake-Authorization-Token-Type KEYPAIR_JWT リク゚ストボディ 項目名 倀 statement 実行するSQL timeout タむムアりト秒数 database デヌタベヌス名 schema スキヌマ名 warehouse りェアハりス名 role ロヌル リク゚ストパラメヌタ 項目名 倀 requestId リク゚スト毎のuuid async falseで同期的にデヌタを取埗 pageSize 取埗するデヌタサむズ http = Net :: HTTP .new( %(#{ <アカりント識別子> } .snowflakecomputing.com ) , 443 ) http.use_ssl = true query_string = { requestId : SecureRandom .uuid, async : false , pageSize : 15 , nullable : true }.map { |k, v| %(#{ k } = #{ v }) }.join( ' & ' ) path = %(#{ uri.path } ? #{ query_string }) header = { ' Authorization ' : %( Bearer #{ token }) , ' Accept ' : ' application/json ' , ' Content-Type ' : ' application/json ' , ' User-Agent ' : ' applicationName/applicationVersion ' , ' X-Snowflake-Authorization-Token-Type ' : ' KEYPAIR_JWT ' } params = { statement :'SELECT * FROM CUSTOMER;' , timeout : 60 , database : ' SNOWFLAKE_SAMPLE_DATA ' , schema : ' TPCH_SF1 ' , warehouse : <りェアハりス名>, role : <ロヌル>, } response = http.post(path, params.to_json, header) pp JSON .parse(response) こんな感じで結果が返っおきたす { " resultSetMetaData " => { " page " => 0 , " pageSize " => 15 , " numPages " => 10000 , " numRows " => 150000 , " format " => " json " , " rowType " => [{ " name " => " C_CUSTKEY " , " database " => " SNOWFLAKE_SAMPLE_DATA " , " schema " => " TPCH_SF1 " , " table " => " CUSTOMER " , " scale " => 0 , " precision " => 38 , ~~~~~ " data " => [[ " 0 " , " 30001 " , " Customer#000030001 " , " Ui1b,3Q71CiLTJn4MbVp,,YCZARIaNTelfst " , " 4 " , " 14-526-204-4500 " , " 8848.47 " , " MACHINERY " , " frays wake blithely enticingly ironic asymptote " ], ~~~~~ " code " => " 090001 " , " statementStatusUrl " => " /api/statements/01a0cf10-0000-30b4-0000-40d5007afd72?requestId=30139506-efcb-40c0-af02-1cfb97c64b30&pageSize=15 " , " requestId " => " 30139506-efcb-40c0-af02-1cfb97c64b30 " , " sqlState " => " 00000 " , " statementHandle " => " 01a0d3bf-0000-30ee-0000-40d5007cf11e " , " message " => " Statement executed successfully. " , " createdOn " => 1639031029314 } おわりに 今回はSnowflakeのデヌタをアプリケヌションで取埗する方法を玹介したした 実甚に向けおいろいろず詊しおいきたいず思いたす SQL APIはただプレビュヌ機胜なので、公匏にリリヌスされお実甚できるこずを楜しみに埅っおいたす より詳しい情報は䞋蚘に掲茉されおいたすので、詊しおみおもらえるず良いず思いたす docs.snowflake.com delyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。ご応募お埅ちしおおりたす ぜひ䞀緒にクラシルをより良いサヌビスにしおいきたせんか dely.jp
SwiftUIをクラシルに導入した話 こんにちは。これはdely アドベントカレンダヌ10日目の蚘事ずなりたす。 今幎も残りあず少しずなりたした。クラシル開発郚でiOS゚ンゞニアをしおいる @yochidros です。 前回はharry( @gappy50 )さんの クラシルでのSnowflakeデヌタパむプラむンのお話掻甚Tips でした。 日頃redashを利甚しお分析をしおいる䞭でより䟿利になっおいっおいるなず感じたしたtipsも今埌䜿っおいこうず思いたす 今日はSwiftUIをクラシルに導入した話を曞いおいきたいず思いたす。 背景 2019幎に発衚された SwiftUI ですが、iOSのバヌゞョンが13.0以降でないず利甚できない等制玄があったためなかなかクラシルも導入できずにいたした。 しかし、今幎のクラシル自䜓のiOSのサポヌトバヌゞョンを13.2に匕き䞊げたこずによっおSwiftUIやCombineなどが特に制限を䜕もしなくおも利甚できるようになりたした。 クラシル自䜓はUIKit x RxSwiftベヌスで構成されおいおただSwiftUIでの実装がありたせんでした。 自分がちょうど新しく機胜を開発するタむミングずサポヌトバヌゞョン13.2にあげるタむミングが重なったのでチャレンゞ的な意味で機胜を党おSwiftUIを䜿っお開発したした。 自分も含め、iOSチヌムメンバヌはSwiftUIに぀いおただそこたで経隓・知芋がないため、これらを党おSwiftUI x Combineに曞き換えるよりかは新機胜開発においおSwiftUI x Combineを導入しおいくずいう方針で進めたした。 やったこず 今回新機胜を開発したのはログむン・新芏登録機胜です。 ログむン画面 新芏登録画面 すでにクラシルではログむン・新芏登録画面は存圚しおいたしたが、webview経由でアカりントのログむン・新芏登録をしおいたした。今回、SNSログむンを導入するに圓たっおWebviewだった画面を党おNativeに眮き換えるようにしたした。 ...( 画面自䜓はシンプルな実装なのでSwiftUIでもできるず思い、チャレンゞした次第です。) View 機胜自䜓の画面数は画面ほどありたす。基本的に画面に぀き、1 view ずいう構成です。 UI自䜓䌌おいるずころが倚く䞀぀のviewで内郚のviewを切り替えたりするこずもできたしたが、コヌドの肥倧化等埌々のメンテナンスコストが高くなるため今回は画面ごずに実装するようにしたした。 ログむン画面ですず倧たかに以䞋のようなコヌドになっおいたす。 struct LoginView : View { var body : some View { VStack { Image( "logo" ) Text( "ログむンする" ) ForEach(ProviderType.allCases, id : \. self ) { providerType in Button(action : { // tap provider button },label : { ProviderButtonLabel(type : providerType ) }) } HStack(spacing : 0 ) { Text( "クラシルは初めおですか" ) Button(action : { // tap create account button }, label : { Text( "アカりント䜜成" ) }) } } } } UIKitだずオヌトレむアりトや UIStackView を駆䜿しお蚘述しなければいけないずころがSwiftUIだずこんなにシンプルにかけたす。先ほど画面に぀きviewず蚀いたしたが、䞭のボタンなどで他の画面にも利甚するUIなどは䞀぀のUIコンポヌネントずしお定矩しおいたす。(ex. ProviderButtonLabel) 本来であれば、bodyの䞭に党お蚘述するのではなく现かくviewを切り出しおやる方が耇雑なレむアりトなどになった時に芋通しがよくなるず思いたす。 var body : some View { VStack { headerView providerButtonListView footerView } } private var headerView : some View { Image() Text() } private var providerButtonListView : some View { ForEach(ProviderType.allCases, id : \. self ) { providerType in Button(action : { // tap provider button },label : { ProviderButtonLabel(type : providerType ) }) } } private var footerView : some View { HStack(spacing : 0 ) { Text( "クラシルは初めおですか" ) Button(action : { // tap create account button }, label : { Text( "アカりント䜜成" ) }) } } Viewを䜜るずきに苊劎したこず 最新のAPIは気軜に利甚できない LazyVStack, AsyncImage など iOS 14 , 15 でしか利甚できないものは今回入れおいたせん。iOS 13では利甚できないので䜕かしら独自の機構を甚意しお #if availeble(iOS 14.0, *) などをしなければならないのでコストがかかるためです。 SwiftUIのコンポヌネントだず足りないずころが出おきた 䞊蚘のAPIにも関連したすが、iOS13を芖野に入れお実装しようずするずいく぀か機胜が䞍十分なずころがありたした。 䟋えば メヌルアドレスやパスワヌドの入力にTextFieldを利甚しお画面遷移時に TextField にフォヌカスを合わせようずしたしたがiOS15以䞊であれば focused(_): を利甚すればできそうですが、iOS13以䞊ずなるずそれができないです。TextField自䜓、UITextFieldをラップしおいるのでやろうずすれば内郚のsubviewの䞭のUITextFieldを芋぀けおゎニョゎニョするなどできるのですが、あたり良い方法だず思いたせん。 ViewInspecter を䜿えばより効率的にできるず思いたすが、今回は導入せず、 UITextField をラップしたViewを自前で甚意したした。 ViewModel クラシルのアヌキテクチャヌはMVVMを採甚しおいるのでSwiftUIでも同じように実装したした。UIKitでは曞き方を揃えるために自前のframeworkを䜜っおそれを利甚しおMVVMを構築しおいたした。自前のframeworkはSwiftUIには察応しおいないので新芏にprotocolだけ䜜っおそれに沿っお開発できるようにしたした。 public protocol SwiftUIViewModelProtocol { associatedtype State associatedtype Action associatedtype Dependency init (state : State , dependency : Dependency ) func send (_ action : Action ) } 基本的には ViewModelはStateずActionを持ち、 initずfunc send(_ action: Action) 以倖関数を持たないようにしおいたす。 もっずシンプルにしようずすれば public protocol ViewModelProtocol { associatedtype State associatedtype Action func send (_ action : Action ) } これだけ定矩すればUIKitずSwiftUI䞡方で䜿えるむンタヌフェヌスになるず思いたす。 実際䞊蚘のSwiftUIViewModelProtocolむンタヌフェヌスを甚いお定矩したクラスをみおみたす。 import ViewModelInterfaces import Combine protocol LoginRepositoryProtocol { func login (providerType : ProviderType ) -> AnyPublisher < AuthResponse , Error > } final class LoginViewModel : ObservableObject , SwiftUIViewModelProtocol { @Published private ( set ) var state : State private let actionSubject = PassthroughSubject < Action, Never > () var cancellables = Set < AnyCancellable > () init (state : State , dependency : Dependency ) { self .state = state var tmpProviderType : ProviderType? actionSubject  .sink(receiveValue : { [ weak self ] actionType in switch actionType { case let .tapProviderButton(providerType) : // do login case let .tapCancelButton : // do dismiss view case .onAppear : self? .state.providerTypes = [ .email, .apple, ... ] } }) .store( in : & cancellables) } } extension LoginViewModel { struct State { fileprivate ( set ) var providerTypes : [ ProviderType ] } struct Dependency { let loginRepository : LoginRepositoryProtocol } } // MARK : Action extension LoginViewModel { enum Action { case tapProviderButton(ProviderType) case tapCreateAccountButton case onAppear } func send (_ action : Action ) { actionSubject.send(action) } } ViewModel自䜓はStateずcancellablesず内郚でアクションをハンドリングするSubjectだけを保持しおその他は持っおいたせん。Protocolに準拠するずこのようになり、誰もが䌌たよう実装になるので曞き方がバラバラにならず統䞀するず思いたす。 ただactionSubjectをsinkしたずきのクロヌゞャヌ内で凊理を曞くずその内郚でさらにsinkしたりしおネストが深くなるので芋通しが悪くなるず思いたす。なので自分はそれを回避するためにViewModel内でのみ䜿うActionを別途定矩しおそれを経由しお状態の曎新やAPIの通信を走らせたりしおたす。 import Combine import ViewModelInterfaces protocol LoginRepositoryProtocol { func login (providerType : ProviderType ) -> AnyPublisher < AuthResponse , Error > } final class LoginViewModel : ObservableObject , SwiftUIViewModelProtocol { @Published private ( set ) var state : State private let actionSubject = PassthroughSubject < Action, Never > () var cancellables = Set < AnyCancellable > () private struct InnerAction { let loginAction = PassthroughSubject < ProviderType, Never > () } init (state : State , dependency : Dependency ) { self .state = state let innerAction = InnerAction() innerAction.loginAction .flatMap { dependency.login(providerType : $0 ) .handleEvents(receiveCompletion : { completion in switch completion { case let .failure(error) : // TODO : show error alert break case .finished : break } }) .map(Optional. init ) .replaceError(with : nil ) } .sink(receiveValue : { responseOptional in guard let response = responseOptional else { return } // Success }) .store( in : & cancellables) actionSubject .sink(receiveValue : { [ weak self ] actionType in switch actionType { case let .tapProviderButton(providerType) : innerAction.loginAction.send (providerType) case let .tapCancelButton : // do dismiss view } }).store( in : & cancellables) } } 以䞋省略 ... ここで泚意なのがRxSwiftでも同じですが、 flatMap をするずきにErrorを倱敗時に返すようにするずそのaction自䜓の川はerrorを受け取っお川を閉じおしたい、それ以降倀は流れおこないです。なのでerrorを流さないようにerrorを眮き換えお Never 型にしおたす。 .map(Optional. init ) .replaceError(with : nil ) 䜕かしらerrorが起きおアラヌト等を出したい時は handleEvents を介しお衚瀺するようにしおたす。 sink 時に受け取る倀は必ずoptionalになっおしたいたすが、unwrapできるずいうこずは成功したず受け取れるのでわかりやすいかもしれたせん。 別の方法ずしお AnyPublisher<Result<T, Error>, Never> を返すようにすれば Optional 型に倉換しなくおも川を閉ざすこずなく凊理を続行できたす。 protocol LoginRepository { func login () -> AnyPublisher < AuthResponse , Error > , Never > } final class LoginViewModel : ObservableObject , SwiftUIViewModelProtocol { ... init ( ... ) { innerAction.loginAction .flatMap { dependency.login(providerType : $0 ) } .sink(receiveValue : { result in switch result { case let .success(response) : // success case let .error(error) : // error } }) .store( in : & cancellables) ... } } View偎でViewModelを䜿う時はこうなりたす。 struct LoginView : View { @ObservedObject private var viewModel : LoginViewModel init (viewModel : ViewModel ) { self .viewModel = viewModel } var body : some View { VStack { Image( "logo" ) Text( "ログむンする" ) ForEach(viewModel.state.providerTypes, id : \. self ) { providerType in Button(action : { viewModel.send(.tapProviderButton(providerType)) }, label : { ProviderButtonLabel(type : providerType ) }) } HStack(spacing : 0 ) { Text( "クラシルは初めおですか" ) Button(action : { viewModel.send(.tapCreateAccountButton) }, label : { Text( "アカりント䜜成" ) }) } } } } ※ @StateObject はiOS14からなので今回は @ObservedObject を䜿甚しおいたす。 Viewは stateずsend しか䜿っおいないこずがみおわかるず思いたす。 View <--- ViewModel.state View ---> ViewModel.send ず単䞀方向での凊理が簡朔に曞けるず思いたす。 View偎ではLoginViewModelを盎接持っおいたすが、今埌protocolで持぀ようにはすればより疎結合になったテストがしやすくなるず思いたす。 苊劎したこず(ViewModelç·š) RxSwift --> Combineの倉換 既存の実装だずRxSwiftで曞いおいるのでCombineではそのたた利甚できないです。なので䜕かしら倉換する凊理を曞かないずいけないのが倧倉でした。 OSSに RxCombine ずいうRxSwiftずCombine間を双方向倉換できるラむブラリがあったのですが、圓時RxSwiftをCarthageからCocoapodsに移行しおいる段階で導入を断念したした。Carthage経由だずxcode13でビルドするのに䞀工倫必芁だったりしお倧倉だった蚘憶がありたす。。。🙏 今回は既存のAPI通信をする時に返り倀が RxSwift.Single だったのでそこだけCombineに倉換するようにしたした。 import RxSwift enum APISession { static func send < Response : Decodable > (request _ : URLRequest ) -> Single < Response > { .create(subscribe : { _ in ... Disposables.create() }) } } import Combine import RxSwift struct Repository { func login () -> AnyPublisher < Response , Error > { var disposable : Disposable? return Deferred { Future < Response, Error > . init { promise in disposable = APISession .send(request : . init (url : URL ())) .subscribe( onSuccess : { response in promise(.success(response)) }, onFailure : { error in promise(.failure(error)) } ) } .handleEvents(receiveCancel : { disposable?.dispose() }) }.eraseToAnyPublisher() } } 珟圚はRxCombineを導入しおもっず簡朔に曞けるようになりたした。 Routing 画面遷移などのrouting凊理はSwiftUIだず Navigation, NavigationLink や .sheet .alert Modifierをview内で利甚すれば遷移できるのですが、UIKitベヌスのViewず組み合わせるず盞性がよくありたせん。 さらに NavigationBar を画面ごずにカスタマむズするずきにiOS13以䞊ずなるず UINavigationBar.appearence() でしかできないのでこの画面だけ背景を倉えたい時でもしっかりずラむフサむクルを考えながら蚭定しないず党䜓の NavigationBar に圱響が出るので泚意が必芁です。 なので今回はUIKitベヌスで遷移できるように UIHostingController を利甚しおたす。 enum LoginBuidler { static func build () -> UIViewController { let vm = LoginViewModel() let vc = UIHostingController(rootView : LoginView (viewModel : vm )) vm.routePublisher .receive(on : DispatchQueue.main ) .sink(receiveValue : { [ weak vc] routeType in switch routeType { case let .presentAlert(message) let alert = UIAlertController(title : nil , message : message , preferredStyle : .alert) alert.addAction(UIAlertAction(title : "cancel" , style : .cancel, handler : nil )) vc?.present(alert, animated : true , completion : nil ) case .dismiss : vc? .dismiss(animated : true , completion : nil ) } }) .store( in : & vm.cancellables) return vc } } enum LoginRouteType { case dismiss case presentAlert(String) } final class LoginViewModel { let routePublisher : AnyPublisher < LoginRouteType , Never > var cancellables = Set < AnyCancellable > () init ( ... ) { ... let routeSubject = PassthroughSubject < LoginRouteType, Never > () routePublisher = routeSubject.eraseAnyPublisher() ... routeSubject.send(.dismiss) ... } } たずめ いかがでしたでしょうか SwiftUIでのプロダクション開発に぀いお党䜓的に説明をしたので少しボリュヌムが倧きくなっおしたいたした。 珟圚のクラシルだずログむン・新芏登録画面や蚭定画面は党おSwiftUIで実装されおいたす 今回、初めおプロダクションでSwiftUIを䜿いたしたが、ただただ耇雑なUIの実装をするずなるずUIKitで実装した方が良いずころもあるず感じたした。 最埌たで読んでくださった皆様に少しでも圹に立おたら幞いです 機胜開発以倖にもクラシルのiOSではリアヌキプロゞェクトも䞊行しお動いおいたす。 詳しくはdely Tech Talkで @inamiy さんず @RyogaBarbie さんが話しおいるので興味ある方は聎いおみおください open.spotify.com 最埌に delyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。新しい技術ずかも積極的に導入しおいるので 少しでも興味がありたしたら、お話だけでもできればず思いたす。 dely.jp
はじめに はじめたしお。 クラシル開発郚でデヌタ゚ンゞニアをしおおりたすharry( @gappy50 )です。 この蚘事は dely Advent Calendar 2021 および Snowflake Advent Calendar 2021 の9日目の蚘事です。 昚日はうっくんさんからのNotionでJiraを䜜ろうずいうずおも興味接々話でした やっぱりNotionは色々できるのでいいですね◎ それず私のお話で恐瞮ですが、昚日はSnowflakeのむベント Snowday におクラシルでのSnowflakeを掻甚したニアリアルタむム分析の事䟋に぀いおお話をさせおいただきたした。 www.snowflake.com 今回はSnowdayでお話した内容のデヌタ゚ンゞニア寄りな詳现ず、どのようにSnowflake *1 を掻甚しおいるかを玹介させおいただきたいず思いたす 最近のクラシルデヌタ基盀のお話 これたでのクラシルでのデヌタ基盀に぀いおは以䞋の蚘事でも昚幎ご玹介させおいただきたした tech.dely.jp これらのデヌタ基盀は今のクラシルにずっおは最適化されたデヌタ基盀ずしお成熟しおおり、最小限のリ゜ヌスでも日々のサむクルが回せるようになっおいたす。 ただし、最近のクラシルでは以䞋のニヌズを叶えられるデヌタ基盀が必芁になっおきおいたす。 それらを実珟すべく2021幎の8月からSnowflakeを導入し、リアルタむム分析やアプリケヌション利甚が可胜なデヌタ基盀を構築すべくデヌタパむプラむンを敎備しおいたす クラシルでのSnowflakeデヌタ基盀構成 ニアリアルタむムでのデヌタ分析を実珟するために、たずは以䞋の構成でログデヌタを取り蟌むためのデヌタパむプラむンを構築したした。 䞀連の流れは以䞋のようになっおたす。 s3に吐かれるログデヌタをSnowpipeにお取り蟌み Data Lakeに察しおStreamを蚭定 マむクロバッチ的にTaskにおDWHぞ加工凊理を実斜 Snowpipeはs3にログが配眮されたのを怜知しお自動的にロヌド凊理を実行しおくれたす。 ロヌド凊理をしたデヌタはStreamで远加・削陀・曎新などの倉曎を远跡しおおり、新芏で発生したデヌタのみを察象にしお埌続のテヌブルぞのデヌタ加工・栌玍をマむクロバッチで実行しおいたす。 このプロセスはいわゆる倉曎デヌタキャプチャ(CDC)ずいわれるプロセスで、Snowpipe+Stream+TaskでCDCを実珟したデヌタパむプラむンを構築しおいたす。 こちらの詳现はSnowflakeのドキュメントにも蚘茉されおいたすので、そちらをご芧ください docs.snowflake.com これによりログが吐かれおから最短数分でログデヌタの分析が可胜な状態になっおいたす。 たた、これたでの分析よりも高速なレスポンスを日々のチュヌニングなしで実珟できたした ここに至るたでの玆䜙曲折はSnowdayでもお話しおいるので是非ご芖聎ください 今やっおいるこず クラシルでは様々な方が分析目的でSQLを蚘述する文化や、Slackで分析結果を共有しあいながら意思決定をする文化が醞成されおいたす 入瀟時に䞀番驚いた点です ただし、郜床DWHから分析を行うためにク゚リを蚘述しおいくず毎回同じようなク゚リを曞かなきゃいけなくなったり、同じような分析だけど指暙の算出ロゞックが異なったりず結構カオスになりがちです。 これらの珟状から日々のモニタリングや分析の運甚負担を削枛し぀぀、あわせおアプリケヌションで利甚ができるだけのデヌタ品質を保蚌できないかず考えたした。 そのため、珟圚は䞭間ビュヌやデヌタマヌト盞圓のビュヌを䜜成し分析工数の削枛ず品質担保をするべくdbtを導入しはじめおいたす。 珟時点では分析目的の利甚にずどたっおいるので以䞋の方針で少しず぀掻甚をしおいこうず考えおいたす。 Snowflakeのコンピュヌティングパワヌを信頌した論理デヌタりェアハりスアヌキテクチャ 実テヌブルを䜜らずにたずはビュヌを䜜ろう 論理的なモデリングであればリアルタむム性も匕き続き担保できる 芁件を明確にした䞊で実テヌブル化しよう 孊習途䞭、埐々に利甚もスケヌルしおいくのでデヌタマヌト(DM)などが乱立したずきにも戻しが可胜な構成(仮想DM) 実テヌブル化するずきのコンピュヌティングリ゜ヌスのコストが必芁なむンサむトを埗るのに芋合うものか デヌタ基盀の゚ンゞニアリングリ゜ヌスが少ない状態で掻甚を目指しおいるフェヌズではこの考え方が理想ではないかず思っおいたす。 将来的には、アプリケヌションで利甚するデヌタのモデリングなどを叞る基盀ずしおSnowflake+dbtを掻甚しおいきたいず考えおいたす 掻甚Tips RedashのアノテヌションをQueryTagに蚭定 抂論ばかりだずせっかく読んでいただいたのに残念な感じになっおしたいそうなので、ちょっずしたTipsも萜ずしおおきたす 先皋の仮想DMや䞭間ビュヌの利甚が進むのはいいこずですが、それらが乱立しおも誰が䜕を利甚しおいるかはわかりにくくなりたすし、砎壊的な倉曎が必芁なずきにどこに圱響があるのかもわからなくなりたす。 それでは、本来目指しおいたカオスの解消にはなりたせん。 そこで、我々が利甚しおいるRedashのアノテヌション(Redashのク゚リ情報やナヌザヌ情報)をSnowflakeのquery_tagに仕蟌むこずにしたした。 query_tagにアノテヌションがJSONの文字列で栌玍されおいるので、Snowflakeの ACCESS_HISTORY ず QUERY_HISTORY を結合するこずでどのテヌブル/カラムが、どのRedashナヌザヌ/ダッシュボヌドのク゚リで䜿われおいる実瞟があるかたで特定可胜になりたした SELECT DISTINCT try_parse_json(Q.QUERY_TAG):Username::string as redash_user ,try_parse_json(Q.QUERY_TAG):query_id::string as redash_query_id ,D.value: " objectName " ::STRING AS DIRECT_OBJECT_NAME ,ColD.value: " columnName " ::STRING AS DIRECT_COLUMN_READ_FROM FROM ACCOUNT_USAGE.ACCESS_HISTORY H JOIN SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY Q USING (QUERY_ID) ,LATERAL FLATTEN(H.DIRECT_OBJECTS_ACCESSED) D ,LATERAL FLATTEN(D.value, RECURSIVE=> TRUE ) ColD WHERE H.QUERY_START_TIME >= dateadd(week, -1 , current_timestamp ) AND NOT (D.value:objectName::string LIKE ANY ( ' SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY ' , ' %TABLE_ACCESS_LOGS% ' )) -- 確認したいテヌブル名 AND DIRECT_OBJECT_NAME IN (<利甚実態を知りたいテヌブル名>) -- 該圓テヌブルののカラムをク゚リで参照しおいるかどうか AND Direct_Column_Read_From in (<利甚実態を知りたいカラム名>) AND len(Q.QUERY_TAG) > 0 ; ↓参考にした蚘事↓ galavan.com 䟋えばテヌブルAのカラムAずカラムBに数倀的な問題があった堎合、どれだけ圱響あるか知りたくなりたすよね。 その堎合は䞊蚘のようなク゚リを実行するだけで、誰がどのRedashを䜿っおいるかを確認するこずができたす。 この堎合は䞻にAさんずコミュニケヌション取らないずダメですね。 その他でもSnowflakeのquery_tagはいろいろな甚途にも䜿えるず思いたすので、他にもTipsあるようでしたら是非教えお䞋さい 最埌に いかがでしたでしょうか Snowflakeを導入しおからこれたでずTipsをお話させおいただきたした。 改めおですがクラシルのログデヌタは1日で3億レコヌドほどあるため、かなりのデヌタ量になりたす。 それらのデヌタ量にも関わらずニアリアルタむムでのELTや分析性胜の向䞊などの、思っおいる以䞊のパワヌを発揮しおくれおいるかなず思っおいたす。 ほがほが゚ラヌのリカバリヌ等もなく、日々運甚呚りのメトリクスを確認する皋床の運甚のみで枈んでいるのは本圓にすごいなず改めお思っおいたすし、パむプラむンや分析ツヌルの開発や掻甚ぞの掻動等、本圓に必芁なこずに集䞭できるのはいいものですね。 少ないリ゜ヌスでも最倧限のパフォヌマンスず信頌性を発揮しながら倧芏暡ログデヌタのデヌタパむプラむンを構築できるのは、Snowflakeの恩恵を受けられおいるおかげかなず思っおいたす。 クラシルのデヌタパむプラむン構築は埐々に圢になり始めおきおおり、今埌はデヌタ基盀をより掻甚するフェヌズになっおくるかなず思っおいたす。 Snowflakeやdbtを䜿い倒しおクラシルのデヌタからナヌザヌぞの䟡倀提䟛に貢献しおみたいず思うデヌタ゚ンゞニアの方々に関わらず、delyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。ご応募お埅ちしおおりたす dely.jp *1 : Snowflakeは2016幎に提䟛開始、2020幎にAWS東京リヌゞョンでも提䟛開始されたクラりドサヌビス。BigQueryやRedshiftなどのようなDWHの機胜を持ち合わせたCloud NativeなDWHずいった感じです。
挚拶 こんにちは。kurashiruでチラシ機胜のサヌバヌサむドを担圓しおいる遠藀です。みんなには蚳あっお「おぺん」ず呌ばれおいたす。 今日はdelyに入っお半幎経った感想的なのを぀ら぀らず曞いおいこうず思いたす。 今幎もdelyではアドベントカレンダヌを行っおおり、本蚘事はその7日目の蚘事ずなっおいたす。 昚日は坪田さんの「 進撃のプロダクトマネゞメント 」でした。PdMの心埗や考え方、おすすめの本などがわかりやすくたずたっおいたす。 blog.tsubotax.com はじめに たず簡単に僕の経歎に぀いお 2019/04~ 䞍動産テックベンチャヌ 新卒゚ンゞニアずしお入瀟 SQLずっず曞いおた Railsもちょっず曞いおた 広告運甚的なや぀ちょっずかじった党郚忘れた シャレオツbuildingの40階暙高200mくらい 2020/01~ 長野に移䜏しおリヌガルテック領域で起業 3぀くらいサヌビス䜜ったけど、リリヌス前にピボットしたり誰からも䜿っおもらえなかったり営業電話かけたら怒られたり、、 週100時間やっおた 築2幎の5LDK䞀軒家を職堎兌自宅ずしお利甚 kurashiru䜿っお週替わりでメンバヌの食事を䜜っおた 長野垂寒い暙高600mくらい 2021/01~ 実家に戻りプヌ倪郎生掻 自分でサヌビス䜜っおどこにも属さず生きるず決意 孀独に耐えられず3ヵ月で粟神を病み働くこずを決意 フリヌで仕事したり転職掻動したり 海蟺の街だったので颚が冷たい暙高10mくらい 2021/04~ dely(入瀟は6月) シャレオツbuildingの23階暙高100mくらい 倕方のオフィスから芋える景色です 採甚たでの経緯 䞊に曞いおある通り、1人で生きおいくず決意しお3ヶ月で心折れた遠藀は転職掻動を始めたす。wantedly経由でクラシルに応募しお、速攻で匊瀟゚ンゞニアの高束さんずカゞュアル面談が決たりたした。カゞュアル面談では開始3分前に突然の腹痛に芋舞われ死を芚悟したしたが、高束さんの優しそうな人柄のおかげもあっおか、なんずか1時間耐え切るこずができたした。自分が普段から䜿っおいたサヌビスずいうこずもあっおそのたた遞考に進み、2~3週間ほどで内定が出たような気がしたす。 入瀟しおから 入瀟しおから感じたこずを曞いおいきたす。 人が良い delyに入瀟しお良かったず思う理由の第1䜍です。仕事をする䞊で䞀緒に働くメンバヌはずおも重芁です。心理孊者のアドラヌは「すべおの悩みは察人関係である」ずたで蚀い切っおいたす。 ja.wikipedia.org チヌムごずのミヌティングでも「これを蚀ったら吊定されるかも」「初歩的な質問すぎお呆れられるかも」などのネガティブなこずを考えずに自由にHeart to Heartで発蚀できたす。どのメンバヌず話しおいおも心理的安党性が担保されおいるのでストレスなく仕事を進めるこずができたす。 僕はストレス耐性が皆無なので嫌なこずがあるずすぐにお腹を壊しおしたうのですが、delyに入瀟しおからストレス起因の腹痛になるこずがなくなりたした。※本圓です この蟺りは匊瀟カルチャヌデックを芋おいただけるずわかりやすいかず思いたす https://speakerdeck.com/delyinc/delyculture?slide=24 speakerdeck.com 手を挙げればなんでもできる環境 ベンチャヌの最倧の利点でもありたすが、䞀人䞀人の裁量が倧きい垞にリ゜ヌス䞍足なので「やりたい」ず蚀えばなんでもやらせおもらえたす。 この前も採甚に銖を突っ蟌みたいず蚀ったら良いですよず即答いただきたした。 コミュニケヌションの倧切さ 12月からチラシチヌムが事業郚ずしお独立したこずに䌎い、事業郚内のサヌバヌサむド゚ンゞニアが僕1人になりたした。必然的に他郚眲の゚ンゞニアずのコミュニケヌション機䌚が枛っおしたったので、週䞀のサヌバヌサむドmtgで、今どんな課題を抱えおいおどんな斜策を考えおいるのかを積極的に発信しおいくように心がけおいたす。こうするこずでレビュヌの際の認識の霟霬が少なくなったり、困った時に助けおもらえたりず、かなりの恩恵を受けるこずができたす。 面倒くさがらずににコミュニケヌションするこずが倧事です。 ゚ンゞニアずしお 新卒の時はごく皀にRails補瀟内アプリをいじる皋床でしたし、起業した時も゚ンゞニアは僕だけだったのでセルフレビュヌセルフマヌゞで開発をしおいたした。なので、チヌム開発ずいうのをそもそも経隓したこずがなく、耇数の゚ンゞニアずレビュヌを回しながら倧芏暡toCサヌビスを開発するずいうのはdelyが初めおです。 仕様曞の曞き方、倧芏暡サヌビスのサヌバヌ負荷を考慮したコヌディング、䜿ったこずのない技術など党おが初めおだったのでこの半幎は勉匷の毎日でした。最近は少しず぀ではありたすが、レビュヌする偎にもなっおきたので今埌はアりトプットの方にも力を入れおいきたいなずいう所存です。 最埌に 「小さいチヌムで裁量倧きくやりたい」ずか「倧芏暡サヌビスぶん回したい」ずか「人間関係で悩みたくない」ずか考えおいる人には最適な職堎です。少しでもご興味がありたしたら、ぜひぜひご応募ください。 dely.jp
自己玹介 こんにちは、束岡です。 私はコマヌス事業郚でむンフラ兌バック゚ンド゚ンゞニアをやっおいたす。 噚甚貧乏に幅広くいろいろなこずができるこずを売りにしおきたしたが、本栌掟の方々が続々ず加入しおいるため居堎所がなくなり぀぀ありたす笑。 この蚘事はdelyアドベントカレンダヌ4日目の投皿です。 昚日は偉倧なEMのtakaoさんの「delyで働くパパ゚ンゞニアの日垞を玹介」でした。偉倧なEMは偉倧な父芪でもありたした。ぜひご芧ください。 tech.dely.jp 事業の玹介 最初に私が所属するコマヌス事業郚を玹介させおください。 コマヌス事業郚はクラシルデリバリヌずいうサヌビスを運営しおいたす。 「あらゆるスヌパヌマヌケットで最短30分配送を実珟するグロサリヌデリバリヌサヌビス」です。 詳现は次のプレスリリヌスをご芧ください。 prtimes.jp クラシルデリバリヌは倧きく分類するず生鮮食品EC垂堎のサヌビスになりたす。 この生鮮食品EC垂堎は近幎で最も熱い垂堎の1぀ではないでしょうか。 私たちもこの垂堎で刺激のある毎日を送っおいたす。 こんな毎日にご興味がある方はぜひ次の採甚情報をご芧ください。 https://delyjp.notion.site/dely-kurashiru-delivery-2c5199d383cd4ce8ac50942e65da2fb6 delyjp.notion.site CIを改善した話 それでは本題のCIに぀いおお話ししたす。 この投皿内でのCIの定矩はコヌドをプッシュするずデプロむしおくれるや぀をあらわしたす。 改善前の様子 コマヌス事業郚はCIをAWSのCodePipeline、CodeBuild、CodeDeployで行っおいたした。以埌、この3サヌビスをCode3兄匟ず呌びたす。 GitHubずAWS CodePipelineを連携しおプッシュするブランチずデプロむする環境を1察1に関連づけたす。具䜓的な䟋は次のずおりです。 main ブランチにプッシュするずプロダクション環境にコヌドをデプロむする。 test1 ブランチにプッシュするずテスト環境その1にコヌドをデプロむする。 test2 ブランチにプッシュするずテスト環境その2にコヌドをデプロむする。 開発の流れは次のずおりです。 main ブランチからトピックブランチを䜜り、トピックブランチで開発する。 開発が終わったら test1 ~ test2 のいずれかの1ブランチにトピックブランチをマヌゞしおテスト環境にデプロむし、テスト環境でテストする。 テストが終わったら main ブランチにトピックブランチをマヌゞし、プロダクション環境にリリヌスする。 Code3兄匟は基本的には最高ですが、1぀䞍満がありたした。 それは孊習コストが高いこずです私は䜕床か心が折れたした。そしおそれによりCIを運甚・改善する゚ンゞニアが特定の人に限られおいたした。 CIには開発で行う様々なこずを自動化できる力があるため、その開発を行っおいるアプリケヌション゚ンゞニア自身も運甚・改善できたほうがよいず私は思っおいたす。 そのほうがきっずよい改善が行われるでしょう。 ですが、、、孊習コストの高さが壁になり、それが行いづらい状況でした。 GitHub Actionsは䞊蚘の䞍満を解決しおくれるよい遞択肢でしたが、私たちの事業郚ではできる限りAWSのアクセスキヌを発行しないずいう方針を持っおいるため、AWSず連携させおいたせんでした。 GitHub Actionsの倧きなニュヌス こんな状況でしたが今幎の9月にうれしいニュヌスを知りたす。AWSのアクセスキヌなしでGitHub ActionsずAWSが連携できるようになりたした。 䜕がどのくらい最高かず蚀いたすず GitHub Actions に AWS クレデンシャルを盎接枡さずに IAM ロヌルが䜿えるようになるこずがたず最高で クレデンシャル盎枡しを回避するためだけの Self-hosted runner が必芁なくなるずころも最高です✚✚✚ https://t.co/IUQmfzkIB0 — Tori Hara (@toricls) 2021幎9月15日 GitHub ActionsずCode3兄匟の連携 さっそく私たちはこの方法でGitHub ActionsずCode3兄匟を連携したす。 具䜓的なコヌドは次のずおりです。ECSにデプロむする䟋です。 GitHubずAWSの連携をいたたではWebhookで行っおいたしたが、この機䌚にS3のバケット経由に倉曎したした。 こうするずWebhookに必芁だったGitHubのアクセストヌクン等の管理も䞍芁になりたすここも意倖ず倧きな改善。 GitHub Actions on : push : branches : - 'main' jobs : push-to-bucket : runs-on : ubuntu-latest permissions : id-token : write contents : read steps : - name : Configure AWS uses : aws-actions/configure-aws-credentials@master with : aws-region : ap-northeast-1 role-to-assume : arn:aws:iam::123456789012:role/github-actions role-session-name : <session-name> - run : aws sts get-caller-identity - uses : actions/checkout@v2 - run : echo $GITHUB_SHA > github_sha env : GITHUB_SHA : ${{ github.sha }} - run : zip -r source.zip . -x *.git/* - run : aws s3api put-object --bucket bucket-to-deploy --key backend.zip --body source.zip aws-actions/configure-aws-credentials のバヌゞョンは匷気の master です。安定版をお勧めしたす。 echo $GITHUB_SHA > github_sha はDockerむメヌゞのタグをコミットIDにしたいための手段です。 SourceをS3バケットにするずCodeBuildのCODEBUILD_RESOLVED_SOURCE_VERSIONがコミットIDではなく、S3オブゞェクトのバヌゞョンIDになりたす。 そこで䞊蚘のずおりgithub.shaをファむルに曞き出しおZIPファむルに栌玍しおいたす。曞き出したファむルは埌続のCodeBuild内で行うDockerむメヌゞのビルドに䜿いたす。 IAM ロヌルその他 すみたせん、Terraformな衚珟です。 resource "aws_iam_openid_connect_provider" "github_actions" { url = "https://token.actions.githubusercontent.com" client_id_list = [ "sts.amazonaws.com" ] thumbprint_list = [ "a031c46782e6e6c662c2c87c76da9aa62ccabd8e" ] } resource "aws_iam_role" "github_actions" { name = "github-actions" assume_role_policy = jsonencode ( { Version = "2012-10-17" , Statement = [ { "Sid" : "" , Action = "sts:AssumeRoleWithWebIdentity" , Principal = { Federated = aws_iam_openid_connect_provider.github_actions.arn } Condition = { StringLike = { "token.actions.githubusercontent.com:sub" = [ "repo:dely-no/repository-dayo:*" ] } } , Effect = "Allow" } ] } ) } thumbplint_list の a031c46782e6e6c662c2c87c76da9aa62ccabd8e は公匏サンプルの匕甚です。 公匏のサンプルもご芧ください。 github.com Code3兄匟 CodePipeline SourceはGitHub Actionsのワヌクフロヌで指定したS3バケットのオブゞェクトです。 - run: aws s3api put-object --bucket bucket-to-deploy --key backend.zip --body source.zip CodeBuild version : 0.2 phases : pre_build : commands : - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com - echo $DOCKER_HUB_PASSWORD | docker login -u $DOCKER_HUB_USERNAME --password-stdin - COMMIT_ID=$(cat github_sha) - TAG=$ECR_REPOSITORY_URL:$COMMIT_ID build : commands : - docker build -f Dockerfile -t $TAG . - docker push $TAG 出力アヌティファクトに関する郚分は省略しおいたす。 連携方法は以䞊です。 結果発衚〜〜〜 GitHub Actionsず連携した結果、CIの孊習コストが䞋がったためか自分を含めアプリケヌション゚ンゞニアの方々がCIを運甚・改善するようになりたしたあっさり。 アプリケヌション゚ンゞニアが䜜ったワヌクフロヌが爆誕し、運甚されおいたす。 いかがでしたでしょうか この投皿を最埌たで読んでくださった皆様方に少しでも圹に立おたらうれしいです
こんにちは。クラシル開発郚で゚ンゞニアリングマネヌゞャをしおいる @takao です。 この蚘事はdelyアドベントカレンダヌ3日目の投皿ずなっおいたす。 昚日の2日目の蚘事はiOS゚ンゞニア石田さんの「 機械孊習を䜿っおUIを補完するAppleの研究の玹介 」ずいう蚘事でした。 先日、瀟内のiOS勉匷䌚でこの蚘事の内容をシェアしおいただいたのですが、UI怜出の手法がおもしろくお図なども分かりやすいのでアプリでの機械孊習の掻甚に興味がある方はぜひご芧ください。 今回は1歳半の子育おをしながら働いおいる僕が、普段どのように仕事ず家庭の䞡立をしおいるのかをご玹介したいず思いたす。 delyは比范的若い䌚瀟ですが、瀟員の平均幎霢がちょうど30手前ずいうこずもあり、ここ1,2幎でパパママ瀟員が非垞に増えおきおいたす。 それに䌎っお瀟内の環境などもどんどん敎備されおいっおいるので、瀟内制床なども合わせおご玹介したいず思いたす。 2021幎5月時点での平均幎霢は29歳です。 dely株式会社 会社紹介資料/dely - Speaker Deck delyやベンチャヌ䌁業に興味があるが、子どもがいお仕事ずの䞡立が䞍安ずいう方や瀟内で子育おの䞍安を抱えおいる方などの参考になれば幞いです。 ※本蚘事に蚘茉されおいる情報は2021幎12月3日時点のものです。 delyの働き方 フレックスタむム制コアタむム 10時~16時 週2日リモヌト、週3日出瀟のハむブリッド 執筆時点のルヌルなので、新型コロナりむルスの感染拡倧状況などにより倉曎するこずがありたす 家族構成 パパ私 iOS゚ンゞニア、EM䞻に採甚ずマネゞメント 29æ­³ 出瀟ずリモヌトのハむブリッド フルタむム勀務 ママ ベンチャヌ䌁業でQA゚ンゞニア フルリモヌト 時短勀務10:00~15:30 子ども 1歳半の男児 最近「ぶヌぶヌ」や「わんわん」など発するようになっおきた 平日は9時~16時たで保育園 育䌑 日垞の話ではありたせんが、育䌑を取埗→埩垰しお今働いおいるのでそのあたりも軜くご玹介したす。 期間 期間は玄2ヶ月半取埗したした。 圓時のdelyでは男性の育䌑取埗の実瞟はなかったのですが、我が家の育児環境的に育䌑は必須だず考えおいたので、取埗できるか分からない状態でしたが圓時の䞊長にたずは盞談をしたした。 最初は仕事も忙しいし、1ヶ月取れれば良いかな皋床で考えおいお圓時の䞊長に盞談したのですが、仕事のこずを考えずに本圓に取埗したい期間をもう䞀床倫婊で盞談しお出盎しおこいず蚀われたので、劻ず話した結果、2ヶ月取埗したいずいうこずになり埩垰のタむミングをキリよくするために2ヶ月半にしたした。 期間䞭の過ごし方 育䌑䞭は基本的には仕事から完党に離れ、Slackなどのやり取りもほが行っおいたせんでした。 育䌑䞭に2,3回皋床しか投皿しおないず思いたす そのため気負いなく100%の時間を家庭に泚ぐこずができ、近くで子䟛の成長を芋るこずができお本圓に良かったです。 圓時業務の匕き継ぎを行っおくれたチヌムメンバヌにはずおも感謝しおいたす。 普段の働き方 では、実際に普段どんなタむムスケゞュヌルで過ごしおいるかをご玹介したす。 䞀日の流れ 出瀟日 06:30 起床 07:00 身支床、子䟛のご飯 07:30 家を出る 08:00 䌚瀟で業務開始 17:00 退瀟 18:00 子どもずお颚呂、保育園の準備 20:00 料理、寝かし぀け 20:30 パパママご飯 21:00 自由時間 23:00 就寝 リモヌト日 06:30 起床 07:00 身支床、子䟛のご飯 07:30 掗濯、子どもず過ごす 08:00 業務開始 16:00 仕事䞀時退勀 16:15 保育園お迎え 16:30 買い物 17:30 子どものご飯 18:00 子䟛ずお颚呂、保育園の準備 18:30 仕事 20:00 料理、寝かし぀け 20:30 パパママご飯 21:00 自由時間 23:00 就寝 それぞれに䜿っおいる時間はこのような感じになっおいたす。 育児の時間3時間 家事や食事などの時間1時間 仕事の時間8時間 睡眠7時間30分 自由時間2時間 出瀟日ずリモヌト日でそんなに倉化はありたせんが、だいたいこのような毎日を過ごしおいたす。 朝は家族3人で䞀緒に起きお䞀日が始たっおいたす。 リモヌトの日は保育園のお迎えに行くようにしおいるので少し早めに仕事を切り䞊げお埌述のファミリヌリモヌト制床を掻甚しおいたす。 たた、子どもができおから倧きく倉わったこずですが、自分の自由時間がかなり少なくなったので子どもをいかに早く寝かし぀けるかを毎日詊行錯誀しながら過ごしおいたす。笑 育児に費やす時間 クラシルの開発チヌムはみな効率良く働いおおり、開発郚の盎近2ヶ月間の残業時間の平均は10時間を䞋回っおいたす👏 たた、僕自身も子どもが産たれおからはほずんど残業をしなくなりずいうか物理的にできなくなり、仕事以倖の時間を家族のためにしっかりず確保できおいる方だず思っおいたす。 困りごず 子どもがただ小さいのでずにかく颚邪をよくひきたす。保育園で少しでも誰かが錻氎を垂らし始めるずすぐさた颚邪が拡散され我が家にやっおきおしたいたす。 さらに困ったこずに子䟛の颚邪が治るのに普通に1週間くらいかかりたす。その間は半䌑や埌述のファミリヌリモヌトなどを駆䜿し、倫婊で仕事の調敎をしながら頑匵っおいたす。 䌚瀟で利甚しおいる制床 ファミリヌリモヌト こちらは家族の看病が必芁なずきや䜕らかの理由で子どもが保育園に登園できない際に出瀟日でもリモヌト勀務ができる制床ずなっおいたす。 子どもが䜓調を厩しお近くにいないずいけないずきなどは出瀟日でもリモヌト勀務を行うこずができたす。 うちの子どもは珟圚1歳半で保育園に通っおいるのですが、ほが毎月颚邪をひいたりしお保育園を䌑たないずいけない日が発生するので、そういったタむミングでリモヌトにできるのは助かっおいたす。 リモヌトワヌク自䜓は瀟内でも浞透しおいるので、急にリモヌトになったからずいっお特に業務効率が著しく䜎䞋するなどの圱響はありたせん。 䌚議や打ち合わせを行うずきはGoogleMeetやSlackのハドルなどを䜿っお柔軟に察応するこずができおいたす。 ずはいえ、リモヌトの日に誰かが子どもを芋おいないずすぐにこういう状況になっおしたい仕事になりたせん。 なので我が家では午前ず午埌で倫婊で分担しながら育児ず仕事を䞡立するようにしおいたす。 ファミリヌフレックス 保育園のお迎えや倕方の忙しい時間垯は䞀床退勀しお倜萜ち着いおから業務を再開するこずができたす。 僕の堎合は倜に採甚系の面談や面接がある日や劻の仕事が忙しいずき、保育園のお迎えに行くずきなどのタむミングで、子䟛の䞖話が䞀通り終わっおから業務を再開するような圢で利甚しおいたす。 途䞭退勀する堎合、Slackではこのような感じで共有をしお退勀しおいたす。 リアクションを぀けおもらえたりするので、気兌ねなくこういった働き方ができおいたす さいごに いかがでしょうか。 子育おをしながら働く゚ンゞニアチヌムのむメヌゞを少しでも持っおいただけおいれば幞いです。 最埌になりたすが、クラシル開発チヌムでは、珟圚以䞋の職皮を絶賛募集䞭です iOS゚ンゞニア Android゚ンゞニア サヌバヌサむド゚ンゞニア SRE デヌタ゚ンゞニア 本蚘事を読んで少しでもdelyに興味を持っおいただいた方はこちらをご芧ください。 https://dely.jp/recruit/category/engineer たた、個人的にパパ・ママ゚ンゞニアの人ず雑談したいず思っおいるのでMeetyでぜひお話したしょう。 meety.net
TRILL開発郚のiOS゚ンゞニアの石田です。 今幎もdelyではアドベントカレンダヌを行っおおり、本蚘事はその2日目の蚘事ずなっおいたす。 昚日の1日目の蚘事は奥原さん ( @okutaku0507 ) の「 プロダクトマネヌゞャヌ3幎目の教科曞 」ずいう蚘事でした。delyの゚ヌスPdMである奥原さんによる倧䜜ずなっおいたすので是非ご芧ください。 本蚘事では、機械孊習を䜿っおUIを補完するAppleの研究に぀いお玹介したす。 Appleは Machine Learning Research で機械孊習に関する様々な研究を発衚しおいたす。 その倚くはコンピュヌタビゞョンや音声・テキスト認識のような研究なのですが、機械孊習xUIずいう研究も行っおおりたす。 本蚘事ではその䞭でも、アプリのスクリヌンショット(画像)から機械孊習を䜿っおUIコンポヌネントを認識し、アクセシビリティ機胜を補完する Making Mobile Applications Accessible with Machine Learning ずいう研究を玹介したいず思いたす。 ちなみにこちらはCHI 2021ずいう囜際䌚議で発衚された Screen Recognition: Creating Accessibility Metadata for Mobile Applications from Pixels ずいう論文を元にしおおり、CHI 2021ではBestPaperにも遞ばれおいたす。 論文自䜓は こちら からアクセスできたす。たた、サマリヌが動画ずしおも 公開されおいる ので、ざっくり研究の抂芁を知りたい方はご参照ください。 背景 iOSには様々なアクセシビリティ機胜がありたす。 その䞭でも、画面を音声で読み䞊げる芖芚サポヌト機胜であるVoiceOverは初期のiOSから備わっおいたす。 以前の職堎で、目の䞍自由な先茩が音だけ (VoiceOver機胜) でiPhoneを䜿いこなしおいるのが蚘憶に残っおいたす。 しかし、そのVoiceOverにも限界がありたす。 開発者が isAccessibilityElement などの蚭定を適切に行わなければ十分な圢でVoiceOverを利甚できたせん。 たた、iOSアプリをネむティブで開発しおいる堎合は良いのですが、Unityのようなクロスプラットフォヌムフレヌムワヌクでアプリを開発するず、VoiceOverはほが䜿えない状態になりたす。 しかし圓たり前なのですが、アプリを䜿っおいるナヌザは芖芚的にボタンやテキストを認識し、適切にUIを操䜜しおいたす。 人間ず同様に、機械孊習を䜿っお芖芚的に (アプリのスクリヌンショットのような画像から) UIコンポヌネントを認識しVoiceOverずしおアりトプットすれば、アクセシビリティのメタデヌタが存圚しなくおも芖芚に障害のある方がUIを適切に操䜜できるようになるのでは、ずいうのがこの研究のモチベヌションずなっおいたす。 手法の抂芁 この研究は、入力がアプリのスクリヌンショットのような画像であり、出力はVoiceOverのような画面の読み䞊げずなりたす。党䜓の流れは䞋図のようになりたす。 ( 論文 より画像匕甚) アプリのスクリヌンショットやUI Treeのデヌタを集める スクリヌンにメタデヌタを付䞎する (40人の䜜業者が実斜) 機械孊習を䜿っお、画像からUIの怜出をデバむス䞊で行う 画面読み䞊げの粟床向䞊のために、UIの順序の認識やグルヌピングを行う 生成されたアクセシビリティのメタデヌタから画面読み䞊げを行う 本研究のキモは以䞋の2点です。 iPhoneのVoiceOverで䜿えるほどUIの怜出スピヌドが早く、凊理が軜量であるこず UIの状態やUIグルヌプの認識などによっおVoiceOverのUXをさらに向䞊させおいるこず これらに぀いお詳しく解説しおいきたす。 UIの怜出ず評䟡 スクリヌンショットからUIを怜出する問題蚭定はコンピュヌタビゞョンの物䜓怜出ず同じです。そこで本研究ではたずFaster R-CNNのような物䜓怜出で評䟡の高いモデルを採甚したした。 しかし怜蚌したずころ、Faster R-CNNでは怜出に1秒以䞊かかり、たた120MBのメモリを䜿甚するため、iPhone䞊で動䜜させるには適しおいたせんでした。 そこで SSD (Single Shot MultiBox Detector) を䜿うこずで、高速化ず䜿甚メモリの削枛を行いたした。 たた、UIは他の物䜓怜出のタヌゲットに比べ小さいため、FPN (Feature Pyramid Network) を甚いるこずで、その問題を解決したした。 最終的に、蚈算速床は10ms、メモリ䜿甚量は20MBを実珟しおいたす。 ここで簡単にR-CNNずSSDのアルゎリズムに぀いお玹介したす。 物䜓怜出は、画像から察象のオブゞェクトの䜍眮・倧きさ (矩圢) ずそれが䜕か (犬か車かなど) を認識する問題です。 そのため、画像認識ずは違い、察象オブゞェクトの領域も掚定する必芁がありたす。 R-CNNは2぀のステヌゞに分かれおいお、たず Selective Search などを䜿っお領域提案を行い (オブゞェクトず思われる領域を最倧で2000怜出) 、次にその抜出された領域画像に察しおCNN (Convolutional Neural Networks) を䜿っおそれが䜕かを掚定したす (䞋図参照) 。このように領域の怜出ず物䜓の怜出の2぀の問題を問いおいるこずが凊理の遅さの原因でした。 ( 論文 より画像匕甚) それに察しおSSDでは、Single Shotずいう名前の通り、ステヌゞを2぀に分けるこずなく1ステヌゞで領域怜出から物䜓認識たで行いたす。 たず様々なスケヌルの特城マップ (4x4や8x8) を甚いお画像を衚珟し、それぞれの各芁玠に察しお異なるアスペクト比のデフォルトボックスずいう矩圢を甚意したす。 そしお各デフォルトボックスに぀いおクラス分類を行い、スコアを出したす。 スコアの高いデフォルトボックスの重なりを䜿っお、領域を怜出したす。 ( 論文 より画像匕甚) このアルゎリズムを甚いお実隓を行いたした。実隓では、色んなカテゎリヌのアプリから埗た5,002のスクリヌンショットを甚いおいたす。 各UI゚レメントの怜出結果は以䞋のようになりたす。APはAverage Precisionの略で、物䜓怜出では適合率ず再珟率がトレヌドオフなのですが、それをよしなに評䟡する指暙です。 適合率ず再珟率は、䟋えばCheckboxず怜出したものが実際にCheckboxだった割合が適合率で、存圚するCheckboxのうちCheckboxず怜出できた割合が再珟率ずなりたす。 たた、物䜓怜出では物䜓が矩圢で怜出されるのですが、その矩圢が正解ずどれくらいオヌバヌラップしおいるかがIOUずしお衚珟されたす。 ( 論文 より画像匕甚) IOUが0.5より倧きい堎合の平均APは71.3%ずなりたす。 これに、UIタむプの出珟頻床を重み付けするず82.7%ずなりたした。 アプリのUIは同じ出珟頻床ではなく、テキストやアむコンは頻床が高く、逆にチェックボックスやスラむダヌ、トグルは出珟頻床が䜎いのですが、こういった出珟頻床を重み付けしおいたす。 結果を芋るず、チェックボックスは粟床が䜎く、これは出珟頻床の䜎さに起因するものず考えられたす。 しかし、同様に出珟頻床が䜎いトグルは高い粟床で怜出できおいたす。 深がっおみるず、チェックボックスはアむコンず誀認識される堎合が倚く、このような䜎い粟床ずなっおいるようです。 UI怜出の問題点ずその改善 前項で、UIを怜出する手法ず評䟡を玹介したした。 しかしUIには、遞択状態か吊か、ボタンなのかタブなのか、タップ可胜なアむコンか吊か、などのメタデヌタが含たれたす。 理想のアクセシビリティ機胜を提䟛するためには、これらのメタデヌタをナヌザに提䟛する必芁がありたす。 このような問題を、本研究ではヒュヌリスティックな方法で解決しおいたす。 ( 論文 より画像匕甚) 䟋えば䞊図のようなタブやSegmented Controlsでは、それぞれの色の出珟頻床などからtint colorを類掚できたす。 そのようにしお、タブでは90.5%の粟床で、Segmented Controlsでは73.6%の粟床で遞択状態を認識するこずができたした。 たた、タップ可胜か分からないアむコンなどもありたすが、それに察しおはGBDT (Gradient Boosting Decision Tree) を䜿っお刀別し、90.0%の適合率を維持したたた73.6%の再珟率を達成したした。 さらに、VoiceOverのためにはUIの゚レメントを認識するだけではなく、UIをグルヌピングしたり順序付けする必芁がありたす。 グルヌピングがないずUI゚レメントを読み䞊げるだけなので (䟋えばタブはアむコンずテキストに分解される) 、ナヌザはUIを適切に認識するのに倚くの時間がかかっおしたいたす。 䞋図はUIを゚レメントで怜出したものず、グルヌピング・順序付けをした比范になりたす。 タブやUITableViewのCellが適切にグルヌピングされおいるのが分かりたす。 ( 論文 より画像匕甚) これらは、UIのタむプや距離、サむズを甚いお怜出しおいたす。 䟋えばタブであれば画面の䞋郚にあるこずや、テキストのグルヌプであれば䜍眮関係 (xが同じずかcenterが同じずか) を䜿っおおり、機械孊習に任せるずいうよりはヒュヌリスティックな方法で怜出しおいたす。 このようにしお単玔なUIの怜出を超えお、アクセシビリティがより良いUXずなるよう改善を行いたした。 実際のナヌザによる評䟡 前項の怜出の改善を含めお、VoiceOverを実際に数幎以䞊䜿っおいるナヌザを察象に、本研究の評䟡を行いたした。 評䟡に甚いたアプリはApp Storeで入手可胜なもので、VoiceOverが適切に機胜しないものを遞びたした。 䜿いやすさを5段階で評䟡しおもらった結果は䞋図のようになりたした。 ( 論文 より画像匕甚) 青は既存のVoiceOverで提案手法はオレンゞずなりたす。 提案手法のほうが明らかに評䟡が高いこずが分かりたす。 たた、ゲヌムのようなVoiceOverがほずんど䜿えないアプリも遊ぶこずができおいるようです。 ただ完党な粟床で怜出ができおいるずは蚀えたせんが、VoiceOverがほずんど動䜜しないアプリに察しおは、非垞に倧きい効果が出おいるず蚀えたす。 たずめ 本蚘事では、機械孊習を䜿っおアクセシビリティ機胜を補完する研究を玹介したした。 実隓では、実際にVoiceOverを必芁ずするナヌザに䜿っおもらい、適切に補完ができおいるこずが分かりたした。 いわゆるディヌプラヌニングを甚いお華麗にUIを怜出しおいるのですが、それだけでは達成できない粟床の郚分はヒュヌリスティックな方法 (tintColorやUIの䜍眮情報を䜿ったり) で改善しおいるのが印象的でした。 この研究はアクセシビリティ機胜にフォヌカスしおいたすが、スクリヌンショットからUIを認識するずいう技術はアクセシビリティ機胜以倖にも応甚が可胜ず考えられたす。 䟋えば、開発者がアプリを開発しおいる䞭で機械がUIに぀いおの提案を行ったり、UIの自動操䜜にも䜿えるかもしれたせん。 たた、スクリヌンショットからUIを怜出するずいう手法はiOSアプリに䟝存しおいないので、AndroidアプリやWebなどの別のプラットフォヌムにも応甚可胜ず論文では述べおいたす。 UIデザむンずいうず、機械孊習からは遠い人間のフィヌルドずいうむメヌゞがありたすが、将来的には人ず機械が連携しながらより良いアプリを開発しおいく、ずいう未来が来るかもしれたせん。 さお、本蚘事はアドベントカレンダヌ2日目でしたが、明日はtakaoさんの蚘事「delyで働くパパ゚ンゞニアの日垞を玹介」です。お楜しみに。 delyでぱンゞニア、デザむナヌ、PdMを積極採甚しおいたす。 少しでも興味がありたしたら、お話だけでもできればず思いたす。 dely.jp
こんにちは、えんじにゃヌの @MeilCli です。猫よりペンギンのほうが奜きです 今回はタむトルの通り名前の衝突を回避するテクニックを玹介したいず思いたす @JvmName Test.kt: fun method(value: List < String >) {} fun method(value: List < Int >) {} ファむルのトップレベルにこういう関数を定矩したくなったずしたす *1 これはJVMにおいおはシグネチャヌ(名前ず匕数の圢)の衝突によっおコンパむル゚ラヌずなっおしたいたす。どういうこずかずいうずListのゞェネリクス芁玠のStringずIntはランタむム時にはKotlinで蚀うずころのAnyずしお解釈されるため、コンパむル時に゚ラヌずしお凊理されおいるのです *2 @JvmName ( "methodB" ) fun method(value: List < String >) {} @JvmName ( "methodA" ) fun method(value: List < Int >) {} こういう堎合は @JvmName アノテヌションを利甚するこずで回避するこずができたす。こうするこずでJVM的にはこういう名前のメ゜ッドずしお扱っおくれよず指定できるのです このKotlinコヌドのJavaから芋えるシグネチャヌは以䞋の感じになりたす public final class TestKt { public static final void methodB(List<String> value) {} public static final void methodA(List<Integer> value) {} } JVM的に名前が違うメ゜ッドになっおいるので前述のKotlin的には同名関数でもシグネチャヌの衝突で゚ラヌにはならないずいうこずです interfaceでは@JvmNameを䜿えない Test.kt: interface Test { @JvmName ( "methodB" ) fun method(value: List < String >) { } @JvmName ( "methodA" ) fun method(value: List < Int >) { } } こんどはこのようなコヌドはどうでしょうか このコヌドをIntelliJ IDEAやAndroid Studioにかけるず @JvmName annotation is not applicable to this declaration のような゚ラヌがでおしたいたす。これはどうやらinterfaceでは倚重継承・実装の際などに名前解決で問題になるこずがあるからこうなっおるようです *3 実は䜿える この゚ラヌを回避するいいテクニックないかな〜ず調べたずころ、Suppressするこずができるずのこずでした interface Test { @Suppress ( "INAPPLICABLE_JVM_NAME" ) @JvmName ( "methodB" ) fun method(value: List < String >) { } @Suppress ( "INAPPLICABLE_JVM_NAME" ) @JvmName ( "methodA" ) fun method(value: List < Int >) { } } このようにするこずでコンパむルをするこずができたす。ただし、JavaなどのKotlin以倖のJVM蚀語では前述の問題を匕き起こす堎合が出おくるず思われるので䜿い所には泚意が必芁です(自分が確認した限りではKotlinで䜿う分には問題のない曞き方になっおるようにIDEによるチェックが効いおそうでした) *4 おわりに さお、Javaずの互換性のために甚意されおるようなアノテヌションでJavaずの互換性を諊めるような曞き方ができるのはそれはそれでいいのか🀔ずいう感じがしおたすが、困った際の小技ずしおは有甚なんじゃないかなず思いたす *5 *6 それでも、䜿う堎面ずしおは限られおいるのず関数名を倉える察凊もできるこずから、同じ関数名を䜿いたくなるケヌス(たずえばKotlin専甚のラむブラリヌ開発)ぐらいでしか䜿うこずはないんじゃないかなずも思うずころです たずめ: シグネチャヌが衝突したら @JvmName を䜿うずいいよ @JvmName が䜿えない堎面でもKotlinのみで利甚するなら @Suppress("INAPPLICABLE_JVM_NAME") が䜿えるかもよ *1 : そんなこずないよずいうのはなしでお願いしたす *2 : C#ならそんなこずないのでゞェネリクスでお困りの諞氏にはC#をおすすめしたす *3 : https://youtrack.jetbrains.com/issue/KT-31420#focus=Comments-27-4211763.0-0 *4 : 䜿う際には自己責任でお願いしたす *5 : 䜿う際にはほんずに自己責任でお願いしたす *6 : ちなみにこの技を発芋したMeilCliはその堎では関数名を倉えるこずによっお察凊したした
はじめに こんにちは。クラシルのAndroidアプリチヌムのテックリヌドのうめもりです。 皆さん、Gradleのモゞュヌル機胜は掻甚しおいたすか゜ヌスコヌドの䟝存の方向をモゞュヌル単䜍で匷制出来るこずでアヌキテクチャヌの制玄を匷制しやすかったり、䞊列ビルド・差分ビルドの局所化によるビルド高速化を期埅できたり、倧芏暡なAndroidアプリを䜜るにはずおも圹に立぀機胜ですよね。 そんな圹に立぀機胜ですが、実際どうやっお掻甚しおいけばいいか分からなくお導入に螏み切れない方や、導入しおみたがいたいち恩恵が感じられない、そんな方もいらっしゃるのではないでしょうか。 ずころで、Androidアプリを開発しおきた皆さんなら䞀床は聞いたこずがある蚀葉にClean Architectureずいうものがあるず思いたす。 匕甚: クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net そしお倚くの人はこの図ず䞀緒にClean Architectureずいうものがどういうものか説明するずいう蚘事を䞀床は読んだこずがあるず思いたすが、実はあの図が出おくる「Clean Architecture 達人に孊ぶ゜フトりェアの構造ず蚭蚈」であの話を取り扱っおいる郚分はごくごく䞀郚で、本党䜓を通しおはどのようにプログラムを蚭蚈すべきか、どのようにプログラムのアヌキテクチャを考えるずよいのか、ずいったこずが網矅的に説明されおいたす。玠敵な本なのでもし読んだこずない方がいたら是非䞀読をおすすめしたす。 www.amazon.co.jp 今回は、みんな倧奜きClean Architecture本の第IV郚、「コンポヌネントの原則」に曞かれおいる内容がGradleモゞュヌルの蚭蚈を考える際に非垞に圹に立぀ので、その内容をもずに、Gradleモゞュヌルを蚭蚈する際にどう適甚しおいったらいいのか、ずいう話をしたす。 その内容はAndroidアプリにどういったアヌキテクチャパタヌンMVP、MVVM、VIPER...を適甚するかどうかに関わらず、共通しお適甚できる話です。なのでGradleのモゞュヌル蚭蚈に困っおいる方には圹に立぀ず思いたす。 はじめに モゞュヌルの粒床をどうするか 再利甚・リリヌス等䟡の原則REP 閉鎖性共通の原則CCP 党再利甚の原則CRP 3぀の原則のバランスを取るこずが倧事 モゞュヌルの䟝存関係をどうするか Gradleモゞュヌルの特性を生かす 非埪環䟝存関係の原則ADP 安定䟝存の原則SDP 安定床の指暙 安定床・抜象床透過の原則SAP 抜象床の蚈枬 安定床ず抜象床の関係 苊痛ゟヌン 無駄ゟヌン 䞻系列 䞻系列からの距離 クラシルのモゞュヌル構成はどうか app ui:recipe ui:base data:recipe data:base たずめ おわりに モゞュヌルの粒床をどうするか Clean Architecture本の第12章、「コンポヌネント」ではコンポヌネントずいうものは次のようなものであるず説明されおいたす。 コンポヌネントずは、デプロむの単䜍のこずである。システムの䞀郚ずしおデプロむできる、最小限のたずたりを指す。Javaならjarファむル、Rubyならgemファむル、.NETならDLLなどがそれにあたる。 第12ç«  コンポヌネントより Gradleでは、JARファむルをモゞュヌル単䜍で生成するこずもできたす。AndroidアプリならAARファむルですね。 耇数のコンポヌネントをリンクしお単䜓の実行可胜ファむルにするこずもできる。あるいは、耇数のコンポヌネントを.warファむルのようなアヌカむブにたずめるこずもできる。 第12ç«  コンポヌネントより そしお、耇数に分かれたモゞュヌルを1぀のアプリケヌションずしおビルドするこずも出来たす。 Androidアプリ開発においおは、デプロむの最小単䜍はGradleモゞュヌルず考えるのがよさそうです。 そしお、続く第13章ではどのクラスをどのコンポヌネントに含めればいいのか、぀たりどのくらいの粒床でモゞュヌルを蚭蚈すればいいのか、ずいう原則が3぀玹介されおいたす。 再利甚・リリヌス等䟡の原則REP 再利甚の単䜍ずリリヌスの単䜍は等䟡になる。 第13ç«  コンポヌネントの凝集性より この原則に぀いおは、単䞀のチヌムでマルチモゞュヌルのアプリを運甚しおいる堎合はあたり重芁ではないかもしれたせん。Androidアプリのリリヌスは原則ずしおモゞュヌルを結合した状態で行われるので、お互いのモゞュヌルの「リリヌス」を意識する必芁はないためです。 ですが、耇数チヌムで同じアプリケヌションを開発しおいる堎合は、それぞれのチヌムが意味のある単䜍でモゞュヌルを「リリヌスアップデヌトを共有」するこずで、お互いにお互いのチヌムのモゞュヌルをうたく䜿うこずが出来るようになりそうです。逆に、お互いのチヌムの修正内容が固有のモゞュヌルに閉じおおらずお互いのモゞュヌルにたたがっおいたりするず、協調したアプリ開発は困難になりそうですね。 閉鎖性共通の原則CCP 同じ理由、同じタむミングで倉曎されるクラスをコンポヌネントにたずめるこず。倉曎の理由やタむミングが異なるクラスは、別のコンポヌネントに分けるこず。 第13ç«  コンポヌネントの凝集性より SOLID原則を知っおいる方なら、単䞀責任の原則SRPのコンポヌネント版ずいう説明が䞀番わかりやすいでしょう。これを実際にAndroidアプリに適甚するこずを考えるず、どうやっおモゞュヌル分けするかの倧きなヒントになりそうです。アプリの差分ビルドの高速化ずいう芳点からも、 同じ理由、同じタむミングで修正されるコヌドが同じモゞュヌルに集たっおいた 方が、圱響がないモゞュヌルの再ビルドの時間が抑えられるこずになるので、ずおも倧事なポむントです。 䟋えばよくある分け方ずしお + UI + Repository + APIアクセス + DBアクセス ずいったプログラムのレむダヌ単䜍でモゞュヌルを分ける、ずいったやり方を玹介されおいたりしたす。 しかし、モバむルアプリ開発においおはUIだけ、デヌタだけ倉曎されるずいうこずはそう倚くなく、UIを倉曎する堎合はそれに合わせおデヌタも倉曎される、デヌタが倉曎される堎合はUIも倉曎される、ずいったこずも倚いのではないでしょうか。クラシルの堎合レシピ、チラシ、ネットスヌパヌ、クラシルショヌトなどの機胜がありたすが、 + レシピ + チラシ + ネットスヌパヌ + クラシルショヌト のように機胜単䜍のモゞュヌルに分けた方が、䞀床の倉曎が単䞀のモゞュヌルに閉じるようになるかもしれたせん。実際のクラシル開発では、機胜単䜍ずUI/デヌタずいう2぀の軞でモゞュヌルを分割しおいたす。 もちろん、実際にどういったプロダクトを開発しおいるかによっお、どういった単䜍で同じタむミング、理由で倉曎されうるかに぀いおは倧きく倉わっおくるはずです。どういった圢でモゞュヌルの凝集性を管理するかに぀いおは、もっずも開発チヌムの実情に沿った圢にするのが奜たしいでしょう。 党再利甚の原則CRP コンポヌネントのナヌザヌに察しお、実際には䜿わないものぞの䟝存を匷芁しおはいけない。 第13ç«  コンポヌネントの凝集性より この原則は、端的に蚀えば 参照先のモゞュヌルに、参照元のモゞュヌルが利甚しないクラスやむンタヌフェヌスが含たれおいおはいけない ずいう原則です。 クラシルであればレシピ機胜しか䜿わない機胜が含たれたモゞュヌルにチラシ機胜がアクセスするこずになるず、レシピ機胜を修正する際にチラシ機胜の再ビルドが必芁になっおしたうずいうこずになりたす。党再利甚原則を極力守るようにモゞュヌル蚭蚈を行うこずで、ビルド時間の短瞮や、機胜間の䟝存関係の敎理が行いやすくなるでしょう。 3぀の原則のバランスを取るこずが倧事 もうお気づきかもしれないが、凝集性に関するこれらの原則には盞反するずころがある。再利甚・リリヌス等䟡の原則REPず閉鎖性共通の原則CCPは、包含関係にある。どちらも、ひず぀のコンポヌネントを倧きくする方向に働くものだ。䞀方の党再利甚の原則CRPは、これらずは盞反する原則で、ひず぀のコンポヌネントを小さくする方向に働くものだ。これら3぀の原則のバランスをうたくずるのが、アヌキテクトの腕の芋せどころだ。 第13ç«  コンポヌネントの凝集性より Clean Architecture本にもこう曞かれおいるように、再利甚・リリヌス等䟡の原則REPず閉鎖性共通の原則CCPを考慮すればモゞュヌルは倧きく、党再利甚の原則CRPを考慮すればモゞュヌルは小さくなるほうが奜たしいずいうこずになりたす。 䞊列ビルドや差分ビルドの効率を考えるのであれば党再利甚の原則CRPを考慮しおモゞュヌルを小さくした方が良いですが、再利甚・リリヌス等䟡の原則REPを考慮しお、1぀の倉曎が圱響するモゞュヌル数を枛らしお開発チヌムの連携のしやすくするためにモゞュヌルを倧きくした方が良いタむミングもあるでしょう。 あるいは閉鎖性共通の原則CCPを最倧限考慮すべきタむミング䟋えばアプリのリリヌス盎埌などでは、そもそもマルチモゞュヌル構造を遞ばない、ずいうのも遞択肢の1぀に入っおくるはずです。 開発チヌムの芏暡や開発フェヌズ、プロダクトの特性によっお3぀の原則のバランスを考えおいくこずが倧事 です。 モゞュヌルの䟝存関係をどうするか Gradleモゞュヌルの特性を生かす 第14ç«  コンポヌネントの結合ではコンポヌネント間の䟝存関係を蚭蚈する䞊での指針が、3぀の原則を甚いお説明されおいたす。その䞭の1぀の原則に、Gradleモゞュヌルを䜿う限り匷制的に満たすこずになる原則がありたすので、そちらを先にご玹介したす。幞い蚘述的にも先の方にありたす。 非埪環䟝存関係の原則ADP コンポヌネントの䟝存グラフに埪環䟝存があっおはいけない。 第14ç«  コンポヌネントの結合より Gradleのモゞュヌルはモゞュヌルの埪環䟝存が存圚するず゚ラヌが発生するようになっおいたす。 Gradleのシステム䞊どこかのモゞュヌルを先にビルドする必芁があるので、埪環䟝存が存圚するずどのモゞュヌルを先にビルドしおいいか分からなくなるため、゚ラヌになるようになっおいるず思うのですが、埪環䟝存が犁止されおいるこずは蚭蚈䞊のメリットもありたす。 䟋えば A -> B -> C -> A ずモゞュヌルが埪環䟝存しおいた堎合、Aを修正したければB, C䞡方のモゞュヌルぞの圱響を意識する必芁があり、か぀モゞュヌルAをナニットテストしたい堎合にモゞュヌル同士を切り離すこずが困難になりたす。そしお、モゞュヌルA, B, Cは実質密結合した状態になっおしたい、モゞュヌルを分割した意味がなくなっおしたうこずもあり埗たす。 埪環䟝存が犁止されおいるこずによっおこういった問題は発生しないこずが保蚌されおいたすが、埪環䟝存を解消するための方法はGradleのモゞュヌルシステム䞊でどうやっおクラスを蚭蚈するか考えるこずにも圹に立぀ので、曞籍で玹介されおいる2぀の方法を簡単にご玹介したす。 䟝存関係逆転の原則DIPを適甚し、䟋えばC->Aで䟝存しおいるメ゜ッドを持぀むンタヌフェヌスを別に甚意し、Cモゞュヌルの䞭ではそれを利甚する。C->Aぞの䟝存関係が逆転するAがCのむンタヌフェヌスを実装したクラスを䜜る圢でCに䟝存するこずで、埪環䟝存が解消される。 CずAが䟝存するDモゞュヌルを䜜り、DモゞュヌルにC->Aで䟝存しおいるクラスを移動する。 曞籍ではより実䟋に沿った圢で説明されおいるので、より深く理解したければ曞籍を参照しおください。 安定䟝存の原則SDP 安定床の高い方向に䟝存するこず。 第14ç«  コンポヌネントの結合より モゞュヌルからモゞュヌルぞの䟝存、ずいうこずを考える䞊で、そのモゞュヌルがどの皋床の頻床でどのくらい倉曎されうるか、ずいうこずは䞀぀の重芁な芳点になりたす。そしお、 よく倉曎されるこずを想定したモゞュヌルは、倉曎しづらいモゞュヌルから䟝存されるべきではありたせん。 䜕故ならば、倉曎しづらいモゞュヌルから䟝存されおしたうず、本来よく倉曎されるこずを想定したモゞュヌルが倉曎しづらい状態になっおしたうからです。 䟋えば䜕らかの共通の凊理を行うために切り出したモゞュヌルが、特定の機胜の凊理を行うためのモゞュヌルに䟝存しおしたっおいる、ずいった状況がこれにあたるでしょうか。こうなっおしたうず、特定の機胜の凊理に察しお倉曎を加えるず共通の凊理に波及しおしたうようになるので、その特定の機胜の凊理を行うためのモゞュヌルを倉曎するこずが行いにくくなるでしょう。 安定䟝存の原則SDPの原則は、よく倉曎されるこずを想定したモゞュヌルが、倉曎しづらいモゞュヌルから䟝存されおいないこずを保蚌されるために、満たすべき原則ず定矩されおいたす。 安定床の指暙 曞籍では、 モゞュヌルの倉曎しにくさを安定床ず定矩しおいたす。そしお、安定床を蚈枬するための指暙ずしお、 そのモゞュヌルがどのくらいの数のモゞュヌルから䟝存されおいるか ずいうこずず、 どのくらいの数のモゞュヌルに䟝存しおいるか ずいう二぀の指暙に着目しおいたす。 そしお安定床䞍安定床を次のように定矩しおいたす。 + ファン・むン: そのモゞュヌルに䟝存しおいる別のモゞュヌルの数 + ファン・アりト: そのモゞュヌルから䟝存しおいる別のモゞュヌルの数 + 安定床䞍安定床: I(Instability) = ファン・アりト / (ファン・むン + ファン・アりト) Gradleでは、明瀺的にモゞュヌル間の䟝存を蚘述しなければ別モゞュヌルぞのコヌドぞアクセスするこずはできないので、各モゞュヌルのbuild.gradleファむルを芋るこずで各モゞュヌル間の安定床を簡単に算出するこずが出来たす。䜿わないモゞュヌルにアクセスしおいない限りですが 䟋えば、 + app + ui:recipe + ui:netsuper + data:recipe + data:netsuper + api + db + infra ずいうモゞュヌルがあり、 のような圢でモゞュヌルが䟝存しおいるずしたす。 infraモゞュヌルを䟋えば芋おみるず、 ファン・むン = 5 ファン・アりト = 0 I = 0 / (5 + 0) = 0 ずなり、䞍安定床が0なので非垞に安定した倉曎しにくいモゞュヌルになっおいるこずが分かりたす。 䞀方appモゞュヌルは ファン・むン = 0 ファン・アりト = 8 I = 8 / (0 + 8) = 1 ずなり、䞍安定床が1なので極めお䞍安定な倉曎しやすいモゞュヌルずいえたす。 そしお、実際に矢印の数を数えおみるず分かるのですが、必ずIが高い=䞍安定なモゞュヌルから、安定したモゞュヌルに䟝存するような圢になっおいたす。 実際にアプリを蚭蚈する際の感芚ずしおも、アプリケヌション党䜓が䟝存するinfraは安定しおいお倉曎しづらく、uiは䞍安定で倉曎しやすいモゞュヌルずいうのは実感にあっおいるのではないでしょうか。同じuiの䞭でも、ui:recipeの方が耇数のモゞュヌルに䟝存しおいおよく倉曎がありそうですね。 安定床・抜象床透過の原則SAP コンポヌネントの抜象床は、その安定床ず同皋床でなければいけない。 第14ç«  コンポヌネントの結合より 安定䟝存の原則SDPに埓うず、基本的にモゞュヌルの䟝存関係は安定床が䜎い倉曎しやすいモゞュヌルから安定床が高い倉曎しにくいモゞュヌルに䟝存するこずになりたす。そうなるず、必然的に 安定床の高いモゞュヌルはあたり倉曎の必芁がない蚭蚈にする必芁がありたす。 プログラムコヌドには実装ずむンタヌフェヌスずいう二぀の偎面がありたすが、基本的にむンタヌフェヌスは倉曎されにくく、実装は倉曎されやすい傟向にありたす。そのこずを考えるず、安定床の高いモゞュヌルはあたり実装を含たず、むンタヌフェヌスを倚く含むKotlinであればinterfaceやabstract classモゞュヌルである必芁があるず考えられたす。 そのこずを曞籍では 安定床・抜象床透過の原則SAP ず衚珟しおいたす。 安定床・抜象床等䟡の原則SAPは、安定床ず抜象床の関係に぀いおの原則だ。安定床の高いコンポヌネントは抜象床も高くあるべきで、安定床の高さが拡匵の劚げになっおはいけないず䞻匵しおいる。䞀方、安定床の䜎いコンポヌネントは具䜓的なものであるべきだずしおいる。安定床が䜎いこずによっお、その内郚の具䜓的なコヌドが倉曎しやすくなるからである。 第14ç«  コンポヌネントの結合より こちらの䟋でいえば、安定床が最も高いinfraモゞュヌルには むンタヌフェヌスが最も倚い割合で含たれおいるべき で、安定床が最も䜎いappモゞュヌルには 実装が最も倚い割合で含たれおいるべき ずいうこずになりたす。 ずころで、䞊蚘の䟋だず、data:recipeやdata:netsuperには、uiから参照されるむンタヌフェヌスず、その実装の䞡方が含たれおいるこずになりたす。実装次第では、uiずdataで抜象床が逆転する可胜性もありたす。そのこずを考えるず、安定床・抜象床透過の原則SAPに埓うためには䞋のようにモゞュヌルの䟝存関係を敎理したほうがいいかもしれたせん。 data:bridgeモゞュヌルを導入しおそこにuiから䟝存しおいたむンタヌフェヌスを移動し、各dataモゞュヌルではそのむンタヌフェヌスを実装する圢でdata:bridgeモゞュヌルに䟝存したす。 抜象床の蚈枬 曞籍ではモゞュヌルの抜象床を次のような蚈算匏で定矩しおいたす。 + Nc: モゞュヌル内のクラス抜象クラスずむンタヌフェヌスも含むの総数 + Na: モゞュヌル内の抜象クラスずむンタヌフェヌスの総数 + A: 抜象床。A=Na / Nc Aが0であれば䞀切抜象クラスやむンタヌフェヌスが含たれない、最も抜象床が䜎いモゞュヌルであるこずを衚しおいお、Aが1であれば抜象クラスやむンタヌフェヌスしか含たれない最も抜象床が高いモゞュヌルであるこずを衚したす。 もっずもKotlinではむンタヌフェヌスに実装を持぀こずが出来るデフォルト実装ですがこずや、抜象クラスにも実装を持぀こずが出来るこずも考えるず、あくたで目安ずしお参考にするのがよさそうです。 安定床ず抜象床の関係 前述したやり方でモゞュヌルの安定床ず抜象床を蚈算するこずで、安定床ず抜象床の関係を定量的に芋るこずが出来るようになりたした。曞籍では次のような図を䜿っお安定床ず抜象床の関係を敎理しおいたす。 暪軞が安定床、右に行けば行くほどそのモゞュヌルは安定しおおり、瞊軞が抜象床、䞊に行けば行くほどそのモゞュヌルの抜象床は高いものずなりたす。 この図にモゞュヌルをプロットしおいくずしお、曞籍では二぀の「モゞュヌルがプロットされるすべきではない」ゟヌンず、「䞻系列」を定矩しおいたす。 苊痛ゟヌン 図の巊䞋のゟヌンは抜象床が䜎く、か぀安定床が䜎いモゞュヌルが含たれるゟヌンです。 倉曎がしにくい、か぀抜象床が䜎いために実装の拡匵もしにくい、そういったモゞュヌルがここに含たれるので、そういったモゞュヌルが倚いマルチモゞュヌル蚭蚈は倉曎に苊痛を䌎いやすいでしょう。 スマヌトフォンアプリ開発ではどのようなモゞュヌルがこのゟヌンに含たれやすいかずいうず、䟋えば曞籍でも䟋ずしお䞊げられおいる具象ナヌティリティラむブラリヌです。ほにゃららUtilクラスが䜜られ、アプリケヌションの色々なずころから呌び出される凊理がそのほにゃららUtilクラスに远加されおいく、ずいうのは皆さんも心圓たりがあるのではないでしょうか。こういったクラスはあたり倉曎されないのであれば苊痛を䌎いたせんが、良く倉曎される凊理がその䞭に含たれおいるずその倉曎が予期しない圢で他のモゞュヌルに波及したり、あるいはどういった利甚のされ方をされおいるか分からないので倉曎できなくなっおしたうようなこずが想定されたす。 基本的には 䞀床䜜ったら倉曎されないようなモゞュヌルロガヌ実装や基本的なデヌタ構造に察する凊理以倖はここに含たれないのが理想的 でしょう。 無駄ゟヌン 図の右䞊のゟヌンは、抜象床が高く、か぀安定床が高いモゞュヌルが含たれるゟヌンです。 抜象床が高い、぀たりむンタヌフェヌスや抜象クラスが倚く含たれおいるのにあたり参照されおいない、このようなモゞュヌルはそもそも必芁性がない可胜性が高いです。 もしこういったモゞュヌルがプロゞェクトに含たれおいるのを発芋したら、 敎理を怜蚎した方が良い でしょう。 䞻系列 倉動性の高いコンポヌネントをこれらのゟヌンからできるだけ遠ざけおおくべきなのは明らかだ。䞡方のゟヌンから最も離れた点を結ぶ軌跡は1,0ず0,1を぀なぐ盎線になる。この盎線を䞻系列ず呌ぶこずにする。 第14ç«  コンポヌネントの結合より 苊痛ゟヌンや無駄ゟヌンから遠いずころにある盎線、(1, 0)ず(0, 1)の間を぀なぐ盎線を曞籍では䞻系列ず呌んでおり、 䞻系列からの距離が近ければ近いほど、モゞュヌルの安定床ず抜象床が比䟋した関係にある こずになりたす。 䞻系列からの距離 モゞュヌルがどの皋床䞻系列から離れおいるかの指暙ずしお、曞籍では以䞋の指暙を定矩しおいたす。 D(Distance): 距離。D = | A(抜象床)+I(安定床)-1 | Dが0の堎合、モゞュヌルは䞻系列䞊にあるこずになり、Dが1の堎合は最も䞻系列から遠い苊痛ゟヌンか無駄ゟヌンにあるこずになりたす。 マルチモゞュヌル開発をする際は、 党おのモゞュヌルが極力䞻系列䞊に近いずころに配眮されるように開発を進めおいくべき でしょう。 クラシルのモゞュヌル構成はどうか さお、最埌に簡単ですが、ここたでの内容を䜿っお、クラシルのモゞュヌル構成を分析しおみたいず思いたす。以䞋は珟行のクラシルのモゞュヌル構成を簡略化した図になりたす。 クラシルではUIずデヌタの2局にアプリケヌションをモゞュヌル分割した䞊で、それぞれ機胜ごずにモゞュヌルを分割しおいたす。 ui:baseずdata:baseはそれぞれむンタヌフェヌス甚のモゞュヌルであり、UI局同士のアクセス、デヌタ局同士のアクセス、UI局からデヌタ局ぞのアクセスはそれぞれui:baseずdata:baseを経由しお行うようになっおいたす。䞀方で、共通で利甚する具象クラスもここに含たれおいたす。 そしおui:xxxずdata:xxxに、それぞれui:baseずdata:baseに定矩されたむンタヌフェヌスの実装が含たれおいるずいう構造になっおいたす。 図ではそれを矢印ずしお衚瀺するず煩雑になっおしたうため省略しおいたすが、common_modulesは基本的にどのモゞュヌルからもアクセスできるようになっおいたす。なので図では䟝存しおいるモゞュヌルの数は少ないが実は安定床MAXなので、これらのモゞュヌルが頻繁に倉曎されるようだず、蚭蚈を芋盎す必芁がありそうです。 安定床に着目しおみるず、 app ファン・むン = 0 ファン・アりト = 14 I = 14 / (0 + 14) = 1 ずなり、極めお䞍安定なモゞュヌルから䟝存グラフが始たり、 ui:recipe ファン・むン = 1 ファン・アりト = 3 I = 3 / (1 + 3) = 3/4 ui:base ファン・むン = 6 ファン・アりト = 3 I = 3 / (6 + 3) = 1/3 data:recipe ファン・むン = 1 ファン・アりト = 3 I = 3 / (1 + 3) = 3/4 data:base ファン・むン = 12 ファン・アりト = 2 I = 2 / (12 + 2) = 1/7 ず安定床が掚移しおおり、基本的に䞍安定なモゞュヌルから安定したモゞュヌルぞ䟝存関係があるこずが分かりたす。 そしお、ui:baseやdata:baseずいった共通むンタヌフェヌスを配眮するモゞュヌルが䟝存グラフの先にあるこずで、ある皋床安定床ず抜象床が比䟋しおいるこずが分かりたすが、今埌の改修でui:baseやdata:baseモゞュヌルに具象クラスを倚く含むようになっおきおしたうず、プロゞェクト党䜓の改修しにくさに繋がっおいきそうです。実際、どうしおも共通モゞュヌルは肥倧化しがちなので、適宜リファクタリングをするこずでなるべく抜象床を䞋げおいきたいものです。 今回は、クラシルのモゞュヌル図の䞀郚を䜿っお安定床ず抜象床の分析を行っおみたした。皆さんのAndroidプロゞェクトでも、是非やっおみおはいかがでしょうか。 たずめ å…šAndroid゚ンゞニアはClean Architectureの第IV郚を読んだ方がいいよ Gradleのモゞュヌルは第IV郚のコンポヌネントを衚珟するのにうっお぀けの単䜍だよ モゞュヌルは同じタむミング、同じ理由で倉曎されるものをたずめるずいいよ どのくらいの粒床で分割すべきかはアヌキテクトの刀断次第だよ、バランスだよ モゞュヌルは埪環䟝存できないこずを生かした蚭蚈を考えるずいいよ モゞュヌルの䟝存関係は倉曎されやすいものから倉曎されにくいものぞ䟝存する方向で曞くずいいよ 䟝存するモゞュヌルが倚いモゞュヌルは䞍安定で、䟝存するモゞュヌルが少ないモゞュヌルは安定しおいるず考えるず楜だよ モゞュヌルの安定床ずコヌドの抜象床が䞀臎しおいるずいいよ モゞュヌルの安定床・抜象床を蚈枬する䟿利な指暙があるよ、簡単だから今日から䜿えるよ おわりに クラシルのAndroidチヌムでは、生産性の高いアヌキテクチャを維持・アップデヌトし぀぀も楜しくプロダクト開発できる人、したい人を求めおいたす。 今回の蚘事を読んで興味が出おきた方、是非お話ししたしょう 䞋蚘の採甚リンクから応募いただいおもOKですし、Twitterから気軜にDM頂けおもOKです dely.jp twitter.com
こんにちは、プロダクト開発本郚SREチヌムの束嶋です。 delyのSREチヌムは、2020幎末頃たで最倧2人䜓制の少数で奮闘しおきたしたが、嬉しいこずにこの1幎でメンバヌが4人ず倍増したした。 それたでは、リ゜ヌス䞍足であったため足元にある緊急床の高い課題を解決しおいくこずがSREのメむンむシュヌで、長期的に取り組んでいく必芁のある改善業務に着手するこずが困難な状態でした。 しかし、SREのプラクティスを䜕も実践できおいなかった蚳ではなく、想定倖の耇雑さを枛らし、今以䞊に増やさないための文化づくりを意識的にしおきたので、サヌビスの信頌性が倧きく䞋がるこずはほずんどなく、アラヌト察応に远われる状況に陥るこずは防げおいたず思いたす。 実際どのように想定倖の耇雑さを枛らす取り組みをしおいたのかは、珟CTOの井䞊が「SRE NEXT 2020」にお発衚しおいるので、興味のある方はこちらの蚘事をご芧ください。 tech.dely.jp メンバヌが増員したこずでリ゜ヌス䞍足からは解消されたのですが、本来SREずしお䜕をすべきなのか圹割が曖昧であるこず、たたチヌムずしお機胜するための仕組みがないこずが浮き圫りずなりたした。 そこで本蚘事では、ここ1幎で自分たちがサヌビスや組織に提䟛できる䟡倀を改めお再考し、SREがチヌムずしお効果的に機胜するために珟圚たで取り組んできたこずに぀いお玹介したいず思いたす。 1. チヌムミッションの再考 最初に取り組んだのは、SREチヌムのミッションの再考です。 delyのバリュヌずミッションが曎新された同時期にちょうどメンバヌが4人になったため、SREは䌚瀟のバリュヌを䜓珟しおいくためにチヌムずしお䜕を成し遂げおいくのかを議論したした。 delyのバリュヌは、 「Trade on」、「Deliver Passion & Happines」、「Good to Great」、「Heart to Heart」 の4぀があるのですが、これらのバリュヌに沿っおSREずしお䜕を実珟しおいくのかチヌム内で話し合い、たた開発郚の他チヌムの意芋も取り入れた䞊でミッションを決定したした。 delyが持぀熱量ず幞せをできるだけ倚くの人に届けられるように、プロダクトの䟡倀最倧化をシステム運甚においお実珟する。 その過皋においお最善の遞択が䜕であるかを考え、システムの蚭蚈ず運甚を改善し続ける。 このミッションには、䜕故私たちSREはシステムの蚭蚈ず運甚を改善しおいくのかの想いが蟌められおいたす。SREは盎接的にプロダクトの機胜開発に貢献しおいる蚳ではないですが、信頌性ず開発速床の2぀の指暙を远っおいるのは、ナヌザヌの満足床ず事業の成功床を高めるためであり、その手段ずしおシステムの蚭蚈、運甚を改善しおいるこずを日頃から意識しおいくこずが重芁だず考えおいたす。したがっお、䌚瀟ずしお倧切にしおいる「delyが持぀熱量ず幞せをできるだけ倚くの人に届けられる」、「プロダクトの䟡倀最倧化」ずいう文蚀をミッションに入れるこずにしたした。 ミッションを再定矩するこずで、delyのSREらしさが可芖化されたず思いたすし、チヌムずしおの共通認識が生たれ、足元が揃いやすくなったのではないかず感じおいたす。 delyのバリュヌに぀いお詳しく知りたい方は、こちらのカルチャヌデックをご芧ください。 https://speakerdeck.com/delyinc/delyculture speakerdeck.com 2. 圹割スコヌプの策定 続いお、ミッションに沿ったSREの圹割スコヌプを定めたした。 圹割スコヌプずは、SREの責任範囲や業務内容を明確にするためのものです。 䜕故ミッションだけではなく圹割スコヌプも定矩したかずいうず、SREの業務は組織やフェヌズによっおやるべきこずが倉わっおくるので、責任範囲を決めるこずで、SREメンバヌの認識のずれを最小限にし、チヌム間のコミュニケヌションを取る䞊でもSREたたは開発者がボヌルを持ったほうが良いのか刀断しやすくするためです。 SRE本の第1章には、GooleのSREの責任範囲に぀いお以䞋のように曞かれおいたす。 ワヌクフロヌの现かい郚分、優先順䜍、日々の運甚は SRE のチヌムによっお異なっおいたすが、 サポヌトするサヌビスに察する䞀連の基本的な責任ず、䞭栞ずなる信条の尊重は、すぞ゙おのSRE チヌムに共通するものお゙す。抂しお、SRE チヌムは、サヌビスの可甚性、レむテンシ、パフォヌ マンス、効率性、倉曎管理、モニタリング、緊急察応、キャパシティプランニングに責任を負いたす。私たちは、SRE チヌムはず゙のように環境ずやりずりすぞ゙きか、業務の芏範を明文化したした。 この環境には、実働環境のみならず、プロダクト開発チヌム、テスティングチヌム、ナヌザヌなず゙も含たれたす。これらのルヌルや䜜業のプラクティスは、運甚の䜜業お゙はなく、゚ンジニアリング䜜業に集䞭し続けるのに圹立っおいたす。 1.3 SRE の信条/Site Reliability Engineering しかし、delyずサヌビスの芏暡やフェヌズも党く異なるため、Googleの考えを取り入れ぀぀もdelyのSREが珟状取り組んでいるこずを螏たえお圹割スコヌプを11個定めたした。 決定したdelySREの圹割スコヌプは、以䞋のずおりです。 1. サヌビスのSLOを䞋回るこずなく、倉曎の速床の最倧化を远求する 2. モニタリング 3. 緊急察応 4. 倉曎管理 5. 需芁の予枬ずキャパシティプランニング 6. パフォヌマンス 7. むンフラコストの管理 AWS/GCPのコスト管理 8. コンサル/オンボヌディング 開発者ぞのむンフラオンボヌディング、サヌバヌサむド蚭蚈レビュヌ 9. ロヌンチ調敎 新芏サヌビス立ち䞊げ時のコンサルティング、新芏サヌビスのむンフラ蚭蚈・構築・運甚 10. サヌビスのセキュリティ むンフラ呚りのセキュリティ察策、AWS/GCPのアカりント・暩限管理 11. サヌビスの埩旧準備 氞続デヌタのバックアップ蚭蚈・運甚 ※項目7~11が、dely独自の圹割スコヌプなので泚釈を぀けおいたす。 SRE本でも蚀及されおいる項目も含たれおいたすが、delyのSREが今たでやっおきたこず、これからもやっおいくべきこずを考慮した䞊で、新しくスコヌプを定めた方が自分たちの業務範囲を認識しやすく、今たで以䞊に円滑なコミュニケヌションや意思決定ができるず考えたため、独自のスコヌプを定矩したした。 3. 課題の掗い出し優先床決め ミッション及び圹割スコヌプが決定し、チヌム内の共通認識が出来䞊がったずころで次に取り組んだのは、珟状システムが抱えおいる課題の掗い出しず各課題の優先床付けです。 SREが解決しおいくべき課題は倧小様々ありたすが、基本的に䞊述した圹割スコヌプに玐づくものになっおいたす。 たた、課題が可芖化されおいおも各課題の優先床が数倀化されおいないず、メンバヌが着手しやすいものや圱響床の小さい課題ばかり取り組んでしたう可胜性があり、優先床の刀断が個々に委ねられおしたうので、SREチヌムの䟡倀を最倧限発揮するこずができたせん。 そこで、課題の優先床を客芳的な指暙で決定できるように、 「信頌性」、「開発速床」、「運甚効率化」、「工数」 の4぀の指暙を甚いお優先床を算出する方匏を採甚したした。 「信頌性」、「開発速床」、「運甚効率化」の3指暙には3~4段階のりェむトを割り振り、それぞれを掛け合わあせたものを「工数」で割っお算出した倀が高いほど優先床が高い課題ずなり、その課題から取り組んでいくようにしたした。 「優先床」=「信頌性」×「開発速床」×「運甚効率化」/「工数」 各課題における「信頌性」、「開発速床」、「運甚効率化」の重み付けは、以䞋のような重み付け衚で定矩しおいるので、課題に最も近いポむントを遞択するようにしおいたす。 # 信頌性 - サヌビスダりンやパフォヌマンス悪化等、ナヌザヌ䜓隓が著しく損なわれる可胜性が高い or 既にナヌザヌぞ悪圱響がでおいる ->4 - 信頌性を䞋げおいる原因ずなっおいるが、珟段階ではナヌザヌ䜓隓が著しく損なわれる可胜性が䜎い ->3 - 珟状は問題ずしお顕圚化しおいないが、解消するずより信頌性の向䞊に぀ながる ->2 - 信頌性の向䞊には圱響がない ->1 # 開発速床 - 党䜓、たたは各Squadの機胜開発速床を既に倧きく劚げおいる原因ずなっおいる or 開発速床を著しく䞋げおいる可胜性が高い ->4 - 開発速床を䞋げる芁因の぀ではあるが、珟段階では臎呜的な問題になっおいる可胜性が䜎い ->3 - 珟状は問題ずしお顕圚化しおいないが、解消するずより開発速床の向䞊に぀ながる ->2 - 開発速床の向䞊には圱響がない ->1 # 運甚効率化 - SREの運甚業務の負荷が既に高く、自動化するこずで運甚コストが倧幅に削枛できる ->3 - SREの運甚業務の負荷がそこたで高くないが、自動化するこずで運甚コストが削枛できる ->2 - 運甚䜜業の自動化によっお運甚コストの削枛に぀ながらない ->1 実際にSREチヌムで運甚しおいる課題衚はこのようになっおいたす。 SREチヌムの課題衚 基本的に優先床が高い順に着手しおいくルヌルにはなっおいたすが、運甚開始時点からルヌルで瞛りすぎるず柔軟に察応しづらくなっおしたうので、倚少の前埌は蚱容するこずにしたした。 たた、システム自䜓も日々刻々ず倉化しおおり、課題も時間が経぀に぀れ優先床も倉動があるはずなので、定期的に芋盎し䌚を開催し優先床をすり合わせたりず運甚面も改善しおいっおいたす。 4. 運甚負荷の蚈枬 皆さんご存知の通り、Googleでは手䜜業による運甚業務の割合がSREが受け持぀党業務のうち50以䞋に抑え、それ以倖の時間は長期間の゚ンゞニアリングプロゞェクトのために時間を費やすこずを目指しおいたす。 「手䜜業、繰り返される、自動化が可胜、戊術的、長期的な䟡倀がない、サヌビスの成長に比䟋しお増加する」 *1 ずいう特城を持぀䜜業はトむルず呌ばれおおり、゚ンゞニアリング䜜業の進捗を劚げるものです。 delyのSREチヌムでも自分たちがプロゞェクト業務に時間を割けおいるのかどうかの刀断が肌感芚になっおいたので、GoogleSREのこちらの蚘事を参考に蚈枬、トラッキングしおいくこずにしたした。 cloud.google.com Googleず異なっおいる点は、トむルだけではなく、プロゞェクト業務SRE課題の取り組みずオヌバヌヘッドMTG、1on1、評䟡等以倖のものは党お蚈枬察象にしたこずです。 䜕故ならトむル自䜓が明確にトむルである、トむルではないず二分するこずが難しく、スペクトラムずしお考えるほうが良いので *2 、トむルのみを掗い出しお蚈枬するよりも運甚業務党般を察象にしたほうが負荷が高いタスクが可芖化されやすく、改善のためのアクションを取るこずができるず刀断したした。 実際の蚈枬方法は、1週間で運甚業務に費やした時間ず察応した回数を蚘録しおいき、1週間の勀務時間あたりどの皋床運甚業務に䜿っおいるか割合を出しおいたす。 最近の運甚負荷の倉動ず内蚳を集蚈した結果は以䞋のずおりです。 SREチヌムの運甚負荷の割合 運甚タスク別集蚈結果 運甚開始時は、ちょうどテレビ番組におクラシルのレシピ玹介が倧きく取り䞊げる機䌚が近かったこずもあり、負荷察策に時間を䜿っおいたため䞀時的に運甚負荷が高い割合ずなっおいたしたが、レビュヌが䞀郚のメンバヌに集䞭しおいたり、開発者䟝頌の運甚タスクが䞀郚負担が倧きく効率が悪かったので、この郚分は改善に取り組んできたした。 レビュヌに関しおは、䞀郚のメンバヌに偏らないようランダムアサむン方匏に倉曎したり、運甚タスクに関しおは自動化や開発者自身でも察応できる郚分を増やすために環境敎備を実斜しおきたので、運甚負荷は埐々に枛少しおいたす。 5. SRE月報の実斜 最埌にSREの瀟内認知の拡倧のために取り組んでいる内容に぀いお玹介したす。 SREの存圚䟡倀を最倧限発揮しおしおいくためには、他のチヌムやステヌクホルダヌのサポヌトや理解が必芁䞍可欠です。 しかし、珟状delyのSREチヌムは、他のチヌムから芋るずSREが普段どのようなこずに取り組んでおり、䜕を改善しおいるのかが芋えづらく、SREの圹割を理解しづらいずいう問題がありたす。 SRE自䜓の認知が䜎い状態でSREのプラクティスを実践しおいっおも、浞透しなかったり圢骞化しおしたいたすし、たずは自分たちが普段どんなこずに取り組み、䜕を改善しお成果をあげおいるのかを可芖化し、知っおもらうこずが必芁だず考えたので、システムの珟圚の状態や傟向、その月に発生した障害の話やSREメンバヌが改善した項目に぀いお月ごずに共有しおいくこずにしたした。 もちろんこれだけでSREの認知床や理解床が䞊がる蚳ではないので、今埌他にも瀟内認知拡倧のための取り組みを実斜しおいく予定です。 最埌に 今回は、SREチヌムが自分たちの䟡倀を最倧限発揮できるように取り組んできたこずを5぀玹介したした。 淡々ず今たでやっおきたこずを曞いおいたすが、珟圚に至るたで様々な玆䜙曲折がありたした。 ただチヌムずしお始動したばかりで発展途䞊だず思うので、これからも良いプロダクトを䜜っおいくために、システム蚭蚈、運甚を改善しおいきたいです。 私たちがチヌム立ち䞊げ期にどのようなこずに苊戊し、乗り越えおきたかなど少しでも興味を持っおいただけたら、是非カゞュアルにお話ししたせんか。 meety.net https://meety.net/articles/t2--tr6k9sxi_jo meety.net delyでは党職皮採甚匷化䞭です。気になる方は以䞋のリンクから募集職皮䞀芧がご芧いただけたす。 speakerdeck.com *1 : 5.1 トむルの定矩/Site Reliability Engineering *2 : 6.3 トむルの分類孊/The Site Reliability Workbook
こんにちは、゚ンゞニアリングマネヌゞャヌのtakaoです。 こちらの蚘事はdely Tech Talk 「#1 dely 新CTO 井䞊厇嗣 / dely new CTO Takashi Inoue」 の文字起こしです。 anchor.fm 今回の配信では、CXOの坪田さん、コマヌス事業責任者の倧竹さん、新CTOの井䞊さんの3名に、CTO亀代に関するお話をしおいただきたした。 现かい盞づちや話し蚀葉など文字起こしの際に線集しおいる箇所がありたす。話しおいる3名の雰囲気などはPodcastを聞いおいただいたほうが感じられるず思うので、お時間がある方はぜひPodcastをお聞きください。 自己玹介 坪田 今日はdelyTechTalk第1回ずいうこずで、CTO亀代に぀いお話したいず思いたす。僕はdelyでクラシルのプロダクトマネゞメントをしおいる坪田なんですけど、今日は倧竹さんず井䞊さんに来おもらっお、CTO亀代に぀いお話しおいきたいず思いたすので、よろしくお願いしたす。早速CTO亀代したしたずいうこずで、たけさんからバトンタッチした思いを語っおいきたすか。 倧竹 たず知らない人もいるかもしれないので自己玹介するず、倧竹雅登ずいいたす。この䌚瀟は代衚の堀江さんず䞀緒に共同創業しお2014幎からなのでもう7幎半ぐらい経ちたす。創業のずきからずっずCTOずしお自分でコヌドを最初はずっず曞いお、特にクラシルのずきは最初は自分1人しかいなかったので、1人でコヌドを曞いたりしおいたした。その埌は、開発組織が倧きくなっお組織マネゞメントずかをやっおいったずいう経緯がありたす。2018幎以降はコマヌス事業郚ずいうずころの事業責任者ずしおビゞネス偎を今芋おいたす。そういった経緯なんですけども、今回9月1日付でCTOを亀代しお、この埌玹介する井䞊さんが新CTOずしおdelyのCTOに就任したずいうような経緯になりたす。井䞊さんの玹介もしおもらっおいいですか。 井䞊 井䞊ず申したす。僕は2018幎の5月に入瀟したんですが、delyは4瀟目で、新卒ではSIerに入瀟しおお、そこから転職しお2瀟経隓しおいたす。䞀぀目がゲヌムを䜜っおる䌚瀟で、ゲヌム䜜っおたわけではなくお、開発者が楜をするためのプラットフォヌムみたいなずころをやっおいたした。その埌はWeb系のベンチャヌに行っお、そこでむンフラ゚ンゞニアやっおたずいうずころで、delyはSREずしお入瀟したした。そこからちょっずマネヌゞャヌずかいろいろし぀぀、開発郚の郚長をし぀぀今回CTOに亀代させおいただいたずいう感じです。 CTO譲りたすの蚘事から2幎半の経過〜なぜ井䞊さんがCTOに遞ばれたのか 坪田 たけさんCTOを譲りたすっおいう宣蚀をしおからどれぐらい経ちたした 累計70億調達、1500万DL突破の「クラシル」のCTO、譲ります。|大竹雅登/dely|note 倧竹 2幎ぐらいだったかな。クラシルのCTOを譲りたすずブログを曞いたのが2019幎なんで、1月ずかで2幎半以䞊かかったかな。圓時、もずもず2019幎時点で僕がコマヌス事業郚の事業責任者になっおビゞネス偎にもフォヌカスするっお決めおたので、CTO業を専任でやる人が必芁っおのはその圓時から、瀟内ずしおも認識があっお、探しおたんですけど、実際あの蚘事を出しおから30人ぐらいは連絡しお䞀郚の人は䌚ったりしおたんですけど、なかなかフィットする人はいなくお。delyにカルチャヌフィットしおるずか、スキルが近いずか経隓があるずかそういうのも党郚フィットする人っおなかなかいなくお、すぐに亀代っおいうこずには党然ならなかったんですけど、今回井䞊さんに決めたずいうか、亀代するっおいうふうにした理由にも繋がるんですけど、今クラシルっおのは、リリヌスしおから5幎半ぐらい経ったかな。アプリだず5幎半ぐらい経っお、結構成熟しおきおいお、今埌もっず発展するためにはなくちゃいけないこずっおのがいく぀かありたすず。そのうちの1個が今埌今やっおいきたいこずにも繋がるんですけど、デヌタをしっかり掻甚し、か぀リコメンドを匷化しおいきたいず思っおですね、デヌタパむプラむンをしっかり敎備しおそれを基に、個人に合ったレシピずかコンテンツをパヌ゜ナラむズしおお届けするっおいうこずをやっおいかなくちゃいけなくお、これたでず比范しお、技術ずいうかテックの深いずころたでちゃんず芋れるCTOずいうか、芋える人が必芁なので、そこの郚分を担っおもらいたい人っおのが適任なんじゃないかなず思っおるんですよ。井䞊さんは今䜕幎でしたっけ入瀟しお 井䞊 もう3幎半くらいですね。 倧竹 3幎半ぐらいでSREでもちろんそのむンフラずかバック゚ンドずかデヌタ回りずかっおのは、もちろんそこに関しおはプロフェッショナルですず、圓然ながらか぀これたで゚ンゞニアリングだけじゃなくお、開発郚が今40人ずかいる䞭で、そこの技術的なマネゞメントずかピヌプルマネゞメントずかっおいうのをずっずやっおたんでそこに察する信頌感が圧倒的にあるず。倖郚で仮にスヌパヌマンみたいな人がいたずしおも、結局チヌムからの信頌ずか、この人が蚀うならそこに察しお぀いおいこうず思えるような人じゃないず、組織ずしおのチヌムずしおのパフォヌマンスがでないじゃないですか。やっぱりそこは結局もう倖郚でずかじゃなくお、もう既に信頌感のある井䞊さんで、技術スキルも今やっおいきたいこずにマッチしおいるし、今埌も信頌しお任せられるっおいう人なんだったら、井䞊さんが適任だよねっおいうこずを決めたずいう経緯ですね。 坪田 その信頌できるパヌトナヌで技術もあるのが井䞊さんであるず。これ流れめちゃくちゃ早かったですよね。そうしようっお決めおから、䜕かその週䞭ぐらいに話しお 倧竹 決めたのは、もうその週の䞭から3日ずかで決めたずいうか、時間だずもう1時間で決たったず思うんですけど 坪田 delyっぜい意思決定ですよね 倧竹 そう、すぐ即決だったんですけど、でもそれっおなんか、適圓に決めたずいうよりかは、もう満堎䞀臎ずいうか、delyの䞭の党員から芋おもう井䞊さんだったらそこがいいよねず、そうなるべきだよねっおこずが決たったし、その埌党䜓䌚議ずかで発衚したじゃないですか。もう党然䜕も違和感ずかなく、結構あるず思うんですよ、人によっおはなんでこの人っおのはなるかもしんないですけどそこは党く違和感なく受け入れられたっおのは、やっぱ適任だからなんじゃないかなず思っおたす。 坪田 玠晎らしい。そんな、䌚話を受けお井䞊さんもちょっずメッセヌゞを。CTOっお突劂発衚されるのもあるんですけど、なんかもうこの人なら玍埗感があったみたいなずころは、ある皋床瀟内の雰囲気もあっお、よかったですよね。 井䞊 そうですね。僕も僕なりにやるべきこずをやっおきたっおいう感じはあっお、別にCTOになりたいずいう気持ちでやっおきたわけじゃなくおシンプルに今自分がやるべきこず、䟡倀が最倧化できるものは䜕なのかっおいうのを考えおやっおきたっおいうのが、やっおきたこずかなっおいうずころはありたすね。なので、やるべき人がいないずころずか、宙に浮いちゃっおるものずかなんだけど、やっぱやんないずいけない郚分みたいなのをやるこずが䞀番その䌚瀟にずっお事業であったりプロダクトを良くするこずであったりっおいうずころに、効くのであれば、やるしかないよねっおいうずころをやっおきたっおいう。 倧竹 僕その井䞊さんのスタンスず、CTOのやるべきこず䞀臎しおるなず思うもう1個が、他瀟ずかも含めお結構成果を出しおいるCTO、あずうちの瀟倖取になっおる束本さん、LayerXで代衚取締圹CTOをやっおいる束本さんずかず話しおおよく思うのは、技術だけじゃ絶察駄目なんですよ、技術力を持っおるずか゚ンゞニアリング力が高いっおのでは駄目で、結局経営者なんで俯瞰しお、䟋えばチヌムのこずずか、事業のこずずかっおいうのを俯瞰した䞊で、技術的なバックグラりンドを持っおいおそちらに関しおも正確な意思決定ができるっおいう人がなるべきだなず思っおお、井䞊さんっお最初もSREのスペシャリストずしおもちろん入瀟しおるんですけど、䜕か必然か、井䞊さんのCapabilityが高いから、すごいハヌドルが高いプロゞェクトずか抜象床の高い䞍確実性の高いプロゞェクトがどんどん任されお、すごい倧倉だったず思うんですけど、そういうのをちゃんずこなすっおいうか、党郚あらゆる可胜性ずリスクずかを敎理しお、実行するこずができるのを3幎間芋おきたっおのも1個倧きな理由ですね。䜕かテクノロゞヌの胜力だけで遞んだわけでは党くないっおいう状況です。 坪田 でもなんかそれはありたすよね。今っお䌚瀟も倧きくなっお人も増えおきお、束本さん理論のプロダクトマネゞメント・プロゞェクトマネゞメント・ピヌプルマネゞメント・テックマネゞメントの䞭で少しず぀分業できるようになったじゃないですか。゚ンゞニアはピヌプルマネゞメントだず倚分もう井䞊さんが今やっおくれお、プロダクトはプロダクトで別であるみたいなずころで、䜕かそれぞれの技術が生かせるようになっおきたりずか、リ゜ヌス投資できる状態になっおいく䞭でのそのバトンタッチずしお、䜕かいい感じになっおきたのかなず思いたす。でも僕あれなんですよ。2幎ぐらい前にdelyに入ったんですけど、井䞊さんその時リヌダヌだったマネヌゞャヌじゃなかったっけ 井䞊 䞀応メンバヌはいたっおいう感じですね。 坪田 メンバヌがいおリヌダヌ職だけど井䞊さん党然マネヌゞャヌ志向じゃなかったんですよ。なんか井䞊さんマネヌゞャヌにしたすっおなったずきに、本圓はもうやりたくないんですよみたいな話があっお、なんかカフェで1on1したんだ。1幎2幎ぐらいだったらやりたすっお蚀ったんですよね。 井䞊 めっちゃなんか蚘憶曖昧ですけど、僕は完党に芚えおいお、2幎やっおくれっお蚀われたしたね。 坪田 最初は技術志向でSREを掚進しおいきたい、プレヌダヌずしおもやっおいきたいけど、井䞊さんが䞀番適任だず思っお1on1をしお話始めたら、僕本来そっちをやりたいから2幎やりたすみたいなこず蚀っお、2幎経ったけどそのたたずっずやっおいただいおるみたいな感じですね。 倧竹 確かにマネヌゞャヌじゃなくおCTOになったずいう意味で2幎の玄束は守られおない 坪田 井䞊さん的にその蟺の考え方ずかCTOをやるず、技術的に突き抜けたいずころから、少し埌方支揎の郚分も含たれおくるず思うんですけど、その蟺の考え方ずかはどうなんですか。 井䞊 CTOっおいうのも抜象的ではあり぀぀、やっぱり誰がやるのかによっお進め方ずか方針ずか倉わっおくるかなずは思っおいお。最終的にどうあるべきなのかっおいうずころが揃っおれば、その山の登り方的なずころは別に人それぞれやればいいのかなっおいうのは思っおはいるので、僕は僕なりにやり方を考えお進めおいお、その䞭で自分がやりたいこずが満たせおいけばそれでいいのかなずは思っおるので、別に䜕かCTOになったから今そのずきにやりたいこずが今できなくなったのかどうかっおいうず、別に僕のやり方次第だなっおいうずころは思っおるんで、そこはいいのかなず思っおたす。 倧竹 井䞊さんっおやるたではちょっず保守的ずいうか、「ちょっずやんない方がいいず思いたすよ」っお蚀うんですけど、やるずすごいExecuteするっおのがあっお、これ入瀟時からそうなんですよ。井䞊さんを採甚するずきに井䞊さんの前職が新宿の蟺りにあったんすけど、そこに井䞊さんがOKっおいうたで毎回行っお毎回同じ話をするっおいうのを3,4回しお。井䞊さんも圓時なんでこの人毎回同じ話するんだろうっお思いたしたよね。 井䞊 党おの面接にたけさんはいるんですよ。 坪田 新宿たで行っおたんですか 倧竹 行っおたした。䜕回か行っおその近くで、こうこうこうだから来おほしいですっお䜕回も蚀っお、わかりたした持ち垰りたすみたいな感じで毎回持ち垰られおもう1回蚀うっおいうこずをずっずやっおたんですよ。 坪田 よく決めたしたね。 井䞊 そうですね。やっぱりそのずきはただ組織も小さかったし、自分のスキルを掻かせるなっおその時SREずしお入っおるわけだから、SREずしお、自分のスキルが掻かせそうだっおいうずころを思っお入っおたす 倧竹 圓時䜕人ぐらいでしたっけdely 井䞊 10人ぐらいだず思いたすね。゚ンゞニアは10人ぐらいで、瀟員は5,60人ぐらい。 倧竹 今ず比べたら党然、3分の1ずか4分の1しかない芏暡なんで、その圓時に入っおるんで、 坪田 でもそこからの信頌感の積み䞊げ、井䞊さん俯瞰力も高いじゃないですか。技術だけに特化しおるんだけど、ありずあらゆるこずを䜕かアンテナ匵っおたりしおるから、マネヌゞメントやっぱ䞊手だし、でもあれですね、ちょっずこの話をするず時間が長くなりすぎちゃうから、ちょっず今埌の新CTOの方針ずいうか、サヌビスの方針も含めお、倚分語らないず、時間があれですね。で、今っおなんか党瀟的にちょっず新しいこずにチャレンゞしおるっおいうフェヌズだず思っおいおECもそうだし、クラシルもそうだし、他の事業もそうかなず思うんですけど、井䞊さんがCTOになっお、デヌタパむプラむンをちゃんず敎備しおいこうみたいな話も、背景ずかもあるず思うんですけど、そういうのを聞けたらいいなず思うんで、語っおいただけるずいいかなず思いたす。 CTOの亀代に䌎っお組織や事業はどう倉化しおいくのか 倧竹 ただ本題の詳现に぀いおは蚀えない郚分が結構あるんですが、ものすごく仕蟌んでるんですよね。いろいろ倉革期ずいうか、クラシルっおこれたでの5幎間は、いわゆるレシピ動画ずしおのコアな䟡倀みたいなのを磚き蟌んできたっおずこがあるんすけど、さらにむンフラずなるようなレベルにしたいなず思っおおそこで1幎ぐらい、仕蟌んで䌁画から実装から蚭蚈からテストからっおいうのをずっずやっお仕蟌んでる郚分があっお、そこに察しお、 デヌタをちゃんず掻甚するために、デヌタパむプラむンがあり、デヌタのストレヌゞがあり、それをリコメンドのアルゎリズムに反映するずかっおいうのが必芁になっおくるず、そこを今絶賛、採甚だったり瀟内でのリ゜ヌスの再配分だったりずか結構アグレッシブにしおるっおいうのが状況ですよね 井䞊 そうっすね、やっぱり䞀般的なWebのアプリケヌションだったりアプリを䜜るっおいう話ず、デヌタを䜿っおどうのこうのするっおいう話は、スキルセットがやっぱり違っおるっおいうずころが特城的で、やっぱりデヌタを扱うっおいうずころのスペシャリティがないずちゃんずしたものが出来䞊がらなかったり、できたずしおもメンテができなくなったりみたいなこずはよく起こるものではあるので、ちゃんずそこに察する開発なり考え方なりアヌキテクチャなりみたいなずころは、統䞀感を持っおやっおいかなきゃいけないっおいうずころは間違いないなず思うんですね、これからこのdelyずいう䌚瀟が、そのデヌタを䜿っおどうこうするっお話になったずきに、それをなんか、ただ1人の人間がやるのかっお蚀ったらそれは結構スケヌラビリティに欠けるっおいうずころがあったり、そもそもそんなこずできるのかっおいう人がいるのかっお話があったりしお、難しさがやっぱり现分化するずいうか、圹割を分けおやっおいかなければいけないっおいうずころかなず思っおいおただその圹割を分けお採甚はするんだけど、圹割が分担されおいる䞭においお、それをうたく遂行しおいくっおのもたた難しさがあるみたいなずころがあるので、それをうたく埋め぀぀、ただしそのデヌタの郚分、技術の郚分をやっおはいるんだけど、最終的にプロダクトを良くしおいくっお話ずかナヌザヌに䟡倀を䞎えるっおいうずころを䞀番目的ずするっおいうずころは忘れずにやっおくっおいうずころをやるっおいうのは、今埌やっおいくべき郚分かなっおいうふうには思いたすね。 倧竹 結構こういうデヌタずかアルゎリズムずかそういうずころをやるっおいうプロゞェクトっお長期になるじゃないすかどうしおも。なので、ちゃんずやっおいくぞっおいう意思ずあずやりきれる人がちゃんずリヌダヌシップを持っおやるっおのがすごい重芁だず思うんすよね。ポンずやろうず思っおも、アサむンがちゃんずされおなかったり、リヌダヌシップを持っお掚進する意思決定する人がいないずき、厳しいっおいうか、フワッず終わっちゃうのが結構あるかなず思うんですけど、そこに関しおはうちの堎合そこに意思を持っお今回の亀代も井䞊さんがそこを名実ずもにちゃんず匕っ匵っおいくっおいう人ずしおちゃんずアサむンしお、そこに暩限ももちろんあるし、匷い意思決定もできるような状態にしお本腰入れおやっおいくぞずいう経営的な意思決定ずプロダクト的な意思決定ず、あずそこに合わせた人材ずをCTOずいうラベルをちゃんずアサむンするずいうずころたで、今セットでやっおるっおいう状況なんで、結構本腰入れおたすっおいうのはアピヌルしたいっすね。 井䞊 そうですね。結構やっぱり長期だし、䜜り倉えるっおいうのも簡単にはできない郚分っおいう話があっお、どうしおもそこは誰かが意思を持぀っおのはすごく重芁かなずいうふうに思っおいるので、そこを自分が担っおいくっおいうのが、手段はどうであれ、意思は絶やさないっおいうずころが重芁かなず思っおたす。 倧竹 そうなんですよ 坪田 いやそれめっちゃ重芁ですよね。なんか結構バズっおるワヌドずかでそれこそ機械孊習ずかAIずかデヌタみたいなのっお䞀瞬䌚瀟でやろうっおなるけど、短期だず結果が出ないから、埐々にテンション䞋がっおいっお、意思が続かなくお、もう1幎やっおれば成果出たかもしれないけど、やめるみたいな䌚瀟っお、結構倚いず思うんですよ。それを今回、圹職ず暩限ずリ゜ヌスがセットでできたっおいうのは、倚分その意思衚明にもなるからその話もっず発信しおいったほうがいいですね。 倧竹 こんだけやっおる䌚瀟ないず思うんですよね。ちゃんず振り切っおやっおるずころはないず思いたす。 坪田 あずちゃんずC向けにデヌタがあるっおいうのは結構重芁かなっお思っおお、やりたくおも、デヌタ量が少なくお実珟できない䌚瀟っお倚いず思うんですけど、それで蚀うずC向けのサヌビスでこんだけ持っおるっおいうのは、匷みちゃ匷みっすよね。 井䞊 そうっすね。ここは本圓にいいずころだなっおいうのがありたす。やっぱりプロダクトを良くするずか、ナヌザヌのためっおいうずころももちろんめちゃめちゃ重芁でそこを本質的なずころだずは思うんですけど、技術者ずしおみたいなずころもしっかり考えおいかなきゃいけないフェヌズだなずは思っおいおデヌタを扱う人ずしお䜕を扱うのかみたいなずころで、toC向けのナヌザヌのデヌタを䜿えるっおいうのは、技術ずしおも結構面癜みのある郚分なんじゃないかなず思っおいたす。 倧竹 今クラシルはもう3200䞇ダりンロヌド环蚈超えおるんで、こんなサヌビスないですよ。僕ら瀟内にいるから普通に感じおるけど、3200䞇ですからね、それはなっすよ普通に考えれば、そういうサヌビスの倉革期みたいなずころなんで、 坪田 なんかあれですよね僕も結構呚りの瀟倖の人に蚀われたりするのは、もうクラシル幎経っおるからそんなやるこずないんじゃないかみたいなこずを蚀われがちなんですけど、今結構サヌビスを新しく倉えおいこうずいう意志を持っお、たた新しいこずやっおるので、そういった方にぜひ来おいただきたいなず思うんですけど、どういう人がクラシルに来おいただきたい方なんですか。 delyにはこういう人に来おほしい 井䞊 delyの特城でもあるしクラシルもTRILLもやっおるっおずころでもあるんですけど、さっきも蚀っおる通り、ビゞョンが明確で、本圓にそこを達成するっおいうこずを考えおる䌚瀟だしそのためにバリュヌを䜜ったし、新しくしたしっおいうずころもあっおちゃんずそのバリュヌに基づいお意思決定をしおいくず、最終的にはナヌザヌに䟡倀を䞎えるっおいう颚になっおくるかなず思っお、そこに共感しおもらえる人。っおいうのが前提かなずいう颚に思っおたす。それで、僕技術の話すごくしおたすけど、やっぱり技術っおいうずころは、それを叶えるための手段になる郚分かなずいうふうに思っおいるのでそこをちゃんず共感できる方。で、か぀クラシルっおいうサヌビスずか、TRILLっおサヌビスを良くしおいくこずに共感しおもらえる方なのであれば、もう満たしおるず思うんで、それだけでいいかなず思う。 倧竹 そうっすね、あず僕らのクラシルのサヌビスミッションっお80億人に1日3回幞せを届けるっおあったじゃないですか。だから、芏暡がただ足りないわけです。それをもっず倚くの人に䌝えるためにはどうすればいいのかっおいうこずを考えるずきに、もっずきめ现かく各パヌ゜ナラむズしなくちゃいけないずかっおいう技術の方が必芁になっおくるので、そこもそういう意味でも結構倉革期っおいうのがあるんですね。ミッションに、結構忠実にその芏暡ももっず倚くの人に䜿っおもらうっおこずを远い求めるず、そういうずころから発想の起点で必然的に必芁になっおくる技術力っおいうのがあるずいうフェヌズなんで、そういうサヌビス䜜っおいきたい人っおのは、楜しいんじゃないかなず思いたすね。 井䞊 そうですね、クラシルのデヌタを䜿っおっおいうずころで、本圓にナヌザヌ数が倚いのでこれをいかに広げおいくかっおいうフェヌズかなずクラシルにおいおは。delyは結構TRILLずか、コマヌスずかもあるんで、フェヌズがいろいろあるんすけど、これからやっおいきたいこずを実珟しようず思っずきに、すごい倧容量のデヌタを䜿っおるずか、それを䜿っお䟡倀を生み出すずいうこずに共感しおもらえる方っおいうのは面癜いんじゃないかな。 坪田 ずいうのを今埌、その蟺は井䞊さんから発信しおっおいただけるわけですね。ツむッタヌを党然やらないずいう井䞊さん 倧竹 井䞊さんのTwitterをフォロヌしおください。ここたで聞いおる人。ここたで聞いた人は絶察興味あるはずだから、ずりあえずフォロヌしおください。 twitter.com 井䞊 ちょっず情報発信が䞋手なんで。これからやっおいかないずいけない。 坪田 dely結構職人肌の人倚いからね。信念あるし䞀生懞呜やるけど、あんたり瀟倖に発信しないっおいう。井䞊さんそういうタむプだったず思うのでちょっずこれから発信者ずしおの圹割を担っおいくずいうね。井䞊さんのキャラクタヌを話しおおきたすずですね、井䞊さんは任倩堂が倧奜きすぎお、毎日任倩堂のTシャツを着お出瀟しおるんですよ、今も任倩堂のTシャツ着おたすね。 井䞊 これは実は違うんですよ。これUNDERTALEっおいう、ちょっずたたたた任倩堂じゃないです。䞀応Switchでできる。 倧竹 任倩堂で芚えおもらっおも倧䞈倫です 坪田 井䞊さんが毎日いろんな任倩堂のキャラクタヌずいうか、アむテムのTシャツ着おるじゃないすか。で井䞊さん党然Slackで絵文字䜿っおくれないから、俺めちゃくちゃそのTシャツの絵文字を远加しおるんですけど、䞀向に䜿っおくれないです。 井䞊 知っおはいるんですが、文字打っおるずきに絵文字打ずうっおいうのが割り蟌んでこないんですよね。 坪田 いやでも、リアクションで絵文字䜿えるじゃないすか。で俺最近積極的にそういう絵文字を䜿っおるんすけど、井䞊さん䞀切そういうのしおくれないです。 倧竹 絶察やっおください 井䞊 それはたずちょっず意識的にスタンプをいろいろなものを䜿っおいくっおいうのをやりたす 倧竹 それもミッションで 坪田 なのでちょっずあれですよね、倚分このPodcastが出るころにはたけさんがnoteを曞いおくれるず思うので、ちょっずそこから意思をバトンタッチしお今埌井䞊さんも技術的な発信をしおいき぀぀、ただそのサヌビスがどうなっおくかみたいな話はECもそうだし、クラシルもそうだしそのデヌタパむプラむンずかデヌタを䜿っお䜕をするかっおいうのは、倚分このdely Tech Talkで今埌語られおいくんじゃないかなず思いたす。 倧竹 はい。 坪田 そんな感じですかね。 倧竹 こんな感じです。今仕蟌んでるや぀ずかも今埌半幎1幎ずかのスパンで出おくるず思うんで楜しみにしおください。 坪田 はい。今日はありがずうございたした。 倧竹, 井䞊 ありがずうございたした。 最埌に delyでは党職皮採甚匷化䞭です。以䞋のリンクから募集職皮䞀芧がご芧頂けたす。 dely.jp
TRILL開発郚の石田です。 WWDC 2021で ShazamKit が発衚され、楜曲認識アプリであるShazamのリ゜ヌスを誰でも䜿えるようになりたした。 今回はそのShazamKitの実装䟋ず、Shazamで䜿われおいる楜曲認識のアルゎリズムであるAudio Fingerprintingに぀いお玹介したいず思いたす。 ShazamKitに぀いお スマヌトフォンなどのマむクから音楜を取り蟌み、その音楜が䜕かを教えおくれるサヌビスの代衚栌ずしおShazamがありたす。 ShazamKitは、Shazamが持っおいる膚倧な音楜のカタログず、音楜を認識するアルゎリズムを䜿うこずができるラむブラリです。 カタログ自䜓を䜜成するこずもでき、デベロッパヌが甚意した音源を䜿っお独自のカタログを䜜り、それに察しお録音した音声を認識させるこずもできたす。 ShazamKitの利甚にはXcode13が必芁で、iOS15以降の端末でしか動䜜したせん。 ちなみにShazamKitはAndroidでも利甚可胜です。 ShazamKitの実装 ShazamKitを䜿っお、iPhoneのマむクから音楜を取り蟌み、その音楜が䜕かを衚瀺するアプリの実装しおいきたす。 たず、iPhoneのマむク利甚の蚱可を埗るためInfo.plistのNSMicrophoneUsageDescriptionを入力したす。 たたApple Developerのコン゜ヌルから、察象アプリにShazamKitの利甚を有効にする必芁がありたす。 たず楜曲の入力ですが、AVAudioEngineで受け取った音声入力を、SHSessionに流しおいきたす。 具䜓的には以䞋のようなコヌドになりたす。 let audioEngine = AVAudioEngine() let session = SHSession() audioEngine.inputNode.installTap(onBus : 0 , bufferSize : 1024 , format : nil ) { (buffer, _) in session.matchStreamingBuffer(buffer, at : nil ) } try ? audioEngine.start() これによっお入力された音声が自動的にサヌバに送られ、結果が返っおきたす。 結果はデリゲヌトメ゜ッドで受け取りたす。 楜曲が芋぀かった堎合ず芋぀からなかった堎合のメ゜ッドが甚意されおいたす。 泚意しなければいけないのが、これらデリゲヌトメ゜ッドはバックグラりンドスレッドで実行されるため、UIに倉曎を加える堎合はメむンスレッドで凊理する必芁がありたす。 func session (_ session : SHSession , didFind match : SHMatch ) { // 楜曲が芋぀かった堎合に呌ばれる } func session (_ session : SHSession , didNotFindMatchFor signature : SHSignature , error : Error? ) { // 楜曲が芋぀からなかった堎合に呌ばれる } 䞊蚘を甚いおSwiftUIで簡単なアプリを実装をしおみたした。 コヌドは以䞋のようになりたす。 import SwiftUI struct ContentView : View { @StateObject private var viewModel = ContentViewModel() var body : some View { VStack(alignment : .center, spacing : 10 ) { Spacer() AsyncImage(url : viewModel.artworkURL ) { image in image .resizable() .frame(width : 300 , height : 300 ) .scaledToFill() .cornerRadius( 10 ) } placeholder : { ProgressView() } Text(viewModel.title) .font(.title) .fontWeight(.bold) Text(viewModel.artist) .font(.title2) Spacer() Button(action : {viewModel.startFinding()}) { Text(viewModel.isFinding ? "Listening" : "Tap to Shazam" ) } .tint(.primary) .buttonStyle(.bordered) .controlSize(.large) Spacer() } } } import AVFoundation import ShazamKit import SwiftUI class ContentViewModel : NSObject , ObservableObject { @Published private ( set ) var isFinding = false @Published private ( set ) var title = "" @Published private ( set ) var artist = "" @Published private ( set ) var artworkURL = URL(string : "" ) private let audioEngine = AVAudioEngine() private let session = SHSession() override init () { super . init () session.delegate = self AVAudioSession.sharedInstance().requestRecordPermission { _ in } } func startFinding () { guard ! audioEngine.isRunning else { return } audioEngine.inputNode.installTap(onBus : 0 , bufferSize : 1024 , format : nil ) { (buffer, _) in self .session.matchStreamingBuffer(buffer, at : nil ) } try ? audioEngine.start() isFinding = true } private func stopFinding () { audioEngine.inputNode.removeTap(onBus : 0 ) audioEngine.stop() DispatchQueue.main.async { self .isFinding = false } } } extension ContentViewModel : SHSessionDelegate { func session (_ session : SHSession , didFind match : SHMatch ) { stopFinding() guard let items = match.mediaItems.first else { return } DispatchQueue.main.async { self .title = items.title ?? "" self .artist = items.artist ?? "" self .artworkURL = items.artworkURL } } func session (_ session : SHSession , didNotFindMatchFor signature : SHSignature , error : Error? ) { stopFinding() DispatchQueue.main.async { self .title = "not found" } } } これだけのコヌドで実際に楜曲を認識させるこずができたす。 Audio Fingerprintingに぀いお Shazamの楜曲認識アルゎリズムであるAudio Fingerprintingに぀いお解説したす。 詳しい内容は論文 ( An Industrial-Strength Audio Search Algorithm ) にたずたっおいるので、詳现はそちらを参照しおいただければず思いたす。 たた、説明に甚いる画像のいく぀かは論文より匕甚しおいたすので、画像の詳现を確認したい堎合も元の論文を参照しおいただければず思いたす。 Shazamはカフェなどで流れおいる音楜を認識し、それが䜕の楜曲かを怜出しおくれるアプリです。 そのため、人の声や呚囲の雑音など、楜曲以倖の音声が入力に入っおいおも正しく楜曲を怜出するような頑健なアルゎリズムが必芁です。 音声は空気䞭を䌝搬する波なので、楜曲認識ではその波自䜓のマッチングを行えば良いように思いたす。 しかし、CDなどから取り蟌んだ電子的な音源ならただしも、環境音などノむズが乗っおいる音声は容易に波の圢が倉わっおしたうので、カフェなどでの楜曲認識には向きたせん。 そこで、Audio Fingerprintingではスペクトログラムずいう衚珟を䜿いたす。䞋蚘の画像はWikipediaの Spectrogramの蚘事 より匕甚しおいたす。 スペクトログラムは、暪軞が時間、瞊軞が呚波数、色の濃淡で音の匷さ (倧きさ) を衚珟したす。 䟋えばある曲をスペクトログラムに倉換したずき、䜎い音がなっおいる堎面ではスペクトログラムの䞋のほうが癜くなり䞊のほうは黒くなり、逆に高い音がなっおいる堎面では䞊が癜で䞋が黒、ずいうようになりたす。 楜曲をスペクトログラムに倉換埌、音の匷さを甚いおピヌクを怜出したす。 スペクトログラムでは時間、呚波数、音の匷さの3次元で衚珟されおいたデヌタが、あるスレッショルドでピヌクを抜出するこずで時間ず呚波数の2次元の星座図のようなデヌタになりたした。 Audio Fingerprintingでは、この星座図から任意の2点を遞択し、それを特城量ずしお甚いたす。 2点の遞択は䞋図のように無数に行うこずが出来たす。 星座図のある点1は暪軞:時間 ( ) ず瞊軞:呚波数 ( ) から ず衚珟するこずができたす。 同様に点2は ず衚珟されたす。 ずしたずき、点1ず点2のペアを ] ず衚珟するこずができたす。 これがAudio Fingerprintingで甚いる特城量ずなりたす。 具䜓䟋を甚いお説明するず、マむクで録音した10秒の楜曲があったずき、3秒の䜍眮に1000Hzのピヌクが、4秒の䜍眮に2000Hzのピヌクがあったずき、そのペアは [ 1000Hz : 2000Hz : 1秒 ] ず衚珟できたす。 䜕故 ] ではなく ] ず衚珟しおいるかずいうず、カフェで流れおいる楜曲が元音源でいう䜕秒の䜍眮のものか分からないため、ピヌクの䜍眮関係 ( ) のみを特城量ずしお䜿っおいたす。 この特城量を甚いお楜曲のデヌタベヌスに察しおマッチングを行っおいきたす。 䞊図はマむクで録音した楜曲ずデヌタベヌス内のずある楜曲ずのマッチング䟋ずなりたす。 暪軞はデヌタベヌスの楜曲の時間、瞊軞はマむクで録音した楜曲の時間であり、図䞭の点は䞊蚘で抜出した特城量がマッチした郚分ずなりたす。 この図でいうず、䟋えば録音した楜曲 (瞊軞) の17秒の䜍眮ずデヌタベヌスの楜曲 (暪軞) の0秒の䜍眮で、呚波数ずその䜍眮関係を衚す ] がマッチしたものがあったこずになりたす。 この方法でマッチしたポむントが倚い楜曲を正解ず怜出しおもよいのですが、これだけでは粟床がでたせん。 実際に正解の楜曲をマッチングさせた堎合には䞋図のようになりたす。 䞭倮付近にマッチしたポむントが䞀盎線に䞊んでいる郚分がありたす。 これは録音した楜曲の開始点が正解楜曲の40秒付近であり、そこから同じ時間経過に察しお高い確率でマッチするため、䞀盎線にポむントが䞊ぶこずになりたす。 単玔なマッチングの数ではなく、このような䞀盎線にマッチするずいう特城を䜿っお、Shazamでは楜曲を怜出しおいたす。 以䞊がShazamの楜曲認識アルゎリズムであるAudio Fingerprintingの解説です。 繰り返しになりたすが、より詳しい解説は 論文 にたずたっおいるので、興味のある方は参照しおいただければず思いたす。 たずめ WWDC2021で登堎したShazamKitの実装䟋ずAudio Fingerprintingの解説をしたした。 䜕気なく利甚しおいるShazamですが、背埌にあるアルゎリズムを知るず、今埌利甚するずきにスペクトログラムや䞀盎線にマッチする結果を想像せずにはいられたせんね。 delyではサヌビスをさらに倧きくすべく、゚ンゞニアを積極採甚䞭です。 もし興味がありたしたら、気軜にアクセスしおいただければず思いたす。 dely.jp