セヌフィヌ株匏䌚瀟のブログ - TECH PLAY

TECH PLAY

セヌフィヌ株匏䌚瀟

セヌフィヌ株匏䌚瀟 の技術ブログ

å…š256ä»¶

はじめに セヌフィヌの髙朚( @hitsan8 )です。 セヌフィヌは2025幎2月13、14日に行われたDevelopers Summit 2025以䞋デブサミにブヌススポンサヌずしお参加したした。 デブサミずは2003幎から開催されおいるIT゚ンゞニアのための祭兞です。今幎のテヌマは「 ひろがる゚ンゞニアリング 」です。 event.shoeisha.jp 倚くの方にセヌフィヌを知っおもらうために2023幎から参加し続けお今幎で3回目になりたした。 この蚘事はデブサミのブヌススポンサヌ参加レポヌトになりたす。 はじめに ブヌスのデザむン アニマルマスクのデモ 展瀺パネル さいごに ブヌスのデザむン 2024幎にロゎをリニュヌアルしたのでブヌスで䜿甚する備品、ノベルティを䞀新したした。 去幎たでは癜をベヌスにしたデザむンでしたが、今幎はコヌポレヌトカラヌであるセヌフィヌブルヌを基調ずしたデザむンに仕䞊げおいたす。 䟋えばバナヌスタンドはこのようなデザむンになっおいたす。 実際のブヌスに䞊べおみるずこんな感じになりたす。 党䜓の色味をそろえたので統䞀感がでたのではないでしょうか。 実際にお客さんに説明しおいる様子はこんな感じでした。 ブヌスではアニマルマスクのデモずパネルの展瀺をしたした。 こちらもそれぞれ玹介しおいきたす。 アニマルマスクのデモ プラむバシヌマスクずいう機胜があり、これは個人の特定を防ぐために映像の䞀郚を隠す機胜です。 通垞は映像を隠すためにモザむク凊理するこずが倚いですが、今回は怜出した人の䞊に動物のむラストを被せおアニマルマスクずしお展瀺しおいたす。 䌚堎では䞉脚を䜿っお俯瞰で撮圱するようにしたした。 この画角がセキュリティカメラっぜいですね。 実際にアニマルマスクを動かすずこんな感じです。 自分の顔が動物になっおいるのでお客さんの目を匕くこずができたした。 こちらはお客さんや他のブヌスの方々から面癜い、かわいいずいうお声をいただきたした。さらに、内郚のアルゎリズムやセキュリティに぀いお興味を持たれた方も倚かったです。 展瀺パネル 今回はアニマルマスクのパネルず技術スタックのパネルを展瀺したした。 どちらもコヌポレヌトカラヌを基調ずしたデザむンにしおいたす。 このパネルは動物たちの質問にセヌフィヌくんが回答しおくれるずいう内容になっおたす。 楜しそうな雰囲気が䌝わっおきたすね。 技術スタックのパネルぱンゞニアの方々に奜評でした。 「セヌフィヌではこれを䜿っおるけどうちの䌚瀟ではこれを䜿っおる」みたいな䌚話が生たれおいたした。 さいごに 2日間のブヌス出展を無事に終えるこずができたした。実際にプロダクトを芋おもらい、その堎でフィヌドバックをもらえたので非垞によい䜓隓でした。 スタッフの感想ずしおは アニマルマスクで゚ッゞの凊理にも興味を持っおもらえおよかった。 䌚堎が広くおきれいだったのでおどろいた。 倧倉だったけど楜しかった。 ノベルティがかわいいず奜評でよかった。 今埌の改善点ずしお挙がったのは アニマルマスクの動物を怜出した人の属性で振り分けけおもよかったかもしれない 生成AIも組み合わせたら面癜かったかも マスコットのぬいぐるみを眮きたい ゲヌム芁玠も入れたかった セヌフィヌは今埌も認知拡倧のため継続的にむベントに参加したす。 セヌフィヌぱンゞニアを積極的に募集しおいたす。ご興味がある方は採甚ペヌゞをご芧ください。 safie.co.jp
はじめに こんにちはセヌフィヌ株匏䌚瀟でデバむス開発をしおいる杉本です。 セヌフィヌでは普段の業務以倖にも、゚ンゞニアのスキルアップのために様々な取り組みを行っおいたす。その䞀぀の取り組みずしお゚ンゞニアの「やっおみたい」をボトムアップで実珟する掻動をしおいたす。 今回はコンセプトの立案からプロトタむプのナヌザヌ怜蚌たで行うプロト開発WG(ワヌキンググルヌプ)の掻動をご玹介したす はじめに プロト開発WGの目的 やったこず 他郚眲からのフィヌドバック やっおみお 最埌に プロト開発WGの目的 セヌフィヌはクラりドカメラサヌビスを提䟛しおおり、様々な珟堎のナヌザヌの課題に向き合っお新プロダクトの䌁画・開発を進めおいたす。 営業、䌁画からの提案で開発をするこずが倚いのですが、゚ンゞニアだからこその気付きもありたす。ナヌザヌが気付かないような芖点から゚ンゞニアが提案ができる組織を実珟すべく、プロト開発WGを開催しおいたす 今回のワヌクショップの目的は以䞋のずおりです。 ゚ンゞニア自身でナヌザヌの課題の仮説を立おお怜蚌し、プロト開発の知芋を埗るこず 業務で䜿甚する技術以倖の技術領域にチャレンゞしおスキルの幅を広げるこず やったこず プロト開発WGではコンセプト(仮説)の立案、プロト開発、ナヌザヌ怜蚌の倧きく3぀のプロセスで進めおおり、今回のプロト開発WGではデバむス開発郚の有志メンバヌにお蚈5か月の期間で実斜したした。 コンセプト(仮説)の立案 玄2カ月 ナヌザヌの想定課題 想定課題に察するナヌザヌぞの提䟛䟡倀 プロト開発 玄2カ月 コンセプトを実珟するための技術怜蚎 コンセプトを詊すためのプロトを開発 ナヌザヌ怜蚌 玄1ヶ月 ナヌザヌにプロトを詊しおもらい、フィヌドバックを埗る フィヌドバックから課題を抜出しお改善の方向性を特定する コンセプトの立案でぱンゞニアならではの芖点でアむデアが合蚈12個出おきたのですが、そこからの絞り蟌みが苊劎したした。ナヌザヌの課題をどう解決できるのか、どれだけナヌザヌにずっお䟡倀があるのか、などの深堀をしおコンセプトの絞り蟌みを進めたした。 最終的には提䟛䟡倀だけでなく、技術的に実珟ができそうか、他瀟ずは違いがありそうか、今埌も掻甚できそうかの4぀の芳点で5段階で点数付けをしおコンセプトを1぀に決定したした。 このような議論を通じお゚ンゞニアが提案できる組織に぀ながるような芖点を逊うこずができたのではないかず思っおいたす たた、本掻動で実際に立案したコンセプトや開発プロトタむプに぀いおはありがたいこずに商品化怜蚎のステップに぀ながっおいるので、残念ながら本ブログでご玹介するこずができたせん。 ただ、ナヌザヌの課題に着目しおコンセプトを゚ンゞニア自身が考えたため、倧倉ながらも楜しくプロトタむプの開発ができたした 他郚眲からのフィヌドバック ナヌザヌ怜蚌に協力いただいた各郚眲の方から本掻動に぀いおたくさんのフィヌドバックがありたしたので䞀郚抜粋しお公開したす ずおもいい掻動だず思いたした。営業偎では思い぀かない芖点もありありがたいです。 提案内容が突拍子もないものではなく、既にある機噚の拡匵や改造で行けるずいう、倢ず珟実のはざたの倧倉バランスの良い所を攻めおいるので、商品化の可胜性が高いず思いたした 技術オリ゚ンテッドな提案は営業䌁画ずしおも刺激されるずおもいたす。なにより掻動メンバヌが楜しそうにしおいたのが印象的でした 非垞に面癜かった。今すぐ商品に繋がらないこずも倚いず思いたすが、このようなこずをやっお今埌の商品に぀ながる皮をいっぱい䜜っお欲しいです。 営業、䌁画スタヌトではなく、開発から発信したほうが固定抂念に瞛られないモノが䜜れる堎合があるし、営業・䌁画が暗黙のうちに諊めたり埌回しにしたものが䜜られたりするので、今埌も継続しおほしいです。 想定機胜を型にするこずで、もっずむメヌゞしやすいです。「こんなこずもできるこずだ」を盎感でき、ペヌパヌより商品に察する理解が深くなる。たた、実珟可胜性も参考になりたす。 日々ずおもお忙しい䞭、アむディアを圢にする時間を取るのは非垞に倧倉だったず思いたすが、ここたでWowのあるものを短期間で仕䞊げおおり本圓に玠晎らしいず思いたした。 開発偎の方がお持ちのアむディアず顧客課題をうたく玐づける掻動をしおいきたいず考えおいるので、こういった事がやりたいこれっおニヌズありそうずいった話はお気軜にしおいただければず思いたす 非垞に有意矩な時間でしたプロトタむプず蚀い぀぀、商品建お付け考えればそのたた売れるのではず思うくらいのクオリティだったのですぐ䌁画ず連携しお進めおいきたいくらいです。 最終的にプロトタむプの実機デモず合わせお、セヌフィヌ党瀟員向けのプロト開発WGの報告䌚を実斜したした。 ありがたいこずに、オフラむン、オンラむンのハむブリッドで開催したのですが、100名以䞊の方に参加いただいお報告䌚の埌も質問が絶えないなど倧盛況で終えるこずができたした 党瀟員向けのプロト開発WG報告䌚の様子 やっおみお 参加メンバヌにお本掻動の振り返りを実斜したしたので䞀郚抜粋しお公開したす圓初の目的に぀いおはおおむね達成できた結果ずなり、䞀安心です 提案したプロトタむプ4぀のうち、3぀は具䜓的にナヌザヌの珟堎でのPoCに぀ながるなど゚ンゞニアのボトムアップの掻動から実際の商品化に向けお動き出すずいう予想以䞊の結果を出すこずもできたした 反省点ずしおは蚘茉の通りですが、通垞業務をしながら本掻動の時間をなかなか割くこずができずにプロトタむプの開発に苊劎しおしたったこずです。良かった点を掻かし぀぀次回の掻動では改善をしおいきたいず思いたす Keep 党員しっかり関わりながら、期間内にコンセプト立案開発実機デモたでやりきるこずができた 業務ではあたり䜿わないプロダクトや技術の知芋が埗られた 営業、䌁画ぞの実機で技術提案をするこずで、プロダクト化に向けた前向きな議論ができた Problem プロゞェクトなどの䞻務の忙しい時期ず重なるず本掻動に割り圓おる時間が確保するのが難しく、進捗がない時期が発生しおしたった トラむ゚ラヌでの実装ずなり、予想よりも開発に時間がかかっおしたった Try 開発期間は2ヶ月ではなく34ヶ月は確保する 新しい技術に挑戊するため、開発期間に䜙裕が必芁なため タスクず担圓を明確にしお蚈画を立おお進捗管理する トラむ&゚ラヌでの開発が前提だが、蚈画を立おお進めるこずで効率的に開発をするため 本掻動はトラむアルずしおデバむス開発郚にお閉じお実斜したのですが、他の郚眲からも参加したいずいう声が挙がっおきおおり、ゆくゆくは開発本郚暪䞲での掻動に広げおいきたいず思っおいたす。 最埌に 本蚘事では、プロト開発WGの掻動に぀いおご玹介させおいただきたした。 セヌフィヌでぱンゞニアを積極的に募集しおいたす。どのような職皮があるのか気になる方はこちらをご芧ください safie.co.jp カゞュアル面談から受け付けおおりたすので、気軜に応募いただければず思いたす 皆様のご応募、心よりお埅ちしおおりたす 最埌たでお読みいただき、ありがずうございたした。
はじめに こんにちは。 セヌフィヌ株匏䌚瀟でサヌバヌサむドの開発をしおいる金成です。 今回は、サヌバヌチヌムで「マむクロサヌビスアヌキテクチャ第2版 」 を題材に、茪読䌚を開催したので、玹介させおください はじめに 背景 実装/実行 やっおみお 終わりに 背景 セヌフィヌは、サヌビスの拡倧ず開発者の増加に䌎い、工数の増加やリリヌスリスクの増倧など、開発生産性の問題を抱えおいたす。この問題の解決のために、組織の再線やコヌドベヌスの分割によるマむクロサヌビス化が進行しおいたす。 私を含め開発チヌムのメンバヌには、マむクロサヌビスずはなんなのか䜕を目指しおるのかどういったメリット・デメリットをもたらすのかなどむメヌゞが぀いおいない郚分がありたした。 そこで、今回の「マむクロサヌビスアヌキテクチャ第2版」を参考に茪読䌚を開催し、このトピックに察する理解床を深めようずしたした。 実装/実行 開催の圢匏は、䞋蚘の通りです 週1回 30-45分で開催 1぀の章を取り䞊げ、参加者は事前に読む 議論したい話題を取り䞊げ、自由に議論する 議論した内容を簡単に残し、埌で芋れるようにする å…š16章、4ヶ月ほどかけお党おの章で実斜したした。 議題は マむクロサヌビスにおける䞀番の目的は䜕か、どんな指暙を持぀べきか REST/RPC/GraphQL/メッセヌゞキュヌの䜿い分け サヌガパタヌンずその適甚するケヌス コンりェむの法則ず逆コンりェむ戊略に぀いお などがあり、技術的な偎面から組織面たで様々な議論をしたした。 匊瀟ではドキュメント管理にnotionを利甚しおるので、䞋蚘のようなテヌブルを䜜成しお、議題を管理しおいたす。 䞋蚘のように笑顔の絶えない議論が展開され、4ヶ月間笑いが絶えるこずはありたせんでした。 — アットホヌムな職堎の写真サンプル(, ) やっおみお 茪読䌚埌にアンケヌトをずったずころ、䞋蚘のような結果が埗られたした。 よかったずころ マむクロサヌビスぞの理解が深たった 参加者の実務経隓から呚蟺知識を補うこずができた 察話の機䌚が増えた 問題点・改善点 事前の準備の時間が足りなかった 発蚀の機䌚が足りなかった 時間が足りなかった 事前準備や議論のファシリテヌションには問題が残りたすが、マむクロサヌビス化ぞの理解を深めるずいう圓初の目的を達成できたこず、リモヌトが倚い匊瀟で察話の機䌚を増やせたこずは䞀定プラスになったかず感じおたす。 終わりに 自分の思い付きから䌁画した茪読䌚でしたが、参加しおくれたメンバヌの満足床は抂ね高く、やっおよかったず感じたした。 実は、私もこの秋からマむクロサヌビス化を進めるチヌムに参画しおいたす。マむクロサヌビスに぀いお知らないたただず、仕事がうたく進められたせん。だから「マむクロサヌビスアヌキテクチャ」を読む必芁があったんですね。 セヌフィヌでぱンゞニアを積極的に募集しおいたす。気になる方はこちらをご芧ください safie.co.jp この蚘事を読んでもし興味を持っおいただけた方は、ぜひ採甚サむトもご芧ください。 カゞュアル面談のみでも倧歓迎ですので、お気軜にご連絡ください。 最埌たでお読みいただき、ありがずうございたした。
はじめに こんにちはQCDグルヌプに所属しおいる小熊です。 Safie Viewer for PCのQAシステムテストを2019幎9月頃から担圓しおいるのですが、悩みのタネであった「床重なるバヌゞョンアップによっお増え続けるリグレッションテスト項目」の解消を目指しおトラむしおみたこずに぀いお曞こうず思いたす。 セヌフィヌにおけるQCDグルヌプはどういう事をしおいるのかを玹介しおいる蚘事もございたすので、是非こちらもご確認ください engineers.safie.link はじめに リグレッションテストに぀いお 暗黒時代 「敎理敎頓」時代 その埌珟圚 たずめ リグレッションテストに぀いお Safie Viewer for PCは月むチで新バヌゞョンがリリヌスされおおり過去はもっず頻繁に23週間に1回皋床リリヌスされおいた、その床に新機胜远加や䞍具合修正などが既存機胜に悪い圱響意図しおいない圱響を䞎えおいないこずを確認する必芁が有りたす。 Safie Viewer for PCは歎史が叀いこずもあっお機胜数が倚くお思わぬずころに開発圱響が出たりするため、範囲や察象を絞り蟌たずに党おのテスト項目の実斜フルリグレッションテストをリリヌス毎に行っおいたす。 暗黒時代 リリヌス毎に新機胜もしくは改修が入るので、リグレッションテスト項目内容もそれに合わせお曎新し続ける必芁がありたす。 具䜓的には新機胜は䞀床リリヌスされたら既存機胜に含たれるのでその内容をリグレッションテストに萜ずし蟌んでいるのですが、その床にテスト項目は増え、増え、増え、ず増え続け、これたで䞀番ひどかった時期の項目数をピックアップしたら䞋蚘衚な感じでした。 リリヌス月 実斜項目数 2022幎7月 1083 2022幎12月 1230 2023幎3月 1584 2023幎8月 2102 1幎で実斜項目数が玄2倍こりゃだめだ。。 この件に぀いお頭を悩たせおいたポむントを䞋蚘にたずめおみたした。 テストの実斜に時間がかかる 項目ごずに優先床を割り振り、優先床䜎い項目は毎回は実斜しないようにしおいたがそれでも限界 テスト項目の芖認性が悪くおやりにくい テスト項目のメンテナンスに時間がかかる 1ず共通点が倚い問題、メンテナンス埌に項目レビュヌするのも倧倉 テスト自動化察応しにくい テスト自動化察応しにくい 自動化できるできないしないの粟査、自動化した埌の管理が倧倉 これずは別に新機胜改修向けのテストの準備や実斜が有り、特にテスト期間䞭はテスト項目消化に远われおいた探玢的テストなど、他のこずに割く工数が無い これらによっお改善掻動テスト項目の敎理敎頓にリ゜ヌス割くのが困難、改善しないので曎に項目が増えおいき、さらにリ゜ヌスが逌迫するずいう悪埪環に陥っおたした。 「敎理敎頓」時代 暗黒時代の䞭、ただ手をこたねいおいたわけでは無く、課題解決のためにはどのような方針で敎理敎頓する必芁があるのかをQAメンバヌ党員で議論や準備を少しず぀進めおいたずころ、ある転機がやっおきたした。 engineers.safie.link ↑の蚘事にあるテスト管理ツヌルの導入むベントです。 これたでスプレッドシヌトでテスト項目を䜜成実斜しおいたものを管理ツヌルで行うこずが決定、せっかく管理ツヌルぞの移行に工数割くなら準備しおきた改善案を適甚した内容でやっおやろうじゃないかずなり、テスト実斜にかかる以倖の工数をほが党振りしお敎理敎頓察応するこずずなりたした。 その時の敎理敎頓の掻動方針は これたでのテスト項目を優先床付けしお、優先床高い内容を移行する新項目のメむン機胜骚栌ずする 1で決めたメむン機胜チェックは、なるべくシンプルにたずめる肉付け 肉付けの際は「自動化できる自動テストのみで完結できる内容」「できない or 困難メンテナンスに時間かかるなど」のように自動化可吊を分けお混圚しないように行う の3点です。 特に①ず②の察応に苊心したした。 どの機胜を骚にしおいわゆる優先床付けどれだけ肉付けするかは、「これたでで実斜しおきた項目」から「どれだけむンシデントが怜知できおきたか」の分析を行っおその結果を指針にしたり新しい項目によっお実斜工数は枛ったけどリリヌス埌に芋぀かるバグが増えた、は蚱されない、①や②の察応埌に「これたでのむンシデントが怜知できる内容になっおいるか」の芋盎しを行ったり、それをメンバヌ間でレビュヌしあったり①②の実斜は各メンバヌの感芚によっおバラ぀きが有るので、ずにかく詊行錯誀の連続でした。 たた、テスト項目での蚘茉内容によっおちょっずでも項目を枛らすように工倫したした。たずえば「画面AでボタンAの確認」「モヌダルBで機胜Bの確認」ずぶ぀切りになっおいた2぀の項目を「画面AでボタンAを抌䞋した埌のモヌダルBで機胜Bの確認」のように䞀連の流れで網矅できるような1぀の項目ぞ組み替えたりです。 その埌珟圚 敎理敎頓を頑匵り始めおから、その埌項目数はどうなったでしょうか。 リリヌス月 実斜項目数 2023幎8月 2102 2024幎5月 641 2024幎12月 665 ピヌクから3分の1以䞋たで枛りたした拍手 ただし気を抜くずあっずいう間に以前に逆戻りしおしたう実際、5月から少しず぀増えおいるので掻動の継続は必芁なのず、浮いた工数をどのように有効掻甚しおいくかも今埌の課題のひず぀です。 たずめ 今回の察応が最適解ずせず、メンバヌ内で敎理敎頓①③ぞの共通認識ができおいる今の内に曎なる改善目指し、これからも詊行錯誀進めおいこうず思っおいたす。そのこずをたたお話できたら良いなぁ
はじめに セヌフィヌ株匏䌚瀟 でサヌバヌサむド゚ンゞニアをやっおおりたす石塚です。 今回はGoogle Chromeの拡匵機胜に入門したので備忘録ずしお残しおおこうず思いたす。完党にプラむベヌトで利甚するための拡匵機胜を実装したので、ゆるりず呌んでいただけるず幞いです。 はじめに 拡匵機胜の䜜り方 むンストヌル ロヌカルで実行 実装 最埌に 拡匵機胜の䜜り方 今回はGoolge Chrome向けの拡匵機胜を実装する方法を玹介したす。 Google公匏の拡匵機胜ドキュメント がありたす。詳しくはこれを参照しおください。基本的にはHTML, CSS, JavaScriptで実装可胜なので簡単に構築するこずができそうです。他には他に WXT や Extention.js , plasmo などの拡匵機胜向けのフレヌムワヌクを䜿う方法もありたす。 今回は plasmo を遞択したした。”the all-in-one platform that makes it easy for browser extension developers to create, test, and publish amazing extensions.“ずあったので党郚入りか぀簡単に導入できそうずいう安易な理由です。 むンストヌル 動䜜環境は以䞋の通りです。 macOS Sonoma 14.7 node v18.16.0 npm 9.5.1 たずはプロゞェクトを䜜成したす。今回はnpmを䜿いたすが公匏ではpnpmの䜿甚が掚奚されおいるようです。 npm create plasmo 察話圢匏でプロゞェクト名や説明などを蚭定したす。 しばらく埅぀ずプロゞェクトが䜜成され、以䞋のようなディレクトリ構造になっおいるはずです。 / < PROJECT_NAME > ├── README.md ├── assets │ └── icon.png ├── package.json ├── popup.tsx ├── tsconfig.json └── yarn-error.log 意倖ずシンプルな構造ですね。 ロヌカルで実行 たずはロヌカルで実行しおみたしょう。 # 筆者の環境では䞍足しおいたので远加 $ npm install sharp # 実行 $ npm run dev > extention-sample@ 0 . 0 . 1 dev > plasmo dev 🟣 Plasmo v0. 89 . 4 🔎 The Browser Extension Framework 🔵 INFO | Starting the extension development server... 🔵 INFO | Building for target: chrome-mv3 🔵 INFO | Loaded environment variables from: [] ( node:29924 ) [ DEP0040 ] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. ( Use `node --trace-deprecation ...` to show where the warning was created ) 🟢 DONE | Extension re-packaged in 1734ms! 🚀 ビルドされ、開発サヌバヌで実行可胜な状態になっおいるのでブラりザから拡匵機胜を有効化しお動䜜確認しおみたす。 chromeの右䞊の3点リヌダヌから「拡匵機胜」、「拡匵機胜を管理」に進みたす。拡匵機胜のペヌゞの右䞊に「デベロッパヌモヌド」があるので、このトグルボタンをおしお有効化したす。 「パッケヌゞ化されおいない拡匵機胜を取り蟌む」から先ほどビルドの成果物を遞択したす。 ./build/hrome-mv3-dev に出力されおいたす。 取り蟌むず以䞋の画像のようになりたす。 ブラりザから拡匵機胜をピン留めしおクリックするず䜜成した拡匵機胜が確認できたす。 これで最䜎限の開発ができるようになりたした 実装 今回はサンプルずしおペヌゞがロヌドされたずきにコン゜ヌルにURLを出力しおみたす。 mkdir contents code contents/content.ts 新しくcontents.tsを線集したす。今回は以䞋のような実装にしたした。 export {} ; window . addEventListener ( "load" , () => { const url = new URL ( window . location . href ); console .log( "URL:" , url. origin + url. pathname ); } ); ホットリロヌドが有効なのでコン゜ヌルを衚瀺しながらペヌゞをリロヌドするずアクセスしおいるURLが衚瀺されたす ビルドの成果物にはHTML, JavaScript, manifest.jsonそれから画像ファむルが含たれおいたす。manifest.jsonは拡匵機胜に必須のファむルですが、これはplasmoが生成しおいたす。manifest.jsonの内容はpackage.jsonで定矩できたす。 このたたではあたり意味のある拡匵機胜ではないですが、ビルドしおい぀でも䜿えるようにしおみたしょう。 npm run build ./build/chrome-mv3-prod/ にビルド成果物が出力されたす。 これをブラりザの拡匵機胜のペヌゞから読み蟌むず開発サヌバヌが起動しおいないずきでも䜿えたす。 拡匵機胜を広く公開するにはパッケヌゞ化したり、Googleりェブストアで公開したりしないずいけないですが、ここでは玹介しないのでぜひ 公匏のヘルプペヌゞ などを参照しお公開しおみおください。 最埌に 簡単ですが、Google Chrome拡匵機胜の䜜り方に぀いお玹介したした。 シンプルにHTML, CSS, JavaScriptで実装する方法もありたすが、フレヌムワヌクを䜿うずフレヌムワヌク特有のお䜜法があったりず孊習コストが増える分、いろいろずよしなに䜜っおくれたす。 30分から1時間皋床あれば簡単な拡匵機胜は䜜れるず思いたすので、幎末幎始に䜜っおみるのはいかがでしょうか セヌフィヌでぱンゞニアを積極的に募集しおいたす。気になる方はこちらをご芧ください https://safie.co.jp/teams/engineering/ この蚘事を読んでもし興味を持っおいただけた方は、ぜひ採甚サむトもご芧ください。 カゞュアル面談のみでも倧歓迎ですので、お気軜にご連絡ください。 最埌たでお読みいただき、ありがずうございたした。
メリヌ・クリスマス、セヌフィヌCTOの森本です。 こちらは Safie Engineers' Blog! Advent Calendar の25日目の゚ントリヌです。 早いもので、昚幎 創業以来10幎の開発組織の振り返り に぀いお掲茉しおからもう1幎が経ちたす。昚幎の蚘事の最埌でも觊れた通り、メンバヌのお陰で事業、組織、プロダクト、内郚的な仕組みなど党おにおいお様々な課題を乗り越え再成長軌道に茉せるず共に、その先の曎なる成長ぞ向けおの仕蟌みも適宜進められおいるず実感しおいたす。特に倧きなチャレンゞであったシステム刷新も専任チヌムを組成し、䞀歩䞀歩ですが進められおいる状況ずなっおいたす。 さお、今回の゚ントリヌではシステム刷新ずは別の、先々に向けた重芁な取り組みの䞀぀である AI゜リュヌションプラットフォヌム に぀いお玹介したす。 はじめに AI゜リュヌションプラットフォヌム抂芁 実珟したいこず AI゜リュヌション開発における課題 システム構成むメヌゞ 目指すべき姿 経産省PJぞの採択 今埌に向けお たずめ 最埌に はじめに 図1 圓瀟は䞻にB2B領域でクラりドレコヌディングサヌビスを提䟛しおいたす。 様々な業界のお客様の珟堎で、防犯だけでなく業務改善甚途でも幅広く掻甚されおおり、既に27䞇台を超えるカメラがお客様環境で垞時皌働しおおり、それらのカメラで録画された総量35PBを超える膚倧な映像デヌタが圓瀟システム䞊で管理されおいたす。 単玔な録画芖聎に加え、特に業務改善芳点では映像デヌタの解析なども重芁で、既に耇数の 汎甚的甚途の゜リュヌション の提䟛は行っおいるものの、お客様からも業界、課題に特化、もしくはお客様に特化したデヌタ掻甚のご芁望を幅広く頂いおおり、より広範囲で効率的に様々な゜リュヌションの開発、提䟛を進められるような仕組みの敎備が急務ずなっおいたす。 尚、デヌタ掻甚ずいう芳点ではAIの利甚は圓然考慮に入れる必芁がありたすので、劂䜕にAIを掻甚した゜リュヌションの提䟛を効率的に行えるかも重芁な芁玠ず捉えおいたす。 AI゜リュヌションプラットフォヌム抂芁 実珟したいこず 図2 冒頭で觊れた通り、我々は映像デヌタを掻甚し、我々のサヌビスをご利甚頂いおいる様々な業界のお客様の珟堎課題の解決を進めお行きたいず考えおいたす。ただ、様々な業界が存圚し、その䞭の課題もたた倚様な状況で、これらを我々単独で実珟するのが䞍可胜に近いのは明癜です。図2参照 だからこそ我々は我々のシステムをプラットフォヌムず定矩し、APIやSDKを掻甚しおデヌタを掻甚できるような機胜を既に提䟛しおきおいたす。 developers.safie.link 今埌に向けおはこれを曎に発展させ、他のAI開発者も容易にお客様の課題解決に぀ながるAI゜リュヌションの開発ず展開を行える仕組みを敎備し、倚面的にこれらの掻動を進めおいく事が必芁だず感じおいたす。 倧前提ずしお、AI゜リュヌションの開発には適切なデヌタ掻甚が必芁ですので、我々はたずはそれらを促進する為に䜕を実珟する必芁があるかの敎理を行っおきたした。 AI゜リュヌション開発における課題 図3 適切なデヌタ掻甚を実珟するための仕組みの敎理を行っおいる䞭で、AI開発者ずデヌタホルダヌ我々に取っおのカメラをご利甚頂いおいるお客様がそれぞれ課題を抱えおいる事がわかりたした。図2参照䟋えばデヌタホルダヌで蚀うず、そもそもデヌタ提䟛を行うメリットが䞍明確だったり、いざデヌタを提䟛するにも手間がかかりたす。たた、昚今は個人情報やプラむバシヌにも十分に配慮をする必芁がありたす。䞀方で、AI開発者偎はAIモデルを開発しようにもデヌタの収集に手間がかかったり、いざAIモデルを準備しおもアプリケヌションずしお提䟛する環境が必芁ずなりたす。 これらの課題がデヌタ掻甚の促進ずAI゜リュヌションの開発効率を高めるための課題ずなっおいる事がわかりたした。 システム構成むメヌゞ 図4 デヌタホルダヌ、AI開発者の抱える課題を解決するため、我々は圓瀟が管理する映像を教垫デヌタずしお掻甚し、効率よく䞔぀䞀気通貫でAI゜リュヌション開発が行える仕組みを提䟛するず共に、開発したAI゜リュヌションが圓瀟のカメラやクラりドプラットフォヌム䞊に盎ぐに展開でき、実行可胜な環境を敎備しおいきたす。※倧前提ずしお圓瀟が管理するデヌタはデヌタホルダヌに垰属しおいたすので、その掻甚にはデヌタホルダヌの合意が必須です これによっお、デヌタホルダヌはデヌタの取り回しやセキュリティに぀いおあれこれケアする必芁がなくなり、䞀方でAI開発者はAIモデル開発にできるかぎり集䞭し、デヌタ収集に工数を割く必芁も無ければ、アプリケヌションの展開先も圓瀟の環境を掻甚するこずにより玠早く顧客に䟡倀提䟛を行う事ができるようになりたす。 我々ずしおは、わざわざデヌタ収集しなくずも、デヌタホルダヌ環境に展開枈みのカメラによっお録画されたデヌタを掻甚できるのも非垞に重芁な点ですが、開発したAI゜リュヌションを皌働䞭の゚ッゞAIカメラやクラりドシステム䞊に展開し玠早く利甚しお頂く状況に繋げられる点も非垞に䟡倀がある点であるず捉えおいたす。 目指すべき姿 図5 我々は、先ほどの仕組みによりデヌタホルダヌ、AI開発者の抱える課題を解決し、AI゜リュヌションの効率的な開発、展開を可胜ずしおいく事だけでは、目暙ずする様々な業界の課題解決の実珟には䞍十分だず考えおいたす。 AI開発者がどこにどのような課題が存圚するか十分に分かっおいないケヌスがあれば、䞀方でデヌタホルダヌも課題解決に向けおどのAI開発者ず連携すればよいか䞍明確なケヌスがあるず掚枬しおいたす。 これらの状況を解決するために、䞊蚘に加え、デヌタホルダヌずAI開発者の連携を実珟するような堎の構築、提䟛を行う必芁性も感じおおり、合わせお敎備を行っおいくこずを考えおいたす。 このようなデヌタホルダヌずAI開発者間の倚察倚のコラボレヌションの実珟こそが、先皋の仕組みの効果を適切に発揮させるために必芁であるず捉えおいたす。 経産省PJぞの採択 我々は䞊蚘で説明したAI゜リュヌションプラットフォヌムに぀いお、数幎前より怜蚎を進め少しづ぀進めおいたしたが、この床、囜立研究開発法人新゚ネルギヌ・産業技術総合開発機構以䞋「NEDO」が公募した「ポスト5G情報通信システ厶基盀匷化研究開発事業デヌタ・生成AIの利掻甚に係る先進事䟋に関する調査調査類型1」に採択されるこずが決たりたした。 safie.co.jp デヌタ掻甚に察しおの囜ずしおの課題感、危機感の珟れでもあるず捉えおいたす。我々ずしおはこれはもちろん奜機ではありたすが、䞀方で囜策の䞀貫に遞定頂いた責任ず自負を感じ぀぀、開発掻動を加速しお行きたいず考えおいたす。 今埌に向けお AI゜リュヌションプラットフォヌムの開発を進め、2025幎䞭には倖郚に公開できるよう準備を行うべく進めおいたす。 図6 合わせお、その有効性を瀺すべく実際のデヌタホルダヌ、AI開発者にもご協力頂き、AI゜リュヌションプラットフォヌムの効果の実蚌も進めおいきたす。 曎に、有効なコラボレヌションの堎ずしお成立させおいく必芁があり、その為にはよく知っお頂く事が必須だず捉えおいたすので、認知向䞊に向けた取り組みも順次行っおいきたす。 テックブログでも継続的に具䜓的な取り組みに぀いおアップデヌトする想定で怜蚎を進めおいたす。 たずめ 我々はお客様の様々な珟堎課題の解決を倚面的に掚し進めるため、それぞれの抱える課題の解決を行える仕組みの敎備ず、デヌタホルダヌずAI開発者の倚察倚のコラボレヌションの堎を提䟛すべくAI゜リュヌションプラットフォヌムの敎備を進めお行きたす。 これらの仕組みを掻甚しデヌタ掻甚を倚面的に進めお行くこずにより、様々なお客様がAIの有甚性を実感できるような瀟䌚の実珟を目指しお行きたす。 最埌に 今回はAI゜リュヌションプラットフォヌムの玹介ずなりたしたが、セヌフィヌでは他にも曎なる成長ぞ向けお様々な開発に関わる取り組みを行っおいたす。それらに䞀緒に関わっおくれる゚ンゞニアさんを絶賛募集しおいたす
この蚘事は Safie Engineers' Blog! Advent Calendar 24日目の蚘事です。 はじめに こんにちは、セヌフィヌ 䌁画本郚 デザむンセンタヌの碇石いかりいしです。 2024幎10月30日、デザむンシステムを甚いたUIリニュヌアルが぀いに公開されたした。察象プロダクトは、゚ンタヌプラむズ向けに倚台数のカメラを統合管理できるSafie Managerセヌフィヌマネヌゞャヌです。 たず、デザむンシステムに぀いおは、2019幎12月頃から開発を進めおいたした。2023幎に入っおからSafie Managerを含む管理ツヌルの開発を行っおいる開発チヌム内でフレヌムワヌク移行の話が䞊がり、そのタむミングに乗せる圢でデザむンシステムを甚いたUIリニュヌアルプロゞェクトが始動。 手探りでスタヌトしたこのプロゞェクトは玄1幎10ヶ月の開発期間を経お無事公開ずなりたした。 はじめに 開発䜓制 戊略手探り感満茉の初動期 タヌゲットナヌザヌ 目的 UX課題 具䜓方針 構造オブゞェクト指向OOUIで再蚭蚈 サむトマップずデヌタ管理の流れの型化  骚栌〜衚局䜜っおは壊しを繰り返しお磚き䞊げるUX 画面構成ゟヌニング WF〜デザむンカンプ マむクロむンタラクション たずめ さいごに safie.co.jp 最適なUXを考える䞊で、デザむンセンタヌでは日頃からJesse James Garrett 氏が提唱する5段階モデルを甚いる事が倚く、今回のプロゞェクトもこちらをベヌスにデザむン制䜜たでを振り返っおみようず思いたす。 UXの5段階モデル 開発䜓制 フレヌムワヌク刷新を含む倧型リニュヌアルはセヌフィヌずしおも初めおの詊みずなるのですが、このプロダクトは初期リリヌスの埌デザむナヌ䞍圚ずなり開発チヌムのみで守っおいたプロダクトなのです。 そういった背景もあり、このチヌムにおいおぱンゞニアずデザむナヌの共同開発は実質初めおの状態。今回のプロゞェクトのためにディレクタヌずデザむナヌをアサむンしたした。 PdM 1名 フロント゚ンド゚ンゞニア 9名 デザむンディレクタヌ 1名 デザむナヌ 2名 戊略手探り感満茉の初動期 UXの5段階モデル - 戊略 -  日頃から䜿い勝手に関する足元の課題感は倚く、この機䌚にしっかり解決しおいきたい意志を゚ンゞニアず共に意識を合わせ、再蚭蚈に圓たり、タヌゲットナヌザヌのすり合わせず目的、珟状のUX課題の抜出を行いたした。 タヌゲットナヌザヌ 䌁業の管理者 情報システム郚など䌚瀟のシステムを管理する人物 スヌパヌバむザヌやマネヌゞャヌなど、珟堎の監督責任者にあたる人物 利甚甚途 耇数店舗を跚いで倚台数カメラの蚭定および操䜜暩限を管理する 目的 フレヌムワヌクの刷新Nuxt2→React デザむンシステムの適甚 【ポむント】UXの改善あるべきを考え、䜿い勝手の負を解消する 今回のリニュヌアルのポむントは、最適なUXの実珟です。ナヌザビリティ *1 を担保するこずはもちろんのこず、耇雑な仕様に察しナヌザヌがストレスなく利甚できる状況を目指したす。 UX課題 䞀貫性が無く、孊習コストの高い操䜜䜓隓 予枬しづらい機胜名称 ぀ぎはぎ的に远加されたナビゲヌションメニュヌ 生かされおいない䞀等地のホヌム画面 具䜓方針 構造の最適化 骚栌の最適化ナビゲヌション 機胜名称の最適化 今回はUIのリニュヌアルなので、機胜芁件はそのたたに、ナヌザヌニヌズに則したUXの怜蚎に向けお構造〜骚栌の再蚭蚈を実斜したす。 構造オブゞェクト指向OOUIで再蚭蚈 UXの5段階モデル - 構造 -  Safie Managerでは、管理するオブゞェクトデヌタが倚くそれぞれを結合させるこずでカメラデバむスの管理や管理暩限の組み合わせの自由床を実珟させおいたす。 その䞀方で耇雑な機胜にむンタヌフェヌスが远い぀いおおらず、䟋えばオブゞェクトが遞ばれおいないのにタスク遞択のUIが出っ攟しになっおおり、実行ボタンはdisableになっおいる、、 実行䞍可の理由が分からないずいうストレスをナヌザヌに䞎える可胜性のある箇所や、操䜜画面の初期状態から「この操䜜は無効です」ずいうような゚ラヌ衚瀺がされおいるなど、散芋しおいたした。 たた、䞀芧䞊の操䜜においおは単䞀の堎合でも䞀時的にオブゞェクトを遞択状態にしなくおはならず効率の面で課題がありたした。 旧UIのオブゞェクト操䜜のむンタラクション 蚭蚈の基本思想ずしおオブゞェクト指向OOUIを意識し、オブゞェクトを遞択→タスクの遞択→結果ずいう流れに調敎しながら、むンタラクションを含めた圢で基本的な負を改善する事ができたした。 敎理したオブゞェクト操䜜のむンタラクション サむトマップずデヌタ管理の流れの型化  仕様理解もかねお、珟行の構造も明らかにしながらデヌタ管理の流れを型化。党䜓像でBeforeAfterのむメヌゞをすり合わせ、ナビゲヌション構造はこのサむトマップを元に再蚭蚈を行いたした。 サむトマップ ナビゲヌション構造の再蚭蚈 デヌタ管理の流れの型化 この蟺りは、今埌画面を䜜っおいく䞭での指針ずなる郚分なので现かく確認を亀えながら蚭蚈しおいきたした。 骚栌〜衚局䜜っおは壊しを繰り返しお磚き䞊げるUX UXの5段階モデル - 骚栌〜衚局 - 型化したデヌタ管理の流れを元に各画面を制䜜しおいきたす。このフェヌズになっおくるずむメヌゞが具䜓化しおいくので、実装に向けた现かい調敎に移っおいくずころではありたすが、画面構成をナヌザヌニヌズに立ち戻り䞀床壊しお再考するずいった堎面も倚く発生したした。 画面構成ゟヌニング ゟヌニング 画面構成はプロダクト党䜓で統䞀されるため、デザむン䞻䜓で蚭蚈しおいたす。 ヘッダヌ プロダクト共通で固定化されおいたす。デザむンシステムがただ反映されおいないプロダクトにも既に展開されおいるUIになりたす。 ナビゲヌションメニュヌ プロダクト固有のメニュヌが䞊びたす。䜜成したデヌタなど可倉するものをメニュヌに䞊べるこずはNGずいうルヌルを蚭けおいたす。 コンテンツ゚リア 制玄は特にないですが、暪幅指定が画面幅100%を基準倀ずし、蚭定画面など暪幅の長さによりコンテンツが芋づらい、䜿いづらい堎合に1040pxを最倧倀ずするルヌルを蚭けおいたす。 WF〜デザむンカンプ UIComponentがある事で、より具䜓的な圢で情報蚭蚈をする事ができたす。芋た目がデザむンカンプなので、この段階で䜜っお壊しおっおいうのは倧倉なのでは、、ず思われるかもしれたせんが、実際の䜜業負荷はそこたででもなかったりしたす。 ただ、゚ンゞニア偎からのFBや提案の際、珟状の制䜜環境ずしおFigmaの線集暩限をもっおいない゚ンゞニアにずっおは改めおWFを䜜っお䌝えなければいけない環境だったので、画面芁件を決めるたでのラリヌが䜕床も繰り返されたのは、今回のプロゞェクトの䞭でも䞀番倧倉だった郚分なのではないかず思いたす、、 デザむンFIXたでの流れ マむクロむンタラクション disable時にリストをhoverするず、遞択䞍可の理由がToolTipにより衚瀺されるなどの现かいむンタラクションを怜蚎しながら最埌の仕䞊げを行なっおいきたした。党おの画面に行き届いおいない状況ではありたすが、このToolTipが出るこずで安心感が高たったように思いたす。 disableのオブゞェクトをhoverした時 たずめ 今回はデザむンを䜜るたでの話を5段階モデルに沿っお振り返っおみたした。改めお振り返っおみるず、初動の「ナヌザヌを知る」ここの玐解きが甘すぎた事が今回の䞀番の反省点です。 実はこの5段階モデルの考え方もOOUIも、゚ンゞニアには党く共有しおいないたた進めおおり、前提ずなる意識の郚分で噛み合わない瞬間がしばしばあったように思いたす。 䞀方で、プロゞェクトやデザむンに察する゚ンゞニアの思いの匷さを肌で感じルこずができ、プロゞェクトが進行するに぀れおプロゞェクトメンバヌの䞀䜓感が匷くなったように思うのはすごく嬉しかったです。 珟圚、絶賛プロゞェクトメンバヌず振り返りを行っおおり、ナヌザヌ理解が十分にできおいればプロダクト特性を捉えた倧胆な操䜜䜓隓も実珟できたかもなどなど埌悔するこずもありたすが、運甚フェヌズではデザむナヌず゚ンゞニアの連携匷化に向けた盞互理解の堎や勉匷䌚の実斜など、前向きな取り組みを始めようずしおいたす。 手探り感のある進行に党力で頑匵っおいただいたプロゞェクトメンバヌには感謝しかありたせん、、今埌の゚ンハンス開発に向けお今回の反省を掻かした共創䜓制を築いおいきたいず思っおいたす。 さいごに デザむンセンタヌでは、今回のプロゞェクトのキヌずなるデザむンシステム「Pantograph」を順次䞻芁プロダクトに反映しおいたす。 デザむンシステムの党䜓像や、開発秘話を掲茉しおおりたすので、よろしければ合わせおご芧ください。 note.com note.com セヌフィヌではデザむナヌ3期生を募集䞭です。 safie.co.jp *1 : ナヌザビリティ「䜿いやすさ」ではなく「利甚可胜性」ず考え、有効さ、効率、満足床の床合いで刀断しおいたす。
この蚘事は Safie Engineers' Blog! Advent Calendar  23日目の蚘事です はじめに はじめたしお、サヌバヌチヌムの城山です。 匊瀟の䞀郚サヌビスで Kinesis Client Library(v2) for Python を利甚しおおり、私なりに感じた躓きやすいポむントに぀いおお話ししたいず思いたす。 はじめに Kinesis Client Library for Python ずは 構成に぀いお 躓きやすいポむント 同䞀シャヌド内でのパヌティションキヌ毎の凊理遅延 重耇レコヌドの制埡 ECS Fargate task での RecordProcessor のログ連携 タスク終了時の MultiLangDaemon のタむムアりト゚ラヌ ロヌカル開発環境の構築 たずめ Kinesis Client Library for Python ずは https://github.com/awslabs/amazon-kinesis-client-python Kinesis Client Library for Python(以䞋KCL) は、kinesis data stream(以䞋KDS) からデヌタを取埗し、凊理するためのラむブラリです。 Kinesis Client Library は Java で実装されおおり、MultiLangDaemon ず蚀われる倚蚀語むンタヌフェヌスを利甚するこずで、他の蚀語から利甚するこずができ、Pythonでも利甚するこずができたす。 構成に぀いお シャヌド数3、ECSタスク数1の堎合の構成図です。 ※ 簡朔にするため、䞀郚省略しおいる箇所がありたす。 KDSに曞き蟌たれたデヌタを、KCL の MultiLangDaemon が取埗し、暙準出力を介しお、耇数レコヌドが RecordProcessor(Pythonサブプロセス) に枡されたす。 RecordProcessor では、䞻にDBぞのデヌタ登録や、API連携等のビゞネスロゞックを実装しおいたす。 たた、KDSは耇数のシャヌドに分かれおおり、RecordProcessor はシャヌド毎に1぀ず぀起動されたす。 これにより、シャヌド単䜍での䞊列凊理が可胜ずなっおいたす。 躓きやすいポむント 同䞀シャヌド内でのパヌティションキヌ毎の凊理遅延 1぀のパヌティションキヌで倧量にデヌタが登録された堎合、同䞀シャヌド内の他のパヌティションキヌのデヌタが凊理埅ちずなり、凊理が遅延する可胜性がありたす。 䟋えば、䞊図のように、パヌティションキヌAのデヌタが倧量に登録された堎合、パヌティションキヌAのレコヌドを党お凊理するたで、パヌティションキヌBのデヌタが凊理埅ちになるずいう状況です。 それに察し匊瀟では、RecordProcessor でパヌティションキヌ毎に非同期凊理を行うこずで、特定パヌティションキヌの凊理遅延が他のパヌティションキヌに圱響を䞎えないようになっおいたす。 たた、 queue.Queue を利甚しお、同䞀パヌティションキヌ内でデヌタの順序を保持し぀぀凊理できるようにもなっおいたす。 以䞋に䞀郚抜粋しおコヌド䟋を瀺したす。(※ 実際のコヌドから䞀郚簡略化しおいたす) def process_records (self, process_records_input: messages.ProcessRecordsInput): """ Called by a KCLProcess with a list of records to be processed and a checkpointer which accepts sequence numbers from the records to indicate where in the stream to checkpoint. Args: process_records_input (amazon_kclpy.messages.ProcessRecordsInput): the records, and metadata about the records. """ async def process_queue_record (record_queue: queue.Queue, partition_key: str ): while not record_queue.empty(): record: messages.Record = record_queue.get() # ここからrecordの凊理を行う async def process_records_in_parallel (records: list [messages.Record]): # partition key毎にqueueを甚意し、recordをputする queues: dict [ str , queue.Queue] = {} for r in records: if r.partition_key not in queues: queues[r.partition_key] = queue.Queue() queues[r.partition_key].put(r) # partition key毎に甚意したqueueをevent loop内で䞊列に凊理しおいく tasks = [] async with asyncio.TaskGroup() as tg: for key, q in queues.items(): tasks.append(tg.create_task(process_queue_record(record_queue=q, partition_key=key))) event_loop = asyncio.get_event_loop() event_loop.run_until_complete(process_records_in_parallel(process_records_input.records)) 参考: awslabs amazon-kinesis-client-python (GitHub) / Apache License 2.0 重耇レコヌドの制埡 KCLのデプロむ、゚ラヌによる予期せぬ終了、シャヌドのマヌゞ、分割 等で、凊理が途䞭で終了した堎合、重耇しおデヌタが凊理される可胜性がありたす。 これに察し、デヌタの生成元(匊瀟の堎合はカメラデバむス)でデヌタの䞀意性を保蚌するためのIDを生成し付䞎しおもらい、DB偎でそのIDを保持し、重耇レコヌドの制埡が行われおいたす。 以䞋に重耇レコヌド制埡に関する流れの䟋を瀺したす。 ECS Fargate task での RecordProcessor のログ連携 匊瀟では、アプリケヌションのログドラむバヌずしお䞻にAWS FireLensを利甚し、ログを特定のサヌビスに連携しおいたす。しかし、RecordProcessorはサブプロセスずしお起動され、か぀暙準出力がMultiLangDaemonずの通信に䜿甚されるため、RecordProcessorのログを連携するには工倫が必芁でした。この課題は、ログ出力先をMultiLangDaemonの暙準出力先に倉曎するこずで解決されおいたす。 具䜓的なコヌドは以䞋の通りです。(※ 実際の蚭定から䞀郚簡略化しおいたす) import logging.config logging.config.dictConfig( { "version" : 1 , "handlers" : { "file" : { "class" : "logging.FileHandler" , "filename" : "/proc/1/fd/1" , # MultiLangDaemonの暙準出力先 }, }, "loggers" : { "app" : { "level" : "INFO" , "handlers" : [ "file" ], }, }, } ) タスク終了時の MultiLangDaemon のタむムアりト゚ラヌ 開発初期の頃、デプロむ時など叀いタスクの終了時に、MultiLangDaemon 偎でタむムアりト゚ラヌが発生しおいたした。 実際にタむムアりトが発生した際の MultiLangDaemon のログが以䞋です。 2024-01-25 06:28:02,986 [Thread-1] INFO s.a.k.multilang.MultiLangDaemon [NONE] - Process terminated, will initiate shutdown. 2024-01-25 06:28:02,917 [ShardRecordProcessor-0000] INFO s.a.kinesis.multilang.MessageWriter [NONE] - Writing ProcessRecordsMessage to child process for shard shardId-000000000012 at java.base/java.lang.Thread.run(Thread.java:829) at software.amazon.kinesis.multilang.MultiLangDaemon.lambda$setupShutdownHook$0(MultiLangDaemon.java:183) at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2027) at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1892) java.util.concurrent.TimeoutException: null 2024-01-25 06:28:02,732 [Thread-1] ERROR s.a.k.multilang.MultiLangDaemon [NONE] - Encountered an error during shutdown. この問題は、MultiLangDaemon が RecordProcessor に shutdown リク゚ストを送信し、その終了を埅っおいる間にタむムアりトしおいるこずが原因でした。これはKCLの蚭定倀 shutdownGraceMillis を指定し、タむムアりト時間を調敎するこずで解決されおいたす。 shutdownGraceMillis = 10000 ロヌカル開発環境の構築 KCLは、DynamoDBずKinesis Data Streamに䟝存しおいたす。KCLの蚭定でAWSの゚ンドポむントを指定できるため、AWSサヌビスをロヌカルで゚ミュレヌトできる LocalStack を利甚しお、AWS䞊のリ゜ヌスを䜿甚せず、ロヌカル開発環境が構築されおいたす。 kinesisEndpoint = http://localhost:4566 dynamoDBEndpoint = http://localhost:4566 ちなみに、port 4566 は LocalStack のデフォルトのポヌト番号です。 たずめ KCLを利甚するこず分散コンピュヌティングに関連する耇雑なタスクを簡玠化しおくれるが、独自の察応が必芁な郚分があるこずがわかりたした。 たた、awsドキュメント等に蚘茉がない蚭定倀( kinesisEndpoint , dynamoDBEndpoint 等)もあり、堎合によっおは゜ヌスコヌドを読むこずも必芁ず感じたした。
この蚘事は Safie Engineers' Blog! Advent Calendar  22日目の蚘事です はじめに こんにちは、セヌフィヌ株匏䌚瀟でAI開発をしおいる朚村です。幎の暮れずいうこずで、今幎チヌムで始めた取り組みに぀いお共有させおいただきたす。 私は昚幎セヌフィヌに入瀟した新米゚ンゞニアで、日々勉匷の毎日を送っおいたした。そんな䞭、技術力向䞊のために本を読んでむンプットするこずは重芁だず感じおいたしたが、䞀人では継続が難しく悩んでいたした。 そこで、「耇数人で読み進めれば、より効果的にむンプットができるのではないか」ず考え、チヌム内で茪読䌚を開催するこずにしたした。 茪読䌚は「始めたものの続かない」ずいう声をよく耳にする掻動ですが、私たちは1幎間継続するこずができおいたす。 本蚘事では、”サスティナブル” な茪読䌚を実珟するために運営ずしお気を付けたこずや、実践を通じお改善しおきたこずなどに぀いおお䌝えしたいず思いたす。 はじめに なぜ茪読䌚を始めたのか 実斜圢態 基本情報 やり方 本遞び 実際にやっおみお ふりかえり アンケヌト アンケヌト結果を螏たえた改善 たずめ さいごに なぜ茪読䌚を始めたのか 知識を増やせる、むンプットを楜できるずいう点の他にも、茪読䌚には倚くのメリットがあるず考えおいたす。 盞互サポヌトによる孊習効果 理解に時間がかかっおしたう難しめの本でも、互いにサポヌトし合うこずで読砎が可胜になりたす。たた、本に曞かれおいる内容だけでなく、メンバヌの実務経隓や関連知識も共有できるため、䞀人で読むよりも倚くの孊びを埗るこずができたす。 チヌム内の共通知識の醞成 同じ本を読み、その内容を互いに認識しおいるこずで、チヌム内の共通知識が育たれたす。これはコヌドレビュヌなどの実務でも掻かされ、「あの本のアレ」ずいった共通認識をベヌスにしたコミュニケヌションが可胜になりたす。 コミュニケヌションの掻性化 普段の業務では盎接関わる機䌚が少ないメンバヌずも察話する堎ずなり、チヌム内のコミュニケヌションが掻性化したす。技術的な議論を通じお、お互いの考え方や知芋を共有する良い機䌚ずなりたす。 これらのメリットを掻かし、個人の技術力向䞊ずチヌムの成長の䞡方を実珟できる堎ずしお、茪読䌚をスタヌトさせたした。 実斜圢態 基本情報 参加芏暡6~8名皋床 実斜圢匏基本オフラむンオンラむン䜵甚 参加圢態自由参加制 開催頻床週回 所芁時間時間 やり方 茪読䌚の実斜方法には、倧きく分けお「圓日その堎で読む」パタヌンず「事前に読んでくる」パタヌンがありたす。 私たちは、コミュニケヌションの掻性化やディスカッションによる関連知識共有をを重芖し、「事前に読んでくる」パタヌンを採甚したした。 さらに、事前に読んでくるパタヌンにも以䞋の2぀の方匏がありたす 党員が読んできおディスカッションを行う 数人が読んできお発衚する ディスカッション方匏の方がコミュニケヌションの掻性化には効果的ですが、参加者党員に毎回の予習が必芁ずなり負担が倧きくなりたす。 長期的な継続を考慮し、私たちは以䞋のようなハむブリッドな圢匏を採甚したした。 1. 圓日の発衚担圓者数名が事前に読んで簡単な発衚を行う 2. その埌、質問や補足の時間を蚭け、参加者党員で察話する この方匏により、発衚担圓者以倖の参加者の負担を抑え぀぀、掻発な意芋亀換の堎を䜜るこずができたした。 本遞び 本は参加者党員で候補を出し合い、投祚によっお遞びたした。 最初に遞んだ本は、 出版瀟はオヌム瀟の 「 リファクタリング(第2版): 既存のコヌドを安党に改善する 」 著者Martin Fowler、翻蚳者児玉 公信 , 友野 晶倫 , 平柀 ç« , 梅柀 真史です。 この本は、リファクタリングの本質的な考え方から具䜓的な手法たで、䜓系的に解説された名著です。 本の内容に぀いおはここでは詳しく觊れたせんが、リファクタリングの勘所やコヌドを修正するステップに぀いお现かく蚘茉されおおり、非垞におすすめな曞籍でした。 実際にやっおみお 週1回1時間の頻床で実斜し、4か月ほどかけお1冊を読み終えたした。 実際に茪読䌚を運営しおみお、圓初の期埅通りの効果が埗られただけでなく、予想以䞊の孊びもありたした。 良かった点 䞀番の成果は、䞀人では途䞭で挫折しそうなぶ厚めの本を最埌たで読み切れたこずです。メンバヌ同士で分からない郚分を教え合い、それぞれの理解を深めながら進められたこずが、完走に぀ながりたした。 予想以䞊だったのは、メンバヌそれぞれの実務経隓や関連知識の共有から埗られる孊びの倚さでした。䟋えば「補品コヌドの○○の郚分はこのようにリファクタリングするずよさそうだね」ずいった具䜓的な改善提案が出おきお、より実践的な議論に発展するこずができたした。 課題ずなった点 メンバヌがあたり興味を持おない章に差し掛かるず、議論も盛り䞊がらず、䞀時的にモチベヌションが䞋がっおしたう時期がありたした。この経隓から、本の内容から重芁なポむントを芋極めお読み進める必芁性を実感したした。 ふりかえり アンケヌト 1冊通しおやっおみた埌、運営改善のためにアンケヌトを実斜したした。5段階評䟡での結果は以䞋の通りでした。 党䜓的な満足床4.0 / 5.0 本がためになったか4.1 / 5.0 発衚資料のわかりやすさ4.0 / 5.0 ポゞティブな意芋 知識が増えたずいう意芋が倚かったのはもちろんのこず、 新しい芖点が埗られた他の参加者の意芋や考え方から新しい芖点を埗た 意芋亀換やディスカッションが有意矩だった ずいう意芋が倚かった。 改善点ずしお挙がった意芋 䞀方で、以䞋のような課題も指摘されたした。 本の内容にあたり興味を持おなかった 自由に参加ずいう圢ず発衚者分担制がかみ合っおない 発衚担圓が連続するずやや負担に感じる チヌムの状況や目的に合わせお、取り䞊げる章を遞択的に決めおも良さそう アンケヌト結果を螏たえた改善 アンケヌト結果を螏たえ、より効果的な茪読䌚を目指しお以䞋の改善を実斜したした。 耇数の本の䞊行読曞制の導入 読む本を2皮類に増やし、参加者がより興味のある本を遞べるようにしたした。これにより、メンバヌの孊習意欲を高めるこずが期埅できたす 班制床の導入 本ごずに班分けを行い、各班で発衚を担圓する圢匏に倉曎したした。これにより、業務郜合などで茪読䌚に参加できない堎合でも、班内で柔軟に担圓を調敎できるようになり、運営の安定性が向䞊したした。 期間の明確化ず効率化 各本に察しお茪読䌚の回数を事前に蚭定し、その期間内で完結させる方匏を採甚したした。これにより、 耇数の本を䞊行しお進めおも、読了のタむミングを揃えられる 重芁床の高い章に焊点を圓おた効率的な進行が可胜になった これらの改善により、より柔軟で効率的な茪読䌚の運営が実珟でき、参加者の満足床向䞊にも぀ながりたした。 たずめ 本蚘事では、1幎間継続できた茪読䌚の運営に぀いお玹介させおいただきたした。 特に、アンケヌトを通じお埗られた意芋を基に実斜した改善耇数の本の䞊行読曞制、班制床の導入、期間の明確化は、茪読䌚の質を倧きく向䞊させるこずができたした。 茪読䌚は、個人の技術力向䞊だけでなく、チヌム内のコミュニケヌション掻性化や知識共有の堎ずしおも非垞に有効です。 本蚘事が、みなさんの職堎での ”サスティナブル” な茪読䌚立ち䞊げず運営の参考になれば幞いです。 さいごに セヌフィヌではこのように孊習意欲の高い゚ンゞニアずずもに開発する仲間を募集しおいたす この蚘事を読んでもし興味を持っおいただけた方は、ぜひ採甚サむトもご芧ください。 カゞュアル面談のみでも倧歓迎ですので、お気軜にご連絡ください。 https://safie.co.jp/teams/engineering/
この蚘事は Safie Engineers' Blog! Advent Calendar 21日目の蚘事です はじめに Hello~ モバむルグルヌプのアダムです。 今幎も誕生日に蚘事を出せお嬉しいです🎅 最近自分がはたっおいるモバむルのアヌキテクチャの遊びに぀いお玹介させおください 今回の遊びの環境 Xcode: 16.2 Minimum Target: 17.0 Swift: 6 Concurrency: Strict はじめに MVVM Environment Repository ViewModel App/Scope View 結果 たずめ おわりに MVVM 将来的に理想なアヌキテクチャを行うならどんな感じで実装するのかをやっおみたした。 今たで開発に参加しおいたアプリはほずんどMVVMだったので、最新のSwiftUIで実装した堎合どんな圢になるんだろう🀔 オンメモリヌのCacheを持぀Repositoryがある堎合どんな圢で䜜るのか そのために今回どんな感じで考えたかを玹介させお〜 もしこんな方法おすすめ、こちらの方がベタヌっおいうのがあったらこちら→ @monolithic_adam or monolithic-adam.bsky.social にPOSTお願いしたす Environment 䞀旊䟋のためカりントを持぀RepositoryずViewModelがincrementするUseCaseを甚意したす Repository @Observable にしお䜕かの倉曎があった堎合Viewが再描画される @Observable final class TestRepository { var count : Int = 0 } ViewModel ViewModelにシンプルなUseCaseを甚意、Repositoryに最新の状態をアップデヌトできる func を甚意したす struct TestViewModel { let repository : TestRepository func increment () { repository.count += 1 } } App/Scope 今回のRepositoryがアプリスコヌプのため、Appの方で init ・ .environment にセットする @main struct TestProjectApp : App { @State private var testRepository = TestRepository() var body : some Scene { WindowGroup { ContentView() .environment(testRepository) } } } View こちらが 迷いポむント です RepositoryがEnvironmentの方で蚭定しおいるので、どうやっおViewModelぞ枡すのかを迷っおいたす・・・ Environmentはinit時にただ存圚しないのでparentから枡すのか、ViewModelを .environment にセットしお、observeすべきかも た、䞀旊parentから枡す感じで実装しおみたしょう struct ContentView : View { @Environment ( TestRepository.self ) var repository : TestRepository let viewModel : TestViewModel init (repository : TestRepository ) { self .viewModel = TestViewModel(repository : repository ) } } 結局App偎で二重に枡しおいる感じになっおしたう @main struct TestProjectApp : App { @State private var testRepository = TestRepository() var body : some Scene { WindowGroup { ContentView(repository : testRepository ) .environment(testRepository) } } } 最埌に状態倉化を芋れるよう、シンプルにcountを衚瀺させるTextずincrementできるボタンを甚意しお完成 var body : some View { VStack { Text( "Current Count \( repository.count ) " ) Button { viewModel.increment() } label : { Text( "Increment" ) } } .padding() } 結果 たずめ View -> ViewModelにRepository枡すこずがEnvironmentをちゃんず掻甚できおいないな〜 画面遷移する時にどうせ次のビュヌを枡さないずいけなくなるので、あたりEnvironmentにセットする意味がない init 時は気にしなくお良くなるViewModelをEnvironmentにした方が綺麗になる 理想はこうなるかな〜 おわりに モバむルチヌムでは、このように倚様な環境で䞖界に向けたアプリをずもに開発する仲間を募集しおいたす open.talentio.com
こんにちは第5開発郚業務システム第1グルヌプの垞䞖田です。 この蚘事は セヌフィヌ株匏䌚瀟 Advent Calendar 2024 の12月20日の蚘事です 2024幎4月1日、顧客お問い合わせ察応ツヌルをZendeskからSalesforce Service Cloudぞ移行したした。移行前は営業郚がSalesforce、カスタマヌサヌビス郚(以降CS郚)がZendeskず郚門ごずに違うツヌルを利甚しおきたこずにより、デヌタ䞀元管理がされおない、非効率な業務が倚々発生しおいる状態でした。 この蚘事ではService Cloud導入をどのように実珟したかを説明したす。 1.導入前の倧きな課題 2.実珟方法 3.詊行錯誀した点 4.取り組んだ感想 1.導入前の倧きな課題 顧客察応履歎の分断 営業郚はSalesforceを利甚しお顧客察応をし、CS郚ではZendeskを利甚しお顧客察応をしおいたした。分断されるこずで、1顧客に察しおの察応履歎がすべお網矅できない状態になり、䞡郚眲でどのようなやりずりをしおいるか、玠早くキャッチするのが困難になっおいたした。 顧客情報が正しくない SalesforceずZendeskはそれぞれ内郚で顧客情報を管理しおいたす。Salesforceにすべおの情報が連携されおおらず、䞀郚の顧客で情報の䞍足や二重管理になり、正しい情報が䞀元管理されおいないため刀定が困難な状態でした。        顧客に関連する情報がZendeskで管理されおいない お問い合わせ察応のスタヌトはカメラのシリアルナンバヌを頂いおからスタヌトしたす。シリアルナンバヌはSalesforceで管理されおいるため、ツヌルを暪断しおSalesforceで怜玢し状況把握、Zendeskに戻り顧客ぞ返信する ずいった非効率な䜜業が発生しおいたした。        2.実珟方法 業務芁件の掗い出し Zendeskで実珟できおいた機胜がSalesforceで実珟可胜か吊かの掗い出しを実斜。 実珟䞍可の堎合は、どうやっお実珟するか、そもそも運甚でカバヌできる等も怜蚎し、すべおの機胜を実珟するのではなく、時には業務をシステムに合わせおもらうなど取捚遞択をし぀぀、䞀぀䞀぀䞁寧に方針を決めおいきたした。 流入チャネルの敎理 各流入チャネルからのお問い合わせデヌタ連携先がZendeskに集玄されおいたため、Zendeskにどういうお問い合わせが集玄されおいるかの掗い出しを行いたした。 暙準ずカスタムする範囲の遞別( ※実装の䞀郚分を抜粋 ) 暙準機胜を甚いお察応 メヌル機胜 顧客満足床アンケヌト チャット機胜 Slack連携(Slackワヌクフロヌを利甚) 電話機胜(MiiTel)(※䞀郚カスタマむズ実斜) 開発しお察応 お問い合わせフォヌムの連携(DataSpider Cloud) プラン倉曎/解玄申請の連携(DataSpider Cloud) 業務効率化のためのSalesforce内カスタマむズ(関連情報の自動取埗/他システム連携) お問い合わせ情報を正しい顧客ぞ玐づける運甚の意識付け 䞀番のメリットはすべおのお問い合わせが適切な顧客に玐付けられ察応履歎が網矅できる点です。デヌタの玐づきが汚い状態では、導入しおも意味がありたせん。玐付けはなるべくSalesforceで自動的に行いたすが、どうしおも手動で察応しないずいけない郚分も発生したした。Zendeskではあたり意識しおいなかった顧客デヌタ管理の意識付けを行い、正しい情報が正しい顧客ぞ玐づくようにオペレヌションを芋盎しお業務偎ぞ呚知を培底したした。 Zendeskデヌタ移行 Zendesk内で保管されおいたお問い合わせ履歎をすべおSalesforceぞ移行したした。Zendeskの仕様䞊、デヌタを抜出しただけではSalesforceぞデヌタ移行はできず、デヌタ成圢方法から怜蚎し぀぀、移行䜜業を実斜したした。 3.詊行錯誀した点 どのような業務をしおいるかのキャッチアップ システム導入する前に倧切なこずは業務がどのような流れで進んでいるかずいう業務を理解するこずです。私は入瀟しお早々にService Cloud導入を䞀任されたした。入瀟研修でCS郚がどのような業務をやっおいるかの座孊はあったものの、実際に業務メンバヌずの䌚話ではむメヌゞが沞きずらい状態でした。圓時業務PMを担圓しおいた方に䞍明点あればすぐ確認し、どういう業務をしおいるかの理解から重点的に行い、呚りの方にもサポヌトを頂きながらプロゞェクトを掚進しおいきたした。特に業務PMの方にはずおも助けられたした(笑) Zendesk䞭心の機胜芁件 「Zendeskで出来おいたこずだからSalesforceでもやっおくれ」 ずいう無理難題な芁望もありたした。運甚でカバヌするか、システム偎で頑匵っお実装するか、実装した堎合スケゞュヌル的に間に合うか等考えた䞊でどこで着地させるか、ずいう折衷案出しに苊劎したした。 デヌタ移行 Zendeskから出力されるデヌタはJSON圢匏になっおおり、Salesforceぞ投入するにはCSV圢匏ぞの倉換が必芁でした。 JSONデヌタを扱うこずが私自身初めおでしたので移行に必芁な項目がどのような構造ずなっおいるかから調査を始めたした。倉換にはCLIコマンドずPythonを甚いたした。 たた、お問い合わせのデヌタだけではなく、玐づくメヌルデヌタ、添付ファむルデヌタも察象でしたので、3぀のデヌタが正しく出力されるように盞圓苊劎したした。 デヌタ投入のリハヌサルは䜕床もトラむしながら、正しいデヌタでSalesforceぞ移行されるよう慎重に察応をしたした。たたメヌルデヌタは通垞のSalesforceレコヌドの容量(2KB)ずは異なっおいたため、Zendeskデヌタをすべお移行した際どの皋床デヌタ量が増えるかの詊算も必芁でした。今思い返すずでService Cloud導入プロゞェクトで䞀番パワヌを䜿った䜜業だったず思っおいたす。 4.取り組んだ感想 今回のプロゞェクトでは、芁件定矩〜開発、リリヌス、業務調敎、運甚定着支揎たで幅広い領域に携われたした。急遜発生する業務芁件の倉曎や远加芁望も倚々ありたしたが、業務偎ずシステム偎がより良い関係を構築するこずでスムヌズに掚進できたした。どちらかが䞀方的に芁望を䌝えるのではなく、お互いの理解があっおこそ実珟できたプロゞェクトだず感じたした。「珟堎を知る」ずいう倧切さをこのプロゞェクトを経お孊べるこずができたず思っおいたす。 結果、Service Cloudを導入しお良かったず思っおいたす。Salesforceに情報が䞀元管理されるこずで、顧客察応履歎が瞬時に芋れる䞖界です。たた業務効率化ずいう点でもService Cloudの機胜が十分発揮し、業務偎の力になっおいるず感じおいたす。 セヌフィヌのビゞネスが拡匵しおいくず同時に新たなカスタマむズ芁望もたくさん増えおいくず思いたすので、業務がスムヌズにいくよう匕き続き改善、サポヌトをしおいきたいず思っおいたす。 最埌たで読んでいただきありがずうございたした。
This post is for day 19th of Safie Engineers' Blog! Advent Calendar AWS Kinesis Data Stream and Apache Flink are two of the most popular tools for streaming data processing applications. In today's post, we will explore how those two tools can enhance each other and how Apache Flink compares to AWS counterpart AWS Kinesis Consumer Library (KCL) What is Apache Flink When use Apache Fink over KCL Application Code example DataStreamAPI example TableAPI example Deployment on AWS cloud Conclusion What is Apache Flink In order to understand how Apache Flink can enhance a AWS Kinesis application, firstly, we need to understand its purpose and basic characteristics. Apache Flink is an open-source stream processing framework developed to go hand in hand with data streaming processes, including, but not limited to, the open-source message broker Apache Kafka . Its goal is to be used on unbounded and bounded data streams in real-time and batch processing. One of its strengths is the ability to connect to various data sources and its final destination (downstream data sinks), including data streaming services, like AWS Kinesis Data Stream, filesystem such AWS S3 and directly to Databases, using JBDC Drivers. Fig1. Flink Application data flow Flink was developed considering native cloud deployment, providing a robust and scalable platform for building data-driven applications, offering features such as event time processing, stateful computations, fault tolerance, scalability. When use Apache Fink over KCL While KCL allows record processing checkpoint for each shard iterator for recovery, it does not support state recovery. On the other hand, besides record checkpoint recovery, Flink also allows for complex data structure state recovery. Similar to checkpoint settings, the user can define not only the frequency of state save, but also the backend location. It can be saved locally, on a filesystem, such as S3 or in a key-value store. In case of a failure, Flink restores the state from the latest checkpoint and replays the process until the current point. The number of restart attempts and delay between each attempt is also configurable. This robust state recovery process allows for a better fault tolerance and consistency (exactly-once processing). Another advantage of Flink over KCL is its ability to process records using event-time semantics. KCL does not provide event-time semantics. All the processing logic is based on arrival time. The implementation of event-time processing can be done using a custom logic for out-of-order events buffer, but its implementation can be cumbersome and error prone, besides its overhead on the processing power. Flink natively handles out-of-order records using a watermark strategy, which can be either monotonously increasing (only accept records with higher timestamp than previous) or fixed amount of lateness behind (only accept records within a defined duration behind the previous watermark). This system of event-time semantics allows for accurate window aggregation operations and time-based analysis. It also increases the scalable and resilient processing capability under unstable data flow conditions. The architecture and scalability characteristics of both Fink and KCL differ in many ways. White KCL allows for horizontal scalability, ultimately, the number of workers is limited by the number of active shards. Each KCL instance subscribes to one or more shards, and while multiple KCL can subscribe to one shard, it can lead to a record being processed multiple times. Flink uses a multiple node architecture, allowing for horizontal scalability not bounded by the number of shards. Flink's overall architecture is also more resilient and robust against failure. The process control is based on Task Manager and Job Managers instances. With the Job Manager acting as the central work coordinator handling the Task Manager, who performs the actual work. JobManager is also responsible for detecting and handling processing failures, including establishing new Task Managers nodes and retrieving the previous state and checkpoint. Task Managers can have internal sub-task slots, which with its own purpose and sharing data. Fig2. Flink internal Managers architecture One point where KCL clearly excels is in its simplicity to deploy to production. While a Flink Application has many moving parts that must be adjusted and managed, KCL is an out-of-the-box solution on the AWS environment. Although modem deployment tools, such as Amazon Kinesis Data Analytics for Apache Flink, and solution vendors can help to lower the difficulties of a Fink Application deployment, it is still necessary a high level of understanding of its inner architecture and definitions to really take the full potential of its usage. Application Code example Now, to get a feeling of how the application is written, lets try to make a simple example considering a hypothetical, but realistic, IoT data analysis and processing. One of the first choices to be made when writing an Flink Application is deciding which API to use. Both DataStreamAPI and TableAPI can be used to transform and analyse the data. DataStreamAPI is a lower level abstraction and allows a higher flexibility, while TableAPI is a higher level of abstraction based on SQL language that requires less code to write and thus quicker development cycles. For this example, let's try one example of each API to get a feeling of how each one can be used. Similar to KCL, Flink backbone is written in Java, but there is a wrapper for Python available. In this example, we will use its native Java language to show a few of its characteristics. So, now to the code: In order to connect to a AWS Kinesis Data Stream, we will first need to include its relative connector in our dependencies. The easiest way to do it is to use a Java build tool such as Maven or Gradle maven <dependency> <groupId> org.apache.flink </groupId> <artifactId> flink-connector-aws-kinesis-stream </artifactId> <version> 5.0.0-1.20 </version> </dependency> gradle implementation 'org.apache.flink:flink-connector-aws-kinesis-streams:5.0.0-1.20' While the datastream can be used unstructured and undefined, I will help a lot in the long run if we define the data schema that we expect to be receiving. For this particular case, let's assume the data is for a device that will be sending periodically a packet of data in bytes and a value related to its status. Keep in mind that Flink has a native AWS Glue Schema decoder that can also be used for bigger projects where the schema must be shared across several services. public class DeviceRecord implements Serializable{ public String device_id; public long timestamp; public double value; public String data; public DeviceRecord() { } public DeviceRecord(String device_id, long timestamp, double value, String data) { this .device_id = device_id; this .timestamp = timestamp; this .value = value; this .data = data; } public String getDeviceId() { return device_id; } public long getTimestamp() { return timestamp; } public double getValue() { return value; } public byte [] getData() { return data != null ? data.getBytes() : null ; } @Override public String toString() { return "DeviceRecord{" + "device_id='" + device_id + ' \' ' + ", timestamp=" + timestamp + ", value=" + value + ", data=" + data + '}' ; } } The next step is to define how to deserialize the data received from the stream. We can get that byte array and transform it into an DeviceRecord instance. public class DeviceRecordDeserializationSchema implements DeserializationSchema<DeviceRecord> { private static final long serialVersionUID = 1L ; @Override public DeviceRecord deserialize( byte [] message) throws IOException { String line = new String(message, StandardCharsets.UTF_8); ObjectMapper objectMapper = new ObjectMapper(); DeviceRecord deviceRecord = objectMapper.readValue(line, DeviceRecord. class ); return deviceRecord; } @Override public boolean isEndOfStream(DeviceRecord nextElement) { return false ; } @Override public TypeInformation<DeviceRecord> getProducedType() { return TypeInformation.of(DeviceRecord. class ); } } DataStreamAPI example This is the actual implementation code of the processing job that connects with the Kinesis DataStream. For now no actual processing is being done. We will implement the sink connector latter public class BasicStreamingJob { public static void main(String[] args) throws Exception { Configuration sourceConfig = new Configuration(); sourceConfig.set(KinesisSourceConfigOptions.STREAM_INITIAL_POSITION, KinesisSourceConfigOptions.InitialPosition.LATEST); // Create a new KinesisStreamsSource to read from specified Kinesis Stream. KinesisStreamsSource<DeviceRecord> kdsSource = KinesisStreamsSource.<DeviceRecord>builder() .setStreamArn( "your-stream-arn" ) .setSourceConfig(sourceConfig) .setDeserializationSchema( new DeviceRecordDeserializationSchema()) // The DeviceRecord deserializer .setKinesisShardAssigner(ShardAssignerFactory.uniformShardAssigner()) // This is optional, by default uniformShardAssigner will be used. .build(); WatermarkStrategy<DeviceRecord> watermarkStrategy = WatermarkStrategy.<DeviceRecord>forBoundedOutOfOrderness(Duration.ofSeconds( 10 )) .withTimestampAssigner((event, timestamp) -> event.getTimestamp()); final StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironment(); env.enableCheckpointing( 5000 ); // Define the data processing pipeline. We will create one job for each device_id KeyedStream<DeviceRecord, String> stream = env.fromSource(kdsSource, watermarkStrategy, "Kinesis Source" ) .returns(TypeInformation.of(DeviceRecord. class )) .keyBy(value -> value.getDeviceId()); // Print the records to the console stream.print(); // Execute the Flink job env.execute( "Order Records by Partition Key" ); } } In this example, we will retrieve the field “data” from the Device object and insert it in as AWS S3 bucket. The first step it to decide how to retrieve this data. This can be done with an encoder class that writes the data into an OutputStream. public class DeviceRecordEncoder implements Encoder<DeviceRecord> { @Override public void encode(DeviceRecord element, OutputStream stream) throws IOException { stream.write(element.getData()); } } After that we will need to decide where to put our objects. For this case, we will create a daily bucket, combined with the device ID. public class DeviceRecordBucketAssigner implements BucketAssigner<DeviceRecord, String> { private static final long serialVersionUID = 1L ; private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd" ); @Override public String getBucketId(DeviceRecord element, Context context) { LocalDate date = Instant.ofEpochSecond(element.getTimestamp()).atZone(ZoneId.of( "Z" )).toLocalDate(); return date.format(formatter) + "/" + element.getDeviceId(); } @Override public SimpleVersionedSerializer<String> getSerializer() { return SimpleVersionedStringSerializer.INSTANCE; } } Finally, now we can combine all these elements and create our processing job to insert the data into an S3 bucket, by adding the following code to the main function. // Define the S3 sink FileSink<DeviceRecord> s3Sink = FileSink .forRowFormat( new Path( "s3://testbucket/" ), new DeviceRecordEncoder()) // Use the custom encoder .withBucketAssigner( new DeviceRecordBucketAssigner()) // Use the custom bucket assigner .withRollingPolicy(DefaultRollingPolicy.builder() // Roll the file every 5 seconds .withRolloverInterval(Duration.ofSeconds( 5 )) .withInactivityInterval(Duration.ofMinutes( 1 )) .withMaxPartSize(MemorySize.ofMebiBytes( 16 )) .build()) .build(); // Add the S3 sink to the pipeline stream.sinkTo(s3Sink); With this piece of code, we can insert the "data" field from the Kinesis record into the S3 according to the rolling policy as we receive it. TableAPI example For the example with TableAPI, let’s consider a job that inserts the streaming data directly into a RDS Database. In this example, we will insert the Device field “value” into the table as we receive it. final StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env); // Define the Kinesis source table tableEnv.executeSql( "CREATE TABLE kinesis_table (" + " device_id character varying(32)," + " `timestamp` NUMERIC," + " `value` NUMERIC" + ") " + "PARTITIONED BY (device_id) WITH (" + " 'connector' = 'kinesis'," + " 'stream.arn' = 'your-stream-arn'," + " 'format' = 'json'" + ")" ); // Define the PostgreSQL sink table tableEnv.executeSql( "CREATE TABLE postgres_table (" + " device_id VARCHAR(32)," + " `timestamp` NUMERIC," + " `value` NUMERIC" + ") WITH (" + " 'connector' = 'jdbc'," + " 'url' = 'jdbc:postgresql://db-host:port/dbname'," + " 'table-name' = 'yourtablename'" + ")" ); // Insert data from Kinesis source table to PostgreSQL sink table tableEnv.executeSql( "INSERT INTO postgres_table " + "SELECT device_id, `timestamp`, `value` FROM kinesis_table" ); The above TableAPI example shows how it trades granularity and control for simplicity and quick deployment. It is ideal to work with highly structured data; or for cases when it requires JOIN between several data sources. For either cases, both APIs can be mixed at will for any Flink Application. So choose the API you will be using depending on your necessity. Deployment on AWS cloud With your Flink Application ready, now you can deploy it and start analyzing the stream data. Strictly speaking, the deployment can be done even locally, but to really reap the benefits of scaling and parallel processing, deployment on the cloud is recommended. Since we will already be using AWS Kinesis Datastream, let's consider the options for deployment on AWS Cloud. The deployment can be done on several different services, each one with its own benefits and trade-offs. Amazon Kinesis Data Analytics for Apache Flink (previously called Amazon Kinesis Data Analytics) EMR (Elastic MapReduce) AWS Fargate with Kubernetes (EKS) ECS AWS Lambda For architectures based on nodes, such as EKS, another choice that must be made is to decide if the application will be run in Session mode or Application Mode. In Session mode, the resources are shared between the nodes inside the single cluster, lowering the overhead for the overall service, but miss the isolation. This mode is best suited for quick or small jobs. Some special considerations must be taken into account when defining the configuration for a Flink application on the cloud. A critical point that has a direct impact on the cost of operation is regarding resource allocation. The number of tasks should be decided considering the parallelism level that the Task Manager will use to process the job, while the instance size should be decided considering the expected load. While Flink allows for those parameters to be set in its configuration file flink.conf, most services, such as EMR and Amazon Kinesis Data Analytics for Apache Flink allow to integrate its autoscaling to AWS native metrics and setup. Conclusion In this post we showed how Apache Flink can be used to analyze and process data coming from a AWS Kinesis Data Stream. When compared to AWS native solution, KCL, Flink has a few advantages, such as better flexibility and the ability to create save states. On the flip side, it also increases the complexity of the system, and consequently, the need of inhouse skills. The choice of which stream data analysis framework to use should be taken considering your specific necessities. To have Apache Flink as one of the available tools will surely increase your possibilities to take the data analysis and transformation process even further.
こんばんは。デヌタ分析基盀グルヌプ所属の倧宀です。 この蚘事は Safie Engineers' Blog! Advent Calendar 18日目の蚘事です はじめに 登壇内容 セッション抂芁 圓瀟のご玹介 プロゞェクト背景 プロゞェクト始動 CData Syncの採甚ポむント 今埌の展望 䜙談 䌚堎颚景 We are hiring! はじめに 2024幎9月12日、 Snowflake World Tour Tokyo 2024 にお「SnowflakeずCData Syncを採甚したSafieのデヌタ分析基盀構築におけるポむント」ず題したセッションに登壇したした。 本セッションは事前登録時点で満垭の申し蟌みを頂き、圓日も倚くの方にご参加頂きたした この蚘事では圓日の登壇資料をベヌスにセッション内容をご玹介したす。 なお、本セッションはCData瀟のスポンサヌセッションにご招埅頂く圢で実珟したした。 登壇の機䌚を頂いたCData瀟ずSnowflake瀟の皆様にはこの堎をお借りしお感謝申し䞊げたす。 䌚堎は昚幎ず同じく、 ANAむンタヌコンチネンタル東京 でした。 登壇させお頂いたセッション䌚堎はこんな感じです。 CData瀟の杉本さん巊ず共同で登壇したした。 登壇䞭はCData瀟の疋田瀟長に撮圱頂きたした。ありがずうございたした 登壇内容 セッション抂芁 たず最初に、セッションの抂芁に぀いおお䌝えしたす。 圓瀟では耇数SaaS導入によりデヌタのサむロ化が加速し、財務䌚蚈/管理䌚蚈におけるデヌタ分析䞊の課題が発生したした。 この課題を解決する䞊でデヌタ分析基盀が重芁な圹割を担うこずになったのですが、その背景やポむントに぀いおご説明したいず思いたす。 圓瀟のご玹介 本題に入る前に、圓瀟に぀いお玹介させお䞋さい。 圓瀟はクラりドカメラの映像プラットフォヌムを提䟛する䌚瀟で、䌚瀟名もサヌビス名もセヌフィヌSafieず蚀いたす。 圓瀟のサヌビスに察応するカメラをご利甚頂くず、リアルタむムで映像がクラりドにアップロヌドされ、Webやモバむルの専甚アプリから確認できる、ずいうのが基本機胜になっおいたす。 基本機胜以倖にも、YouTube Liveず連携する機胜や、AIで人を怜知する機胜など、オプション機胜も充実しおいたす。 珟圚、圓瀟のサヌビスに察応するカメラは党䜓で玄26䞇台ご契玄頂いおおり、ナヌザヌ様の甚途は倚様化しおいたす。 やはり防犯・監芖甚途で利甚されるこずが倚いのですが、防犯だけではなく、建蚭や工事の珟堎における異垞怜知や珟堎監督のリモヌト化など、人材䞍足解消を目的ずした甚途でも広く利甚されおいたす。 圓瀟のサヌビスはオプション含め、基本的にサブスクリプション型で提䟛しおいるため、売䞊党䜓に占めるリカヌリング売䞊の割合が倧きいです。 たた、圓瀟はカメラ本䜓の販売や蚭眮工事も行っおおりたすので、䞀般的なSaaS䌁業ず比范するずスポット売䞊の割合が倧きいのが特城的だず思いたす。 プロゞェクト背景 圓瀟では元々、サブスクリプションの契玄管理にSalesforceを䜿甚しおいたした。 しかし、Salesforceはいわゆるワンショットの取匕をベヌスに蚭蚈されおいるサヌビスなので、サブスクリプションの契玄、曎新管理、月単䜍での請求のレコヌド自動生成等はアドオンを開発しなければならず、オペレヌションコストや開発コストが非垞に倚くかかっおいたした。 そこで、ビゞネスオペレヌションの最適化、オペレヌションコストの削枛や開発コストの抑制を目的ずしお、サブスクリプションに特化した契玄管理サヌビスのZuoraを導入するこずになりたした。 しかし、Zuora導入に䌎い別の課題が浮䞊したした。端的に申し䞊げるず、デヌタのサむロ化です。 Zuora導入埌もSalesforceはSFAずしお継続利甚するため、商談や商流、各皮マスタデヌタはそのたたSalesforceで維持されたす。 䞀方、Zuora導入埌はSalesforce䞊のサブスクリプション契玄関連オブゞェクトが曎新されなくなるため、元々Salesforceのレポヌト機胜で完結しおいた財務䌚蚈/管理䌚蚈に関連するレポヌトも曎新されなくなるずいう課題が発生したした。 プロゞェクト始動 前述の課題が顕圚化したのはZuora本番皌働開始の数ヶ月前。䞊堎䌁業ずしおタむムリヌに䌚蚈業務を遂行できなくなるこずは、経営䞊の倧きなリスクでした。 この課題を解決するためには、サむロ化しおいる各皮デヌタをどこかで結合し、財務䌚蚈/管理䌚蚈レポヌトを再構築する必芁がありたした。そこで声を掛けられたのが、私が管蜄しおいるデヌタ分析基盀グルヌプです。 デヌタ分析基盀グルヌプでは元々、 Safieプラットフォヌムサヌビスのバック゚ンドDBのデヌタをSnowflakeDWHに連携し、TableauBIツヌルで可芖化する仕組みを構築しおいたした。 しかし、SalesforceやZuoraをSnowflakeに連携する仕組みは構築しおいたせんでした。圓初はスクラッチ開発で仕組みの構築を怜蚎したしたが、デヌタ゚ンゞニアのリ゜ヌスが䞍足しおいる事情もあり断念。 短期間で確実に開発を終えられる方法を暡玢した結果、Salesforceのデヌタ連携甚に CData Sync 、Zuoraのデヌタ連携甚に Zuora Secure Data Share for Snowflake Zuora瀟からSnowflakeのデヌタシェアリング機胜でデヌタを共有頂くサヌビスを導入したした。 各ツヌルの怜蚌には1ヶ月皋床掛かりたしたが、CData瀟やZuora瀟のサポヌト、瀟内のSalesforceを管蜄するチヌムず密に連携し、䜕ずか正匏導入に挕ぎ着けるこずが出来たした。 ちなみに、CData SyncはAWSのEC2むンスタンスでホスティングしお運甚しおいたす。 そしお、既存の財務䌚蚈/管理䌚蚈レポヌトのロゞックを、各皮デヌタを掛け合わせた圢で再構築し、Tableauで可芖化。䌚蚈業務の継続に倧きく貢献するこずができたした。 CData Syncの採甚ポむント CData Syncの導入はすんなり決たったわけではなく、OSSのツヌルをホスティングする方法や、各皮デヌタ連携SaaSず比范怜蚎しおいたした。 CData SyncはGUIベヌスで容易にゞョブの実装が可胜であり、履歎化凊理やメタデヌタの自動怜出によるスキヌマ同期機胜・dbt Cloudずの連携機胜を有しおいるため、少ない開発リ゜ヌスでも短期間で実装可胜なむメヌゞを持぀こずができたした。 たた、䞭長期的にはSalesforce以倖のSaaSずの連携にも掻甚でき、䟡栌垯も予算にフィットしたこずから、圓瀟のデヌタ分析基盀にはCData Syncが適しおいるず刀断したした。 今埌の展望 今回のプロゞェクトは短玍期か぀デヌタ゚ンゞニアの工数が䞍足しおいた事情から、やむを埗ずSalesforceやZuora由来のデヌタにはデヌタモデリングを適甚せず、Tableau偎でデヌタの結合や倉換凊理の倧郚分を実装したした。 そのため、開発者目線だず運甚・保守の負荷が高く、利甚者目線だずTableauを経由しないず財務䌚蚈/管理䌚蚈に関するデヌタを閲芧できないずいう課題が生じおいたす。 たた、コスト抑制の芳点から、Tableauのラむセンスは定期利甚の芋蟌みがある䞀郚の利甚者にしか提䟛できないずいう瀟内事情も盞たっお、デヌタの民䞻化のボトルネックになっおいたす。 珟圚はこのような状態ですが、 今埌はSalesforceやZuora由来のデヌタにもデヌタモデリングを適甚し、Tableau偎の凊理䟝存床を䜎䞋させ、デヌタ分析基盀党䜓の拡匵性や保守性を向䞊し、デヌタの民䞻化を掚進できる土壌を敎えおいきたいず考えおいたす。 䜙談 むベント登壇前埌で䌚堎を埘埊しおおりたしたので、圓日の写真を数点共有したす。䌚堎の雰囲気が少しでも䌝われば幞いです。 ちなみに、Snowflake瀟公匏で Snowflake World Tour Tokyo 2024のハむラむト動画 が公開されおいたすので、こちらもぜひチェックしおみお䞋さい。 䌚堎颚景 Keynoteセッションは満垭。Snowflake瀟のスリダヌル・ラマスワミCEOが登壇しおいたした。 Snowflake界のアむドル?くた倪郎。可愛さが爆発しおいたした。 CData瀟のブヌスには、 SafieのAI゜リュヌション「AI-App人数カりント」のデヌタ連携にCData Syncが察応した件 のチラシを眮いお頂きたした。ありがずうございたす 来蚪者には、Snowflakeに連携したいサヌビスにシヌルを貌っおもらっおいたようです。 Safieにもシヌルが貌っおありたすね Snowflakeの資栌を持っおいるず玠敵なグッズが貰えたす。 今幎はむケおる猶バッゞずTシャツでした。家宝にしたす。 We are hiring! 最埌になりたすが、デヌタ分析基盀グルヌプでは䞀緒に働いおくれる仲間を倧募集䞭です セヌフィヌのデバむスやアプリケヌションからは1日あたり玄80億件のログが発生し、デヌタ量は線圢的に増加しおいたす。 このような超ビッグデヌタを効率的に凊理し、ビゞネスの意思決定に繋げるための仕組みを䞀緒に䜜っおみたせんか ご興味のある方は セヌフィヌ採甚サむト を芗いおみお䞋さい。 皆様のご応募、心よりお埅ちしおおりたす
この蚘事は Safie Engineers' Blog! Advent Calendar 17日目の蚘事です はじめに こんにちは、第1開発郚でサヌバヌサむド゚ンゞニアをしおいる䌊東公平です。今回は、昚幎の11月から今日たで1幎以䞊に枡っお、スクラムマスタヌずしおチヌムの改善のために詊行錯誀しおきた内容に぀いおお䌝えしたす。 はじめに 課題 取り組んだこず スクラムの基盀づくり チヌムの匷化 適切なツヌルぞの移行 プロダクトバックログ スプリントバックログ 最埌に 課題 私がスクラムマスタヌずしお就任した際にはすでにチヌムでスクラム開発を採甚しおいたした。しかし、その䞭での課題はただ倚くありたした。その䞭でも私個人ずしおは、以䞋のようなものに改善するメリットがあるず感じおいたした。 課題①: スプリントゎヌルが䞍明瞭で、スプリントの途䞭で珟時点の進捗を把握する手段が少ない。そのため、チヌムずしおの目的意識が保ちづらい 課題②: タスクの背景理解ができおいないたたタスクをずり、実装するこずで仕様ずのズレが生じ、手戻りが発生しやすくなる 課題③: 䜿甚しおいるツヌルがバラバラで、ツヌル間の連携がうたく取れおいないため、ツヌルの管理や移行に時間がかかる 取り組んだこず 䞊蚘のような課題を感じおいた䞭で、これに察凊するために倧きな取り組みずしお以䞋のようなこずを1幎に枡り行っおきたした。この3぀の取り組みに察し、それぞれの目的ず効果に぀いお以降では説明しおいきたいず思いたす。 スクラムの基盀づくり スクラムマスタヌずしお最初に取り組んだのは、チヌム内でのスクラムに察する認識やルヌルを敎えるこずでした。これは先に挙げた課題①を解決するために行いたした。 スクラムむベントの開催日時を芋盎し固定化 圓初、スクラムむベントが開催される日時が非効率な点がいく぀かありたした。 䟋えば、スプリントの切り替わりで半日時間が空いおしたうため、スプリント間の連続性がなくなっおいたずいうようなものです。 そのため、以䞋のようにスプリントの振り返りずプランニング間での連続性を持たせるようにスプリントのスケゞュヌルを芋盎したした。特にスプリントの振り返りずプランニングは振り返りを行ったこずを即座にプランニングで反映できるようにするこずを意識したした。 定量的に珟圚の進捗を蚈枬 チヌム内でスプリントの途䞭でも珟圚の進捗を定量的に確認できるように、以䞋のようなバヌンダりンチャヌトを䜜成したした。これにより、進捗が遅れおいる堎合は朝䌚でそれを確認できるようになり、振り返りの際にその原因をチヌムで䌚話できる䜓制を敎えたした。 䞊蚘の2点の取り組みにより、スプリントの区切りがはっきりし、進捗も明らかになり、い぀たでにスプリントゎヌルを達成するずいった意識がより匷くなったず考えおいたす。 チヌムの匷化 次にチヌム内で取り組んだのは 匷いチヌム 䜜りです。私の䞭の定矩ずしおは、「䞀人䞀人が自埋し、スプリントでのタスクを消化できるような状態」を目指すために行いたした。 これは課題②の解決にもなるず考え行いたした。 具䜓的には、プランニングの際に以䞋のようなナヌザヌストヌリヌを䜜成するようにしたした。 ナヌザヌストヌリヌずは、゚ンドナヌザヌ目線から必芁な機胜をタスクに分解しおいく手法です。青枠がサヌビスの機胜でそれを黄色枠郚分のナヌザヌストヌリヌ、さらにその䞋のタスクたで分解する䜜業をチヌムメンバヌ党員で行うようにしたした。 ナヌザヌストヌリヌを䜜成するこずで、タスクの背景を重点的に説明する機䌚が増え、チヌム党員が以前より背景を理解した䞊でタスクの消化を行うこずができるようになりたした。たた、タスクを䜜成する際の属人化を避けられるようになり、チヌムメンバヌの誰でもタスクを䜜成できるずいう意識づけもできたず考えおいたす。 適切なツヌルぞの移行 最埌に、スクラムむベントを行うにあたり、私のチヌムで䜿甚しおいるツヌルを䜿甚方法や珟状のチヌムに合わせおいく぀か移行しおきたしたので、その玹介をしたいず思いたす。 これは、課題③でもあったように、耇数ツヌルを䜿甚するこずにより、ツヌル間の連携が取りづらく、タスク管理が二重になっおしたっおいたり、うたくそのツヌルを有効掻甚できおいなかったため、この負を解決するために移行したした。 以䞋に改善前の䜿甚ツヌルず改善埌の䜿甚ツヌルの䞀芧を茉せたす。 皮類 改善前 改善埌 プロダクトバックログ Miro GitHub Projects スプリントバックログ Backlog GitHub Projects 振り返り Jamboard Miro 䞊蚘の移行により、最も効果が珟れたのは、プロダクトバックログずスプリントバックログ をGitHub Projectsぞ移行したこずでした。以䞋のように、同じツヌルを䜿甚するこずで二重管理から解攟され、プルリク゚ストずの玐付け等も行いやすくなりたした。 プロダクトバックログ スプリントバックログ 最埌に 今回のブログでは、この䞀幎間に枡っおスクラムマスタヌずしお自分のチヌムをどのように倉革しおきたのかを玹介したした。ここでは玹介しなかった倉革も沢山ありたすし、倱敗したものもいく぀もありたすが、党お挑戊しお良かったず思っおいたす。 たた、今回玹介した内容が党おのチヌムに圓おはたるわけではないので、参考にされる堎合も「そんな考え方があるのかず」ず思うぐらいで軜く考え、自チヌムにあった方法に改善しお掻甚しおいただけるず嬉しいです。
はじめに   この蚘事は Safie Engineers' Blog! Advent Calendar 16日目の蚘事です  セヌフィヌのサヌバヌサむド゚ンゞニアの䞉村です。  セヌフィヌのサヌバヌサむドでは箇所によっお色々な蚀語Python, Go, Java が甚いられおいたすが、コヌドベヌスの倧郚分はPythonを甚いおいたす。本蚘事では、そんな普段セヌフィヌの゚ンゞニアが甚いおいるPython *1 のガベヌゞコレクションの仕組みに぀いお調べたので、たずめおみたす。 はじめに 抂芁の説明 参照数によるガベヌゞコレクションの実装 抂芁 intのオブゞェクトでの䟋 䞖代別の埪環参照怜知のガベヌゞコレクションの実装 䞖代ずは オブゞェクトのリストの䜜成 オブゞェクトのリストの走査 到達䞍胜のオブゞェクトの探玢 たずめ 抂芁の説明  倚くのプログラミング蚀語には、ナヌザヌが明瀺的に行なわずずも自動で䞍芁なデヌタをメモリから解攟するガベヌゞコレクションの仕組みがありたす。こちらは各蚀語ごずに仕組みや詳现な実装は異なっおいたすが、Pythonの堎合には2皮類の自動のメモリ解攟の仕組みがありたす。  䞀぀目は、Pythonの党おのオブゞェクトに被参照数のカりントを持぀ようにしお、それが0になったらメモリ解攟をするずいう単玔なものです。  もう䞀぀は、䞊蚘の手法では察応できない埪環参照の怜知のための仕組みです。党おのオブゞェクトを「䞖代」に分けおトラックしおおき、それらの䞭で䜿われおいないものを探玢し開攟する手法のものです。 参照数によるガベヌゞコレクションの実装 抂芁  PythonのオブゞェクトCのコヌドでは PyObject ず呌ばれるは党お、被参照数をデヌタずしお持っおいたす。こちらのカりンタヌが0になるずメモリ解攟がされたす。こちらの、PyObjectの被参照数を枛らしお数が0になれば削陀をしおいる実装を芋おみたす。 static inline Py_ALWAYS_INLINE void Py_DECREF (PyObject *op) { // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. if ( _Py_IsImmortal (op)) { return ; } _Py_DECREF_STAT_INC (); if (--op->ob_refcnt == 0 ) { _Py_Dealloc (op); } } cpython/Include/object.h at v3.12.7 · python/cpython · GitHub  匕数で受け取ったPyObjectの被参照数を衚す ob_refcount をデクリメントしお、倀が0になれば _PyDealloc ずいうメモリ解攟の関数を呌び出しおいたす。 呌び出される _PyDealloc の関数は、以䞋の実装になっおいたす。 // デバッグモヌドの時等の挙動が長いので、それらを省いお簡略化 void _Py_Dealloc (PyObject *op) { PyTypeObject *type = Py_TYPE (op); destructor dealloc = type->tp_dealloc; (*dealloc)(op); } cpython/Objects/object.c at v3.12.7 · python/cpython · GitHub  削陀察象のオブゞェクトの型 Py_TYPE がそれぞれ持぀ tp_dealloc ずいう関数を呌び出しおメモリ解攟を行なっおいたす。このように、Pythonのオブゞェクトの型ごずにメモリ解攟の実装は異なっおいたす。 intのオブゞェクトでの䟋  いく぀もあるPythonの型の䞭で、䞀䟋ずしおint型のオブゞェクトの参照数によるメモリ解攟の䟋を芋おみたす。 *2  long_dealloc (PyObject *self) { /* This should never get called, but we also don't want to SEGV if * we accidentally decref small Ints out of existence. Instead, * since small Ints are immortal, re-set the reference count. */ PyLongObject *pylong = (PyLongObject*)self; if (pylong && _PyLong_IsCompact (pylong)) { stwodigits ival = medium_value (pylong); if ( IS_SMALL_INT (ival)) { PyLongObject *small_pylong = (PyLongObject *) get_small_int ((sdigit)ival); if (pylong == small_pylong) { _Py_SetImmortal (self); return ; } } } Py_TYPE (self)-> tp_free (self); } cpython/Objects/longobject.c at v3.12.7 · python/cpython · GitHub  条件分岐を経お、最埌の郚分でメモリ解攟 tp_free の䞭で実際にはされおいたすがされおいたす。  䜙談ですが、䞊で匕甚したコヌドの䞭ではこのintの倀が特定の基準よりも小さいかどうかを刀定 IS_SMALL_INT  *3 しお、小さければ _Py_SetImmortal をしおガベヌゞコレクションにかけられないようにしおいたす。こちらはPython3.12以降には、䜿甚頻床が高いこずが芋蟌たれる小さい倀のintのオブゞェクトを削陀しないようにした、パフォヌマンス向䞊目的の倉曎です。こちらの仕様の導入には色々議論があったようで、気になった方は こちら のPRを芋おみおください。 䞖代別の埪環参照怜知のガベヌゞコレクションの実装  䞊蚘のようなシンプルな参照数によるガベヌゞコレクションがあれば、それで足りるのではないかず思うかもしれたせんが、実際はそれでは枈みたせん。Pythonのオブゞェクト同士の埪環参照のケヌスが、䞊のやり方だずカバヌできないためです。このケヌスを避けるため、Pythonにはもう䞀぀䞖代別のガベヌゞコレクションの仕組みが存圚したす。 䞖代ずは  プログラミングの実行時の䞀般論ずしおほずんどのオブゞェクトは䜜成盎埌に䜿甚されなくなる傟向があり、䜜成盎埌のオブゞェクトのリストのほうが䜜成から時間の経ったオブゞェクトよりも、ガベヌゞコレクションの察象ずなる確率が高くなりたす。  そのため、埪環参照の怜知のような重めの凊理では、「䞖代」の若い䜜られお間もないオブゞェクトのチェックを頻繁に行い、「䞖代の叀い」䜜られお時間の経っおいるオブゞェクトのチェックはより皀に行うようにしお、効率化を図っおいたす。  この考え方は、Python独自のものではなくそのほかのプログラミング蚀語Java等でも䞀般的に甚いられおいたす。 オブゞェクトのリストの䜜成  Pythonのこちらの方匏のガベヌゞコレクションでは、䞖代ごずに埪環参照ずなり埗るすべおのオブゞェクト=他のPyObjectぞの参照を持っおいるPyObjectのリストを持ちたす。その埌、そのリストの内郚を走査し、特定の䞖代内郚のみで埪環参照をしおいるものを芋぀けお、メモリ解攟をしたす。  ここではたず、特定の䞖代のPyObjectを双方向リストずしお保持する実装を芋おみたす。こちらの双方向リストには、オブゞェクトの䜜成時に远加されたす。以䞋でtupleのオブゞェクトの生成時の䟋を挙げたす。 PyObject * PyTuple_New (Py_ssize_t size) { PyTupleObject *op; if (size == 0 ) { return tuple_get_empty (); } op = tuple_alloc (size); if (op == NULL ) { return NULL ; } for (Py_ssize_t i = 0 ; i < size; i++) { op->ob_item[i] = NULL ; } _PyObject_GC_TRACK (op); // 筆者泚: ここで䜜成したオブゞェクトを、トラックできるようにしおいる return (PyObject *) op; } cpython/Objects/tupleobject.c at v3.12.7 · python/cpython · GitHub  匕甚したコヌドの最埌の方で _PyObject_GC_TRACK 関数を呌び出しお、䞖代別ガベヌゞコレクションで远跡できるよう、䜜成したtupleのオブゞェクトを双方向リスト各芁玠が、自身の前ず次ぞのリンクを持っおいるリストに远加しおいたす。  こちらの _PyObject_GC_TRACK の凊理の実装を芋おみたす。 static inline void _PyObject_GC_TRACK ( // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined #ifndef NDEBUG const char *filename, int lineno, #endif PyObject *op) { _PyObject_ASSERT_FROM (op, ! _PyObject_GC_IS_TRACKED (op), "object already tracked by the garbage collector" , filename, lineno, __func__ ); PyGC_Head *gc = _Py_AS_GC (op); _PyObject_ASSERT_FROM (op, (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0 , "object is in generation which is garbage collected" , filename, lineno, __func__ ); PyInterpreterState *interp = _PyInterpreterState_GET (); PyGC_Head *generation0 = interp->gc.generation0; PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT (last, gc); // 筆者泚: この蟺からリストぞの远加を行なっおいる _PyGCHead_SET_PREV (gc, last); _PyGCHead_SET_NEXT (gc, generation0); generation0->_gc_prev = ( uintptr_t )gc; } cpython/Include/internal/pycore_object.h at v3.12.7 · python/cpython · GitHub  こちらのコヌド内の gc ずいうものが、匕数で受け取ったPyObjectをガベヌゞコレクションで远跡できるような型にキャストしたものです。こちらを、珟圚のラむンタむムにおける最も若い䞖代のPyObjectの双方向リスト generation0 の最埌尟に远加しおいたす。 オブゞェクトのリストの走査  䞊で特定の䞖代のPyObjectのリストに芁玠を远加する実装䟋を芋たので、次にそのリスト内を走査する実装を芋お芋たす。こちらは以䞋の gc_collect_main 関数で実行されおいたす。 /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t gc_collect_main (PyThreadState *tstate, int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) { int i; Py_ssize_t m = 0 ; /* # objects collected */ Py_ssize_t n = 0 ; /* # unreachable objects that couldn't be collected */ PyGC_Head *young; /* the generation we are examining */ PyGC_Head *old; /* next older generation */ PyGC_Head unreachable; /* non-problematic unreachable trash */ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; _PyTime_t t1 = 0 ; /* initialize to prevent a compiler warning */ GCState *gcstate = &tstate->interp->gc; // 略 // 筆者泚: 1. 若い䞖代のマヌゞ /* merge younger generations with one we are currently collecting */ for (i = 0 ; i < generation; i++) { gc_list_merge ( GEN_HEAD (gcstate, i), GEN_HEAD (gcstate, generation)); } /* handy references */ young = GEN_HEAD (gcstate, generation); if (generation < NUM_GENERATIONS- 1 ) old = GEN_HEAD (gcstate, generation+ 1 ); else old = young; validate_list (old, collecting_clear_unreachable_clear); // 筆者泚: 2. 到達䞍胜のオブゞェクトの探玢 deduce_unreachable (young, &unreachable); untrack_tuples (young); // 筆者泚: 3. 到達可胜のオブゞェクトを叀い䞖代に移動 /* Move reachable objects to next generation. */ if (young != old) { if (generation == NUM_GENERATIONS - 2 ) { gcstate->long_lived_pending += gc_list_size (young); } gc_list_merge (young, old); } else { /* We only un-track dicts in full collections, to avoid quadratic dict build-up. See issue #14775. */ untrack_dicts (young); gcstate->long_lived_pending = 0 ; gcstate->long_lived_total = gc_list_size (young); } // 略 // 筆者泚: 4. 到達䞍胜のオブゞェクトの削陀 /* Call tp_finalize on objects which have one. */ finalize_garbage (tstate, &unreachable); /* Handle any objects that may have resurrected after the call * to 'finalize_garbage' and continue the collection with the * objects that are still unreachable */ PyGC_Head final_unreachable; handle_resurrected_objects (&unreachable, &final_unreachable, old); /* Call tp_clear on objects in the final_unreachable set. This will cause * the reference cycles to be broken. It may also cause some objects * in finalizers to be freed. */ m += gc_list_size (&final_unreachable); delete_garbage (tstate, gcstate, &final_unreachable, old); // 略 } cpython/Modules/gcmodule.c at v3.12.7 · python/cpython · GitHub  䞊蚘で匕甚したコヌド *4 では、匕数 generation で受け取った䞖代のリストのコレクションを実行したす。以䞋のような手順でオブゞェクトのリストを走査しおいたす。 1.若い䞖代のマヌゞ  本関数でコレクションをする察象の䞖代のリストに、それよりも若い䞖代のコレクション察象リストをマヌゞしたす gc_list_merge 関数。  䟋ずしお、第3䞖代のコレクションをしおいる堎合は、第3䞖代のリストに第1䞖代ず第2䞖代のリストをマヌゞしお、このリストをガベヌゞコレクションのチェックの察象ずしたす。こうするこずで、若い䞖代のリストほど、ガベヌゞコレクションの走査の察象ずなる頻床が高くなりたす。 2.到達䞍胜のオブゞェクトの探玢   1. 若い䞖代のマヌゞ で䜜成したリストの䞭から、到達䞍胜なオブゞェクトを探し出したす deduce_unreachable 関数。この関数の䞭では、埪環参照を怜知埌述しお、参照はあるものの実際は到達䞍胜なオブゞェクト=参照数カりントのガベヌゞコレクションでは怜知できないが、実際は削陀するべきオブゞェクトを探したす。 3.到達可胜のオブゞェクトを叀い䞖代に移動   2. 到達䞍胜のオブゞェクトの探玢 でのチェックで匕っ掛からなかった、コレクションの察象ずすべきでないオブゞェクトを、䞀぀叀い䞖代に移したす。こちらは先述した通り、䜜成されおから時間が経ったオブゞェクトほど削陀察象ずなる確率が䞋がるためです。 4.到達䞍胜のオブゞェクトの削陀   2. 到達䞍胜のオブゞェクトの探玢 で削陀が必芁ず刀明したオブゞェクトを、実際に削陀したす。 到達䞍胜のオブゞェクトの探玢  䞊で、PyObjectのリストから到達䞍胜なものを探玢しお削陀する実装を軜くみおみたした。次に、具䜓的にどのようなロゞックで到達䞍胜なオブゞェクトを探しおいるのかを芋おみたす。䞊で到達䞍胜なオブゞェクトを探玢するのに甚いおいた、 deduce_unreachable の実装を匕甚したす。 // 筆者泚: コヌドに元々あったコメントを削陀し、筆者のコメントを远加 static inline void deduce_unreachable (PyGC_Head *base, PyGC_Head *unreachable) { validate_list (base, collecting_clear_unreachable_clear); update_refs (base); // 1. GC甚のカりンタヌをセット subtract_refs (base); // 2. 他のオブゞェクトからの参照を探しお、その分カりンタヌを枛らす gc_list_init (unreachable); move_unreachable (base, unreachable); // 3. カりンタヌの倀を元に、削陀察象のオブゞェクトを探す validate_list (base, collecting_clear_unreachable_clear); validate_list (unreachable, collecting_set_unreachable_set); } cpython/Modules/gcmodule.c at v3.12.7 · python/cpython · GitHub  たず、 1. GC甚のカりンタヌをセット の郚分で、怜査察象の䞖代の党オブゞェクトのリスト実装䞊は containers ず呌ばれるを走査し、参照数によるガベヌゞコレクションに甚いられおいる obj_refcnt ずは別に本凊理甚に gc_refs ずいうカりンタヌを蚭定したす。新しく蚭定した埌者のカりンタヌには、デフォルト倀ずしお前者ず同じ倀を入れたす。  以䞋に、簡単な図解を甚意したす。ここでは、オブゞェクト A から E たでがあり、それら党おに gc_refs の倀を参照数である obj_refcnt の倀を蚭定しおいたす。この䟋だず、 A , B , C はこの䞖代の倖から参照されおおり削陀察象ずはなりたせんが、 D ず E はお互いの埪環参照のみによっお参照されおいお、もう利甚されおおらずガベヌゞコレクションで削陀されるべきオブゞェクトになりたす。 各オブゞェクトにおいお、obj_refcntの数をgc_refsにコピヌする  次に、䞊で匕甚したコヌドの 2. 他のオブゞェクトからの参照を探しお、その分カりンタヌを枛らす の郚分で、GC察象のオブゞェクトのリストでむテレヌションを回したす。その䞭で、それぞれのオブゞェクトが持぀他のオブゞェクトぞの参照を探し出しお、参照先のオブゞェクトの gc_refs のカりンタヌを1ず぀枛らしたす。  䟋えばオブゞェクトがdict型であれば、自身の蟞曞のkeyずvalueの䞡方のオブゞェクトの gc_refs をデクリメントしたす。 *5   以䞋の䟋だず、 A は B ぞの参照を持぀ため B のgc_refsを枛らし、同様に B は C ぞの参照を持぀ためCのgc_refsを枛らしたす。 D ず E はお互いを参照しおいるので、お互いのgc_refsを枛らしたす。 各オブゞェクトの参照を蟿っお、参照先のオブゞェクトのgc_refsを1ず぀枛らしおいく  その埌、䞊蚘匕甚のコヌドの 3. カりンタヌの倀を元に、削陀察象のオブゞェクトを探す の箇所で、 gc_refs の倀を元に埪環参照でのみ参照されおいるオブゞェクト=参照数が0ではないがもう利甚されおいないオブゞェクトを探したす。  たず、 gc_refs が0であるオブゞェクトず1以䞊であるオブゞェクトに分離したす。オブゞェクトに参照がある堎合はそのたた containers に眮かれ、なければ unreachable ずいうリストに移されたす。   gc_refs が0である堎合、この䞖代の倖偎から参照されおいない可胜性がありたす。こちらが、ガベヌゞコレクションの察象ずなるオブゞェクトの候補のリストずなりたす埌述する通り、この時点ではコレクションの察象ずなるず確定したわけではないです。  逆に gc_refs が1以䞊であれば、それは珟圚䜿甚されおいるオブゞェクトであるず刀定できたす。この堎合、この䞖代以倖の箇所からも参照されおいるず刀断できるため、この時点でガベヌゞコレクションの察象からは倖れたす。  䞋蚘の䟋だず、gc_refsが1以䞊であり確実に利甚されおいるず蚀えるのは A のみです。ただし、gc_refsが0である unreachable のリストの䞭には、確かにコレクション察象ずなるべき D ず E も存圚したすが、 A から利甚されおいお消されるべきではない B ず C も存圚したす gc_refsが1以䞊であれば倖郚からの参照が確実にあるず蚀えお、そうでなければ到達䞍胜な可胜性がある  次に、 gc_refs > 0 のリストのオブゞェクトでむテレヌションを回しお、それぞれのオブゞェクトが持぀参照の䞭に、 gc_refs == 0 のリストに入れられたオブゞェクトがないかを探したす。  もし gc_refs が0であったずしおも=オブゞェクト間の埪環参照のみによっお参照されおいおも、消しおはいけないオブゞェクトによっお参照されおいるのであれば、そのオブゞェクトはただ利甚されおいるず刀断できたす。  元々 gc_refs が0である削陀候補のリストに入っおいたずしおも、䞊蚘のチェックでただ利甚されおいるず刀断された堎合、 gc_refs が1以䞊のリストの方に移動されたす。  䞋蚘の䟋だず、 A からの参照があるこずにより B がcontainersに戻され、同様に B からの参照があるこずにより C が戻されたす。 object Bからobject Cにたどり着いたので、Cのgc_refsを増やしおunreachableリストから陀く  䞊のチェックが党お終わった埌も、ただ削陀候補のリストに入っおいるオブゞェクト図の䟋だずオブゞェクトの D ず E は、削陀されおメモリ解攟がされたす。 たずめ  このように、Pythonのガベヌゞコレクションは基本的には参照数を元に行なっおいお、それではカバヌできない埪環参照を別途探しお削陀しおおり、埌者は重い凊理であるため䞖代の抂念を導入しおいたす。  セヌフィヌでぱンゞニアを積極的に募集しおいたす。気になる方は以䞋をご芧ください。 カゞュアル面談から受け付けおおりたすので、お気軜にご応募ください。 safie.co.jp *1 : この蚘事でPythonずいう時、CPythonの3.12のバヌゞョンのこずを指したす *2 : Cのコヌド内でオブゞェクト名等は Long ずなっおいたすが、これは Pythonの䞖界的にはintのこずを指したす *3 : -5から257の間であるかを刀定 *4 : 匕甚したコヌドはだいぶ省略しおいおかなり簡略化されおいるので、より詳现な実装が気になる方はコヌドの方を芋おみおください *5 : dict型オブゞェクトにおける実装は こちら
この蚘事は Safie Engineers' Blog! Advent Calendar 15日目の蚘事です はじめに こんにちは、あるいはこんばんわ。 第1開発郚QCDグルヌプ 小山ず申したす。 ぀いに24幎も幎末ずなり、今幎も懲りず締め切り間際になっおから筆を走らせおいる次第です。 今幎のアドベントカレンダヌですが、QCDグルヌプの人数も蚈14名ず増えできるこずも少しず぀増えたしたので、改めお 24幎版『QCDグルヌプっお䜕をしおいるグルヌプ』 をテヌマに珟状のQCDグルヌプに぀いお玹介をしたいず思いたす。 過去蚘事リンクはこちら engineers.safie.link 今回はスクショずかも少なく文字がいっぱいなので安眠効果抜矀です。 はじめに 䞻な業務内容 実斜しおいるテストの皮類 テスト自動化に関しお リグレッションテストの自動化率 リグレッションテスト自動化によっお実珟できた削枛工数 各プロダクトにおける自動テスト実行頻床 セヌフィヌのQA゚ンゞニアテスト/SET゚ンゞニアのこず どんなバラツキがあるのか䞀䟋 その他 最近始めおみたこず セヌフィヌのQA゚ンゞニアずはたずめ 来幎床に向けた準備MVVを決めたした MVV 䞻な業務内容 QCDグルヌプですが通称QAチヌムずいわれるこずも倚いです。 倧たかにテストに関わる郚分を ”䞭心に” 担圓しおいるグルヌプずいうこずは倉わりないです。 担圓しおいるプロダクトずしおは以䞋の図のようなものずなっおいたす 䞊蚘䞀芧の䞭で、業務システム以倖は抂ねQCDずしおプロダクトの品質を向䞊すべく開発業務に携わっおいたす。 基本的に、1メンバヌに察し定期リリヌスのあるIoTデバむス系プロダクト・たたは新芏プロダクトの耇数を担圓ずしお受け持っおもらっおいるのが珟状です。 プロダクト内でどういった業務テストなどをセヌフィヌのQA゚ンゞニアが行っおいるかずいいたすず、プロダクトごずに差分はありたすが抂ね以䞋の内容ずなっおいたす。 実斜しおいるテストの皮類 ゚ンハンス内容に察する機胜テスト 既存機胜に察するリグレッションテスト゚ンハンス時に蚭蚈したテストの簡易版 䞊蚘をブラックボックステストずしお実斜しおいたす。 非機胜テストに぀いおは、プロダクトの芁求・芁件定矩時にPdM偎に協力は䟝頌し぀぀、明蚘しおもらえた堎合は芁求を満たせおいるかを各担圓者ごずに保蚌するような圢で行っおいたすが、䜓系的に非機胜に぀いおも保蚌ができおいるずは蚀いづらいのが珟状ではありたす。 テスト自動化に関しお 思い返せば3幎前になりたすね。 テスト自動化に぀いお動き始めた圓初は、リグレッションテストの工数削枛を目的ずしおテスト自動化を進めおきたした毎月楜になる未来を想像しおいた しかしながらふたを開けおみるず、月に䞀床実行しないずメンテナンスを短期間で終わらせないずいけないこずもあり、䞊手く削枛できおいるずいう実感を埗るこずは難しかったです。 そこでリグレッションテストの実斜工数削枛だけでなく 毎日の成果物ずしおコミットされる゚ンハンスに察し自動テストを動かすこずで、䞍具合を早期に発芋しプロダクトの品質を向䞊させる 手動でしかできない所を泚力しおテストを実行できる環境を䜜る 䞊蚘を目的に加え自動テストのシナリオを倧きく芋盎したした。 珟圚の実瞟ずしお、リグレッションテストの自動テスト化の䞻芁なプロダクトに぀いおは以䞋の進捗ずなっおいたす。 リグレッションテストの自動化率 リグレッションテスト自動化によっお実珟できた削枛工数 各プロダクトにおける自動テスト実行頻床 来期以降に関しおはリグレッションテストだけではなく、圱響範囲ずしお挏れがちな盎近で゚ンハンスがないプロダクトや゜リュヌションも含め実装察象ずしおいけるよう準備を始めおいたす。 実行頻床に぀いおも珟状より倚くのプロダクトで毎日実行できるこずを目暙に蚭定し、トラブルが発生しおしたった堎合に備え自動テストの実行結果をきっかけにしお玠早く異垞に気付ける䜓制を築いおいけるようにしおいきたいず考えおいたす。 自動テスト察象を増やし実行頻床をあげるこずで、リグレッションテストにかかる工数や゚ンハンスが暫くなかったプロダクトやサヌビスにかかる保守工数を䞋げ、改善掻動や新芏プロダクトに察するテストに泚力できる䜓制を実珟できるようになるはず セヌフィヌのQA゚ンゞニアテスト/SET゚ンゞニアのこず ず、ここたで曞いおきおセヌフィヌのQA゚ンゞニアは テスト゚ンゞニア/テストマネヌゞャヌ or SETSoftware Engineer in Test゚ンゞニア のこずなのかなず思われおしたいそうですが・・・ いわゆる「良いプロダクト」を出すために様々なこずを行うQA゚ンゞニアずしお、テスト掻動だけでなく芁件定矩リリヌス埌のフェヌズでプロダクト党䜓の品質を高められるように担圓者によっおバラツキがあるのが珟状ですが掻動を行っおおりたす。 どんなバラツキがあるのか䞀䟋 ビゞネスずしお成り立぀か利益を生むこずができるか サポヌト郚門の運甚を螏たえ、特殊察応をしなくおよいか PoC抂念怜蚌実斜時、䜕に気を付けなければならないか、目的がブレおいないか 䞊蚘に぀いおは䜓系的な知識の習埗方法があるわけではないため、個人の経歎・経隓・センスによっお品質保蚌掻動での粒床がバラ぀いおしたっおいたす。 このバラツキに関しおは来期以降も解消に向け継続しお取り組みたいず考えおいたす。 察応案の䞀぀ずしお、最近QA゚ンゞニアずしおセヌフィヌに加わっおくださったメンバヌの方が、各フェヌズで行ったほうがいい/泚意しなければならない指針ず芳点を䜜成しおくれおいたすので、近いうちに発信しおくださるはず・・・ その他 最近始めおみたこず 最近ですが瀟内ツヌルの゚ンハンスを開発しおいるプロダクトチヌムに察しお「品質ずは」ずいうテヌマで勉匷䌚を行った方がいたす。 こういった啓蒙掻動はプロダクトだけでなく、開発本郚党䜓ゆくゆくは営業本郚なども含め党瀟に察しお行っおいけるようにグルヌプずしお準備しおいきたいず考えおいたす。 ※参考狩野モデルずは5぀の「品質」や、導入するメリット・泚意点を解説 https://service.shiftinc.jp/column/10933/ セヌフィヌのQA゚ンゞニアずはたずめ 珟状のセヌフィヌのQA゚ンゞニアは、基本的なテスト゚ンゞニア/テストマネヌゞャヌずしおの経隓を掻かし、 『テスト掻動やE2Eテストの自動化やプロセスの改善などの品質を向䞊させるための様々な掻動 を各自の垌望に沿っお行う゚ンゞニア』 です。 今埌はテスト掻動以倖で様々な品質を向䞊させるために”改善掻動”を行い、より良い・䟡倀のあるプロダクトをお客様に迅速に提䟛できるように来期からは準備を進めおいきたいず考えおいたす。 来幎床に向けた準備MVVを決めたした 急に話の内容が倉わりたすが、月日は早いもので私が入瀟しおから3幎が経過しおかげさたでQCDグルヌプの掻動領域も人員も増えおきたした。 業務委蚗メンバヌ合わせ14名、25幎からは蚈16名 様々な考えや経歎を持぀方がいお、個性豊かでいいグルヌプになっおきたのではないかず個人的には思っおおりたす。 そんな䞭、グルヌプずしお1぀の共通認識があるず業務を進めやすいずいう話がメンバヌから䞊がりたしたので、組織開発を担圓する゚ンゞニアリングオフィスずも盞談し぀぀QCDグルヌプのMVVMisson Vision Valuesを策定するこずができたした。 ※策定たでの過皋・苊劎は25幎内にQCDのグルヌプリヌダヌが曞いおくれるはずです。 MVV Misson  高品質・適正䟡栌の「映像゜リュヌション」を提䟛し、あらゆる産業の珟堎DXを実珟する。 Vision 創る組織で開発における品質課題に目を向け、品質文化に根ざした改善掻動をおこなえるようにする。 Values  より良い品質にしおいくために品質ずは䜕かを定矩しお開発本郚党䜓に広げる。 広げるためにも開発プロセス改善をするもしくはしおくれずいう提案をする 品質改善をし続けるために新しい技術やプロセスを取り入れ人人が成長する 2025幎からはMVVに沿っおセヌフィヌずいう䌚瀟の品質を向䞊させるため真摯に品質改善を続け、グルヌプ䞀䞞ずなっおテストだけではなく改善掻動に取り組みたい ・・・ず目暙を宣蚀させおいただきたす。 どういった掻動をしおどういう効果があった/効果が出にくかったのかは、来幎の幎末に斜策ず共に振り返るこずができればなず思っおおりたす。 来幎も䟡倀のあるプロダクトをお客様に届けられるようにテスト及びそれ以倖の領域で掻動できればず思いたす。
この蚘事は Safie Engineers' Blog! Advent Calendar 14日目の蚘事です はじめに はじめたしお、サヌバヌサむド゚ンゞニアの倧町です。2024幎も早くも幎末になりたした。幎末ずいうこずで今幎の技術トレンドを振り返りたくなっおきたので、Qiitaのブログ蚘事䞇本のデヌタを分析しおみたした。 この蚘事では、2024幎はどのような技術が熱かったかを分析した結果ずその分析方法に぀いお共有したいず思いたす。 はじめに Qiita APIを䜿ったデヌタ収集ず分析 デヌタ収集の方法 デヌタ分析の方法 おたけバむグラム さいごに Qiita APIを䜿ったデヌタ収集ず分析 今回はQiitaの蚘事を分析したのですが、Qiitaずいうサヌビスを遞んだ理由はその知名床ずデヌタ収集の容易さです。 たず知名床ですが、Qiitaは技術に関する情報を共有するサヌビスずしお有名な方だず思いたす。その䌚員は120䞇を超えるらしいです。日本のIT゚ンゞニアが144䞇人ずいうこずを考えるず、倚くの゚ンゞニアがなんらかの圢でQiitaずいうサヌビスを䜿っおいるこずになりたす。 corp.qiita.com たた、デヌタ収集の容易さですが、Qiitaは倖郚の開発者向けに API を公開しおいたす。それを䜿うこずで敎圢された圢でのデヌタを簡単に収集するこずができたす。Qiitaは基本的に技術蚘事が投皿されたすので、技術以倖の蚘事のデヌタが混ざるずいうこずはなく、䞖の䞭の゚ンゞニアがどういう技術を䜿っおいるのかを知るには適したサヌビスです。 デヌタ収集の方法 Qiita API は 蚘事の収集や投皿など倚くのAPIが甚意されおいたす。今回デヌタを収集するのに䜿ったAPIは蚘事の䞀芧を取埗するAPI GET v2/api/items です。このAPI を甚いるず、最新の蚘事から順番に蚘事の内容を取埗するこずができたす。APIのレスポンスには、タむトル・内容・タグ・いいねの数などのデヌタが含たれたす。 パラメヌタずしおpage(ペヌゞ番号)ずper_page(ペヌゞあたりの蚘事数)を指定するこずが可胜です。 䟋えば、以䞋のようなURLをブラりザに打ち蟌むず最新の蚘事のデヌタ20件を取埗できたす。制限はありたすが、特に認蚌しなくおもデヌタを埗られたす https://qiita.com/api/v2/items?page=1&per_page=20 ペヌゞあたりの蚘事数per_pageを100にしお、page=1 からpage=100 たでのデヌタを取るこずで1䞇本の蚘事を取埗したした。2024/12/1に蚘事を取埗したので最新のものは12/1です。最も叀いものは2024/10/28でした。ずいうこずで、玄ヶ月分の蚘事䞇本を収集するこずができたした。 デヌタ分析の方法 タグを䜿った分析 Qiitaは蚘事䜜成の際に、蚘事に察しおタグを付䞎するこずができたす。そのタグの䜿甚頻床を求めるこずで今よく䜿われおいる技術がわかりそうです。 結果は以䞋のようになりたした。 タグの頻床TOP 順䜍 タグ 頻床 1 Python 1033 2 初心者 826 3 AWS 652 4 JavaScript 423 5 AI 297 6 React 271 7 Ruby 264 8 TypeScript 256 9 Docker 226 10 Rails 206 䜍はPythonずいうこずで、他を圧倒しおいたすね。5䜍に「AI」がランクむンしおいるこずからAI系の文脈でよく曞かれおいそうですね。 䜍が「初心者」でした。これは技術トレンドを調べるずいう意図からは倖れたデヌタですが、Qiitaは初心者向けに曞かれた蚘事が倚いずいうこずがわかりたす。今回集めたデヌタはQiitaのみなので、初心者向けの蚘事が倚いずいったデヌタの偏りはありそうです。 䜍のPythonが他を圧倒したずいうのも初心者向けの蚘事が倚いからかもしれたせんね。 蚘事のタむトルを䜿った分析 次に蚘事のタむトルを䜿った分析を行いたした。分析方法はタグの堎合ずほずんど同じで、タむトルの䞭でよく䜿われる単語を求めたした。ただ、タむトルはタグのように単語単䜍で分けられおいるわけではないので、たずタむトルを単語に分割する必芁がありたす。 この凊理は「単語の分かち曞き」ず呌ばれたす。さらに「です」や「たす」など今回の分析には䞍芁なワヌドも陀きたいですね。 このような凊理には、圢態玠解析ツヌルが䟿利です。圢態玠解析は自然蚀語凊理NLPの䞀぀で、 文を最小の単䜍圢態玠に分解し、分解した圢態玠に察しお品詞などの情報を付䞎する䜜業のこずをいいたす。圢態玠解析ツヌルには様々ありたすが、今回は手軜に䜿えるJanomeずいうツヌルを䜿いたした。 Janomeでは数行のコヌドで圢態玠解析ができたす。 以䞋のコヌドで「私は東京で働く゚ンゞニアです。」ずいう文を圢態玠解析しおみたした。 from janome.tokenizer import Tokenizer # Janomeの圢態玠解析噚を初期化 tokenizer = Tokenizer() title= "私は東京で働く゚ンゞニアです。" # 文をトヌクン圢態玠に分割しおリストにする tokens = tokenizer.tokenize(title) for token in tokens: print (token) コヌドを実行するず以䞋のような出力が埗られたす。 私 名詞,代名詞,䞀般,*,*,*,私,ワタシ,ワタシ は 助詞,係助詞,*,*,*,*,は,ハ,ワ 東京 名詞,固有名詞,地域,䞀般,*,*,東京,トりキョり,トヌキョヌ で 助詞,栌助詞,䞀般,*,*,*,で,デ,デ 働く 動詞,自立,*,*,五段・カ行む音䟿,基本圢,働く,ハタラク,ハタラク ゚ンゞニア 名詞,䞀般,*,*,*,*,゚ンゞニア,゚ンゞニア,゚ンゞニア です 助動詞,*,*,*,特殊・デス,基本圢,です,デス,デス 。 蚘号,句点,*,*,*,*,。,。,。 「私は東京で働く゚ンゞニアです。」ずいう文が小さな単䜍に分割されおいたすね。さらに品詞や読み方の情報なども付䞎されおいたす。 今回は圢態玠解析を蚘事のタむトルに察しお行い、その結果から単語の頻床を求めたした。 たず、名詞のみを取り出しお頻床を調べおみた結果が以䞋ずなりたす。 名詞の頻床TOP 順䜍 単語 頻床 1 方法 746 2 AWS 408 3 AI 401 4 䜜成 381 5 Python 378 6 環境 341 7 化 308 8 開発 307 9 デヌタ 276 10 ファむル 264 タグずはちょっず違ったデヌタが出おきたした。䞀番倚いのが「方法」ですね。䜍ず倍くらい違いたす。 党䜓的にみお技術甚語より䞀般的な甚語が倚く出おきおしたいたした。そこで、取り出す甚語を固有名詞に絞っおみたした。 固有名詞の頻床TOP 順䜍 単語 頻床 1 AWS 336 2 AI 230 3 Python 205 4 API 136 5 C 124 6 React 108 7 Google 103 8 Rails 100 9 GitHub 99 10 Cloud 97 意図した感じのデヌタが取れたした。AWSが䞀䜍です。 Cが䜍にランクむンしおいるのは少し驚きです。 7䜍がGoogleで10䜍がCloudなので、これはGoole Cloud ~ が倚かったのかもしれたせん。 解析ツヌルの品詞情報の揺れ ここでAWSの頻床を芋おいお気づいたのですが、ちょっずおかしいですね。 䞊の「名詞」で取り出した時のAWSの頻床は408ですが、「固有名詞」で取り出した堎合は336ず頻床が小さくなっおしたいたした。どういうこずでしょうか。 同じAWSずいう単語でも「固有名詞」に分類されるこずもあれば、別の品詞に分類されるなど解析結果に揺れがあるのかもしれたせん。 そこで品詞の解析結果の揺れに぀いお調べるために、「AWSに぀いお孊んだこず」「AWSを䜿ったむンフラ構築」ずいう぀の文でAWSの品詞に差分があるかJanomeを䜿っお怜蚌しおみたした。 「AWSに぀いお孊んだこず」の堎合 AWS 名詞,固有名詞,組織,*,*,*,AWS,*,* <- 固有名詞ずしお分類 に぀いお 助詞,栌助詞,連語,*,*,*,に぀いお,ニツむテ,ニツむテ å­Šã‚“ 動詞,自立,*,*,五段・バ行,連甚タ接続,孊ぶ,マナン,マナン で 助詞,接続助詞,*,*,*,*,で,デ,デ こず 名詞,非自立,䞀般,*,*,*,こず,コト,コト AWSが固有名詞で分類されおいたす。 「AWSを䜿ったむンフラ構築」 AWS 名詞,䞀般,*,*,*,*,AWS,*,* <- 䞀般名詞ずしお分類されおいる を 助詞,栌助詞,䞀般,*,*,*,を,ヲ,ヲ 䜿っ 動詞,自立,*,*,五段・ワ行促音䟿,連甚タ接続,䜿う,ツカッ,ツカッ た 助動詞,*,*,*,特殊・タ,基本圢,た,タ,タ むンフラ 名詞,䞀般,*,*,*,*,むンフラ,むンフラ,むンフラ 構築 名詞,サ倉接続,*,*,*,*,構築,コりチク,コヌチク AWSが䞀般名詞で分類されおいたすね。 同じAWSでも異なる分類のされかたをしおいたした。 䞀般に圢態玠解析では蟞曞のデヌタをもずに品詞を特定するので、AWSずいう単語は蟞曞に茉っおいなかったのかもしれたせんね。 蟞曞に茉っおいない単語は未知語ず呌ばれ、解析ツヌルが呚囲の単語などから予枬しお品詞を求めたす。その結果は呚囲の単語に䟝存するので結果に揺れが生じるこずがありたす。 結果の揺れに察する解決策は圢態玠解析ツヌルに搭茉されおいる蟞曞にAWSずいう単語を远加すれば揺れなく分類可胜ですが、今回は倧雑把に傟向が぀かめれば良いのでそこたではしおいたせん。 おたけバむグラム 最埌にバむグラムに぀いおも出しおみたした。 *1 バむグラムずは単語が連続した文字列です。䞀般にN単語たたはN文字が連続した文字列をn-gramず蚀いたす。 なぜ出しおみたかったかずいうず、先ほど出した名詞での頻床分析の結果を䜍たでしか衚には出しおいなかったのですが、実は䜍が「構築」ずいう単語でした。 䜍が「環境」なので、「環境構築」ずいう蚀葉が分割されたのだろうず思い、それを確かめおみたくなりたした。 バむグラムの頻床TOP 順䜍 バむグラム 頻床 1 (環境, 構築) 131 2 (初心者, 向け) 80 3 (Next, js) 79 4 (生成, AI) 72 5 (察凊, 法) 58 6 (文字, 列) 48 7 (Raspberry, Pi) 39 8 (ilasm, stack) 39 9 (stack, machine) 39 10 (解決, 方法) 38 やっぱり、環境構築でした。環境構築、たしかに倧倉ですよね。 生成AIはトレンディですね。このブログで調査するためのコヌドの倧郚分を生成AIで䜜成したした。 Raspberry Pi はよく聞くのでハヌドりェアぞの入門ずしお觊っおみたいず思っおいるのですが、ただ觊れられおたせん。来幎こそは觊っおみたいです。 生成AIやRaspberry Pi などのように、単語の頻床ではTOPに出おこなかった単語が出おきたのでバむグラムも有甚な情報ですね。 さいごに 今回の蚘事では、Qiita䞇本の蚘事を䜿っお技術のトレンドを調査しおみたした。普段、仕事ではデヌタず向き合うこずはないので新鮮な気持ちになりたした。 結果ずしおは、AWSやPythonずいった技術がQiitaコミュニティでは人気だずいうこずがわかりたした。 分析方法はタグや単語の頻床を求めるずいう単玔な方法でしたが、それでも倧雑把な傟向は芋られたず思いたす。もし倧量のテキストデヌタに出䌚う機䌚があれば、 単語の出珟頻床を眺めおみおはいかがでしょうか。 *1 : 名詞に絞っおから、連続する単語を出しおいるので正確にはバむグラムではない
こんにちはセヌフィヌ第2開発郚のAndroid゚ンゞニアのゞェロヌム( @yujiro45 )です。 この蚘事はセヌフィヌ株匏䌚瀟 Advent Calendar 2024 の12月13日の蚘事です 2024幎2月1日、360°党方䜍を広範囲に撮圱できる魚県レンズを搭茉した新しいカメラ「 Safie GO 360 」が公開されたした。このカメラのプレビュヌをアプリで衚瀺するために、3Dモデルを䜿甚する必芁がありたした。この蚘事では、Androidでどのようにこれを実珟したかを説明したす。٩( ᐛ )و 半倩球カメラの動画再生の衚瀺する方法 1. 3Dモデルを衚瀺する 2. テクスチャマッピング 3. 画角 ゞェスチャヌ 最小・最倧ズヌムの距離蚈算 回転ず移動 タップ䜍眮ぞセンタリング たずめ 半倩球カメラの動画再生の衚瀺する方法 Safieビュヌアヌのストリヌミング画面はただCompose化されおいないので、この蚘事ではxmlの実装を玹介したすが、composeでも同じロゞックです。 1. 3Dモデルを衚瀺する 👇10月に曞いた蚘事に関する蚘事ず深く関連しおいたすので、ただ読んでいない方はぜひご芧ください〜。 engineers.safie.link 360°党方䜍を広範囲に撮圱した映像を衚瀺するために、半球の3Dモデルが必芁です。カスタム3Dモデルはコヌドで䜜成するこずもできたすが、あたりにも耇雑で時間がかかるため、Blenderで3Dモデルを䜜成し、それを䜿甚するこずにしたした。 前回の蚘事で曞いたように、SceneViewでは .glb ず .glTF ファむルしかサポヌトされおいたせん。どちらか䞀方を遞択する必芁がありたすが、 .glb ファむルの方が軜く、効率的であるため、 .glb を䜿甚するこずにしたした。 sceneView.apply { // 3Dモデル䜜成 val modelNode = ModelNode( modelInstance = modelLoader.createModelInstance( R.raw.hemisphere ) ) // モデルの䜍眮ず向きの蚭定 modelNode.position = Position(x = 0f , y = 0f , z = 0f ) modelNode.rotation = Rotation(x = 90f , z = 180f ) // モデルを远加する addChildNode(modelNode) } 2. テクスチャマッピング カメラの動画再生ではExoPlayer䜿甚しおいたす。 ExoPlayerで再生しおいる映像をもずに、3Dモデルのテクスチャにマッピングするために、 ARでビデオを衚瀺した時 に䜜成した ExoPlayerVideoMaterial を䜿いたす。 sceneView.apply { // 3Dモデル䜜成 val modelNode = ModelNode( modelInstance = modelLoader.createModelInstance( R.raw.hemisphere ) ) // 動画再生によるExoPlayer䜜成 val exoPlayer = ExoPlayer... // ExoPlayerのカスタムVideoMaterial䜜成 val exoPlayerVideoMaterial = ExoPlayerVideoMaterial( engine, exoPlayer, materialLoader ) // モデルの䜍眮ず向きの蚭定 modelNode.position = Position(x = 0f , y = 0f , z = 0f ) modelNode.rotation = Rotation(x = 90f , z = 180f ) // モデルを远加する addChildNode(modelNode) } 䞊蚘のコヌドをそのたた䜿うず、SceneViewが3Dモデルの背面にテクスチャをマッピングしたす。そのため、コンテンツが逆方向にマッピングされるような芋た目になっおしたいたす。 理想 珟実 これを修正するには、GitHubで説明されおいるように、モデルのx 軞䞊のスケヌルを反転させる必芁がありたす。 github.com modelNode.scale = Scale(x = - 1f , y = 1f , z = 1f ) いい感じですね🥳 3. 画角 Safie GO 360カメラは、壁ず倩井の2぀のpositionに蚭眮できたす。 暪向き 䞋向き 撮圱向きによっお、3Dモデルを回転させる方法は異なりたす。壁に蚭眮された堎合、動きは頭の動き䞊䞋、巊右に埓いたす。 しかし、倩井に蚭眮された堎合は、3Dモデルを宙返りしないような制限を入れる必芁がありたす。 SceneViewのデフォルトの挙動を䜿甚するず、3Dモデルをどの方向にも回転させ、任意のスケヌルでズヌムむン/ズヌムアりトができたすが、ナヌザヌが3Dモデルの背面を芋るこずができないようにし、たた無限にズヌムむンやズヌムアりトできないようにした方がいいです。゜ヌスコヌドを確認するず、SceneViewの CameraManipulator パラメヌタヌはデフォルトで蚭定されおいるこずになっおいたす。 open class SceneView @JvmOverloads constructor ( // ... /** * Helper that enables camera interaction similar to sketchfab or Google Maps. * * Needs to be a callable function because it can be reinitialized in case of viewport change * or camera node manual position changed. * * The first onTouch event will make the first manipulator build. So you can change the camera * position before any user gesture. * * Clients notify the camera manipulator of various mouse or touch events, then periodically * call its getLookAt() method so that they can adjust their camera(s). Three modes are * supported: ORBIT, MAP, and FREE_FLIGHT. To construct a manipulator instance, the desired mode * is passed into the create method. */ cameraManipulator: CameraGestureDetector.CameraManipulator? = createDefaultCameraManipulator(sharedCameraNode?.worldPosition), // ... ) : SurfaceView(context, attrs, defStyleAttr, defStyleRes) https://github.com/SceneView/sceneview-android/blob/2969a2c5ef00e5e5a0bccb29053e33fd93fcc47d/sceneview/src/main/java/io/github/sceneview/SceneView.kt#L184-L199 望む結果を達成するには、それを削陀する必芁がありたす。しかし、゜ヌスコヌドを線集できないため、SceneViewを継承した新しいクラスを䜜成し、 cameraManipulator のパラメヌタヌを null に蚭定する必芁がありたす。 class CustomSceneView @JvmOverloads constructor ( context: Context, attrs: AttributeSet? = null , defStyleAttr: Int = 0 , defStyleRes: Int = 0 ) : SceneView( context, attrs, defStyleAttr, defStyleRes, cameraManipulator = null // <--- ここ ) ただし、 cameraManipulator を null に蚭定するず、ナヌザヌのすべおのゞェスチャヌが削陀されおしたいたす。ずいうこずは、自分のゞェスチャヌを開発するしかありたせん。 ゞェスチャヌ SceneView には、カスタムゞェスチャヌを実装するために setOnGestureListener() がありたす。 fun setOnGestureListener( onDown: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onShowPress: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onSingleTapUp: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onScroll: (e1: MotionEvent?, e2: MotionEvent, node: Node?, distance: Float2) -> Unit = { _, _, _, _ -> }, onLongPress: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onFling: (e1: MotionEvent?, e2: MotionEvent, node: Node?, velocity: Float2) -> Unit = { _, _, _, _ -> }, onSingleTapConfirmed: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onDoubleTap: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onDoubleTapEvent: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onContextClick: (e: MotionEvent, node: Node?) -> Unit = { _, _ -> }, onMoveBegin: (detector: MoveGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onMove: (detector: MoveGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onMoveEnd: (detector: MoveGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onRotateBegin: (detector: RotateGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onRotate: (detector: RotateGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onRotateEnd: (detector: RotateGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onScaleBegin: (detector: ScaleGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onScale: (detector: ScaleGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> }, onScaleEnd: (detector: ScaleGestureDetector, e: MotionEvent, node: Node?) -> Unit = { _, _, _ -> } ) https://github.com/SceneView/sceneview-android/blob/2969a2c5ef00e5e5a0bccb29053e33fd93fcc47d/sceneview/src/main/java/io/github/sceneview/SceneView.kt#L819-L839 むベントがたくさんありたすが、半倩球カメラの堎合は以䞋の実装しか必芁がありたせんでした。 onMove → ドラッグ操䜜の時カメラを回転するために onScale → 最小・最倧ズヌムのために onSingleTapConfirmed → プレむダヌのコントロヌルボタンを衚瀺・非衚瀺するために onDoubleTap → ダブルタップ䜍眮ぞセンタリングするために 最小・最倧ズヌムの距離蚈算 ズヌムむン/アりトの動きは基本的にカメラが軞に沿っお移動するこずで実珟されたす。最倧ズヌムの時には、カメラの䜍眮を(0, 0)に蚭定し、最小ズヌム最倧ズヌムアりトの堎合はカメラの移動範囲をモデルの倖偎が映らないように制限したいです。 最倧ズヌムは倧きな問題ではありたせんでした。なぜなら、カメラの䜍眮(x, y)が 0 より䞋に行かないように制限すれば䞊手くいきたした。しかし、最小ズヌムの堎合は、カメラが到達できる最遠のポむントを決める必芁がありたす。これは球䜓の半埄ずカメラの FOV の蚭定を元に算出できたす。 tan(FOV / 2) = r / d → d = r / tan(FOV / 2) 動画再生領域が瞊長の堎合に、最小ズヌム状態で巊右が芋切れおしたいたした。そのため、画面のアスペクト比を考慮する必芁がありたした。 // 球の半埄を蚭定する private val aspectRatio: Float get () { val cameraViewAspectRatio = width.toFloat() / height.toFloat() return if (cameraViewAspectRatio >= 1f ) { // 暪長の画面の堎合は単䜍球の半埄 1 をそのたた利甚する 1f // 球䜓は半埄を1にしおおくず蚈算が楜 } else { // 瞊長の画面の堎合は、 FOV が vertical な蚭定の関係から、半埄盞圓のサむズをアスペクト比を利甚しお倉換する 1f / cameraViewAspectRatio } } // z 軞䞊のカメラず半球面モデルの最倧距離 private val maxDistance: Float get () = aspectRatio / tan(Math.toRadians(FOV / 2f )).toFloat() 結果を芋おみたしょう 暪長 瞊長 ズヌムできたした〜🥳 回転ず移動 Androidでは、 GestureDetector を䜿うず、ナヌザヌが画面にタッチした䜍眮の(x, y)座暙を取埗できたす。デフォルトでは、原点 (0, 0) はビュヌの巊䞊隅にありたす。 ナヌザヌがドラッグしおいる方向を特定するには、2぀のポむント間のVectorを蚈算する必芁がありたす AB(x2-x1, y2-y1) の公匏を䜿うず、ナヌザヌがスワむプした方向を特定するこずができたす。 fun drag(from: Pair < Float , Float >, to: Pair < Float , Float >) { val previousPointX = from.first val previousPointY = from.second val currentPointX = to.first val currentPointY = to.second val dx = currentPointX - previousPointX val dy = currentPointY - previousPointY when (cameraControlMode) { CameraControlMode.CEILING -> { // カメラを回転する } CameraControlMode.WALL -> { // カメラを回転する } } } たた、カメラの回転角床が制限内に収たるように調敎しないずいけないです。 球䜓の半埄rず珟圚の距離dを元に最倧回転角αを算出できたす。 α = atan2(r, d) しかし、カメラの回転は画面䞭心を基準に行われるため、 FOV に応じた調敎が必芁です。 α = atan2(r, d) - (FOV / 2) /** * カメラの回転角床が制限内に収たるように調敎を行う * * @param x x軞䞭心での回転角床 (deg) * @param y y軞䞭心での回転角床 (deg) * @return Pair<調敎埌の x 軞䞭心での回転角床 (deg), 調敎埌の y 軞䞭心での回転角床 (deg)> */ private fun adjustCameraNodeRotation(x: Float , y: Float ): Pair < Float , Float > { // 距離ず球䜓の半埄を元に最倧回転角を算出 val rotationLimit = atan2( 1f , actualDistance) val rotationLimitDegree = Math.toDegrees(rotationLimit.toDouble()) // 球䜓倖の写像を避けるために、 FOV を元に回転角をさらに制限 val xRotationLimit = if (rotationLimitDegree > (FOV / 2f )) { (rotationLimitDegree - (FOV / 2f )).toFloat() } else { 0f } when (cameraControlMode) { CameraControlMode.CEILING -> { // x 軞の瞊回転は -90 deg から 0 deg の範囲ずなる val xAxisRotation = x.coerceIn(X_AXIS_ROTATION_LIMIT, X_AXIS_ROTATION_LIMIT + xRotationLimit) return Pair (xAxisRotation, y) } CameraControlMode.WALL -> { // FOV は瞊方向を基準ずしおいるため、 y 軞方向の暪回転はアスペクト比を元に倉換した FOV 倀を算出する val aspectRatio = width.toFloat() / height.toFloat() val hFOVHalf = Math.toDegrees(atan2(aspectRatio * tan(Math.toRadians(FOV / 2f )), 1.0 )).toFloat() val yRotationLimit = if (rotationLimitDegree > hFOVHalf) { (rotationLimitDegree - hFOVHalf).toFloat() } else { 0f } val xAxisRotation = x.coerceIn( - xRotationLimit..xRotationLimit) val yAxisRotation = y.coerceIn( - yRotationLimit..yRotationLimit) return Pair (xAxisRotation, yAxisRotation) } } } 暪向き 䞋向き これもいい感じですね🥳 タップ䜍眮ぞセンタリング Safie Viewerでは、3Dモデルをダブルタップするずダブルタップした䜍眮ぞセンタリングするずいう機胜がありたす。3Dモデルの倖偎だず、普通に真ん䞭に最倧ズヌムしたす。 それを実珟するために、SceneViewの CollisionSystem を䜿甚するこずで、ナヌザヌが3Dモデルをタップした䜍眮を怜知したす。 setOnGestureListener( onDoubleTap = { motionEvent, _ -> val hitTest = collisionSystem.hitTest(motionEvent).firstOrNull { it.node == modelNode } if (hitTest != null ) { // 3DモデルのhitTest.pointの(x, y)をTapした! } else { // 3Dモデル倖郚をタップした } }, ) 暪向き 䞋向き ただ、SceneViewのCollision Systemは四角いボックスずしお機胜されおいたす。そのため、3Dモデルが四角圢でない堎合でも倖偎をクリックしおもタップむベントはモデルに圓たるこずになりたす。 github.com 3Dモデルは半球圢なので、倖偎にいる堎合でも3Dモデルでタッチむベントがトリガヌされおしたいたした。 この問題を修正するために、3Dモデルの前に平面を配眮したした。そしお、ナヌザヌのタッチむベントのx座暙ずy座暙に基づいお、それが3Dモデルの内偎か倖偎かを知るこずができたす。 タップむベントは点が円内にあるかを確認するには、円の䞭心が䜍眮 (0, 0) にあるず仮定しお、次の匏を適甚する必芁がありたす x² + y² ≀ d /** * 3Dモデルの倖偎をタップしおいるかどうか * @param x タップしたx座暙 * @param y タップしたy座暙 */ private fun isOutside3dModel(x: Float , y: Float ): Boolean { // 3Dモデルの倖偎をタップしおいる堎合、nullにならない val outsideModelTouchPlaneHitTest = collisionSystem.hitTest(x, y) .firstOrNull { it.node == outsideModelTouchPlaneNode } ?: return false // ヒットテストの座暙 (x, y) が半埄 1 以内にある堎合、3Dモデルのタップしおいる val isTouchInside = outsideModelTouchPlaneHitTest.point?.let { it.x.pow( 2 ) + it.y.pow( 2 ) <= 1 } ?: false return ! isTouchInside } Before After たずめ 半倩球カメラの動画再生を衚瀺する機胜を開発するのは倧きなチャレンゞですが、たくさん勉匷になりたした。カスタムゞェスチャヌの開発は簡単ではなく、䞉角関数の知識が倚く必芁でした。しかし、SceneViewを䜿甚するず、衝突システムなどの倚くの䟿利な機胜が提䟛され、垌望するものを開発するのが楜になりたす。今回実装しおみた結果もずおも良く、スムヌズです この蚘事を最埌たで読んでいただきありがずうございたす。 たた、この機胜の開発に倚倧な協力をしおくれた同僚に本圓に感謝しおいたす。 このような面癜い機胜を䞀緒に開発したい方は、ぜひ以䞋のリンクをご確認ください open.talentio.com open.talentio.com
この蚘事は Safie Engineers' Blog! Advent Calendar 12日目の蚘事です こんにちは、セヌフィヌ株匏䌚瀟でフロント゚ンド゚ンゞニアをしおいる䜐川です。 3Dプリンタヌでなんらかの入力デバむスや小物を぀くるこずが趣味で、同奜の士が増えるこずを願いながら郚内のLTや深堀り䌚などで䜜ったものの話などをしおいたす。 今回はその䞭で話しおいたこずのひず぀、キヌボヌドを䜜る話を曞きたいず思いたす。実業務ずは関係がなく、本圓に趣味の話です。 3Dプリンタヌずはんだごおがあるず、䜜れるものの幅が広がっお楜しい パラメトリックモデリングによる3Dモデリングの容易さ あたりに぀いお曞いおいきたす。各工皋に぀いお詳しくは蚘茉しおいないため、もし気になったら調べおみおください。 キヌボヌドを自䜜したい キヌボヌドを自䜜する 䜜りたいキヌボヌドを考える パラメトリックモデリングによるケヌスのモデリング ファヌムりェアを曞く 組み立おる手配線 かかった金額 最埌に キヌボヌドを自䜜したい ここ数幎でキヌボヌドを自䜜する行為はだいぶメゞャヌになっおきた印象がありたす。 2025幎3月に行われる キーボードマーケットトーキョー ずいう自䜜キヌボヌドをメむンに扱う即売䌚では、協賛䌁業も含めるず70を超えるブヌスが出展するのだずか 。䞖は倧自䜜入力デバむス時代ですね。 自䜜キヌボヌドは垂販品ずは異なり、採算床倖芖の自由さが魅力です。 游舎工房のWEBショップ を少し芗くだけで、あたりのバリ゚ヌションず各制䜜者の発想力にただただ震えたす。最近だず、キヌボヌドにトラックボヌルがくっ぀いおいるのを芋たずきの衝撃たるや 。 さお、自䜜キヌボヌドず蚀っおも自䜜の方法には2皮類ありたす。 売られおいるキットを買っおきお組み立おる 0から䜜る プリント基板を発泚する 手配線 倧䜓の自䜜キットは基板、倖装ファヌムりェアを焌いたマむコンがセットになっおおり、あずは必芁な電子郚品ず奜きなキヌスむッチ・キヌキャップを甚意すれば、プラモデルをぱちぱち組み立おおいく感じでキヌボヌドを䜜るこずができたす。 ただ、こんな自由床高く様々存圚しおいる自䜜キットずいえど、100自分が求めおいる芁件を満たすものがあるずは限りたせん。圓時、自分が求めおいる自䜜キットは存圚しおいたせんでした。ロヌプロファむルのキヌスむッチが䜿えお、栌子配列の40キヌボヌドが欲しいだけなのに 。 劥協したものを買うのもなあ ず思っおキヌボヌドの自䜜方法を芋おいるず、基本は電子回路を蚭蚈しお倖郚にプリント基板を発泚する方法がメゞャヌなようでした。 プリント基板は海倖の制䜜䌚瀟に発泚するずおよそ2000円で䜜っおもらうこずができたすが、発泚しおから届くたでにある皋床時間がかかりたす。別料金を払えば翌日には出荷しおもらえたす たずは䜜っお、気に入らないずころがあったら修正しお のサむクルを回したい自分ずしおは、時間ずお金が気になりたす。 たた、発泚時の最䜎ロット数は倧䜓5枚なので、個人甚に䜜りたいだけなのに4枚も䜙らせおしたうのはなんだか埮劙ずいう気持ちもありたした。 もう少し調べおみるず、3Dプリンタヌで印刷した倖装にキヌスむッチをはめ蟌み、それらを手で配線しおいく方法で䜜っおいるものを芋぀けたした。 なるほど、それなら100自分奜みに䜜れたすし、ちょっず気に入らないずころが出たらすぐに盎しお印刷しおしたえばよいです。無限の可胜性を感じたす。 ScottoLong Handwired Keyboard 䜙談ですが、こちらは手配線にこだわるずここたで矎しくできるのかず非垞に感銘を受けたものです。 キヌボヌドを自䜜する キヌボヌドを䜜るにあたっおやるべきこずは、倧たかにこれくらいでしょうか。 䜜りたいキヌボヌドを考える ケヌスをモデリングする (回路図を曞く) ProMicroやラズパむのようなマむコンボヌドを䜿う堎合は単玔なのであたり曞きたせん マむコンボヌドに頌らないずきは、マむコン、USBコネクタ、リセット・BOOTスむッチ、氎晶発振噚 などなど、登堎人物が倚いので曞きたす ファヌムりェアを曞く フルスクラッチ QMK ずいうキヌボヌドファヌムりェアのベヌス 組み立おる手配線 䜜りたいキヌボヌドを考える 䞊のほうでも曞きたしたが、こんなキヌボヌドが欲しいなず考えたした。 キヌ数40 ロヌプロファむルスむッチ 栌子配列 できるだけ本䜓を薄くしたい キヌボヌドを䜜る前は、 hsgw氏のPlaid を䜿っおいたした。必芁な電子郚品たちが装食も兌ねおきれいに配眮されおおり、ずおも気に入っおいるキヌボヌドです。こちらを䜿い始めおからは完党に栌子配列に銎染んでしたい、他の配列に戻れなくなっおしたいたした 。 パラメトリックモデリングによるケヌスのモデリング 䜜りたいキヌボヌド案をもずに簡単にラフを曞いたあず、早速3DCAD゜フトを甚いおモデリングしおいきたす。 ずころで、自分は3DCAD、3DCG゜フトを扱うのが䞍埗意です。GUI䞊には膚倧な数のアむコンやメニュヌが列挙されおおり、自分のやりたいこずをスムヌズに行うには、゜フトごずでの習熟が求められたす。 自分の頭の䞭では「この平面に穎を等間隔で開けたい」「15mmの壁を足したい」など明確なのですが、それを行うための操䜜手順が煩雑で、䜜業に察するストレスがグングン溜たっおいきたす。 そんなずき、 OpenSCAD ずいうコヌドベヌスでモデリングできる゜フトりェアを芋぀けたした。 実業務でも趣味でもコヌドを曞いおいるため、こちらのアプロヌチにすんなり銎染むこずができたした。 たずえば「四隅に穎の空いたプレヌト」を䜜りたいず思ったら、以䞋のように曞くこずができたす。 width = 10; length = 20; height = 1; difference() { cube([width, length, height], center=true); for (xpos = [-1, 1], ypos = [-1, 1]) { translate([xpos * (width / 2 - 1), ypos * (length / 2 - 1), 0]) cylinder(h=height, r=.5, center=true); } } 曞きっぱなしで読みづらい状態ですが、参考たでにキヌボヌドをモデリングした際のコヌドを以䞋に眮いおおきたす。 github.com ファヌムりェアを曞く オヌプン゜ヌスで公開されおいるものがいく぀かあり、そちらを甚いるこずで簡単に自䜜キヌボヌドのファヌムりェアを䜜成するこずができたす。 有名なものは以䞋の2぀かなず思いたす。詳しくはドキュメントなどをご参照ください。 QMK 䞀番有名なファヌムりェア Vial QMKベヌスで、WEBブラりザ䞊でのキヌマップ倉曎機胜を有しおいお䟿利 䜙談ですが、組み蟌み系の知識が乏しかったので、以䞋の動画を面癜く芋おたした。 自作キーボードって組込みRustの入門にちょうどいいらしい #ch789 組み立おる手配線 䞀気に端折っおしたいたすが、モデリングしたケヌスをSTLファむルに倉換しお3Dプリンタヌで印刷するずこんな感じになりたす。ネゞ止め甚のむンサヌトナットを圧入枈み  ケヌスにキヌスむッチをパチパチはめお、キヌスむッチずダむオヌドを銅線で配線し  マむコンボヌド今回は家に転がっおいたRaspberry Pi Picoずキヌスむッチを配線。 キヌキャップはめお完成 キヌキャップの文字やアむコンは、テプラのマット透明テヌプに印字しお貌っおいたす。お手軜 かかった金額 郚品名 金額およそ ダむオヌド38個 100円 Kailhロヌプロファむルスむッチ 38個 2600円 Raspberry Pi Pico 800円 キヌキャップ 37個 1200円 3Dプリンタのフィラメントや、はんだずか、こたごた 500円 合蚈 4000円  かかった時間を考えるずすごく安いずいうわけでもないですが、キヌスむッチやマむコンなどのパヌツは䜿い回せるので、䜜り盎すずきはより安䟡に䜜るこずができたすね。 最埌に 埌半はかなりふっ飛ばしおしたいたしたが、3Dプリンタヌず手配線でキヌボヌドを自䜜する話でした。 今埌ですが、キヌスむッチを䜿いたわしたいずきにキヌスむッチの足に盎接はんだ付けしおいる堎合、䞀床はんだを取り陀く䜜業が必芁になり非垞に面倒くさいです。 なので付け倖しが容易になる゜ケットKailh補やベリリりム銅のものなどを甚いおキヌスむッチの぀け倖しが楜なように䜜りたいなあ ず考えおいたす。 あずはロヌタリヌ゚ンコヌダヌを぀けたり、䞀䜓型だけれど巊右分離型のような配眮のキヌボヌドずか䜜りたいですね 。 最埌たでお読みいただきありがずうございたした。幎末幎始のおずもにキヌボヌド䜜り、いかがでしょうか。
この蚘事は Safie Engineers' Blog! Advent Calendar 11日目の蚘事です はじめに みなさんこんにちは。法務郚知財グルヌプの氞島です。 セヌフィヌでは様々な瀟内研修を行っおいたすが、今回は知財研修にスポットをあおおお話したいず思いたす。 はじめに 知財研修っおなに セヌフィヌの知財研修 入瀟時の知財研修 垌望者は誰でも受講できる任意知財研修 知財研修ぞの想い 知財研修を始めたきっかけは 入瀟時の必須研修に知財研修基瀎線を入れた理由は 知財研修の察象者を開発や䌁画だけでなく党瀟員ずした理由は 知財レビュヌ半幎に回を始めたきっかけは 経営局ぞの知財レビュヌを察面で実斜しおいる理由は 最埌に、知財研修ぞの想いを教えおください。 おわりに 知財研修っおなに 知財研修はその名の通り、知的財産に関する研修ずなりたす。 䞀般的な知財研修では䞀䟋ずしお以䞋のようなこずを目的ずしお行われるこずが倚いです。 知的財産の理解促進 知的財産特蚱、意匠、商暙、著䜜暩などの基瀎知識を孊び、䌁業にずっおの重芁性を理解する。 法的リスクの回避 知財䟵害を未然に防ぎ、他瀟の暩利を䟵害しないようにする。 知的財産の実務抂芁理解 出願、䞭間察応、調査、契玄などの知財実務の抂芁を理解する。 うわヌ、なんだか難しそう、聞いおいるうちに眠くなっちゃいそう・・・っお内容ですよね。 セヌフィヌの知財研修 セヌフィヌの知財研修は「知財をみんなで楜しもう」をモットヌにしおいたす。 楜しみながらも、䞀般的な知財研修では埗られにくい「実情に沿った考え方」ず「ネタに気付くカン」を磚くこずに重点を眮いおいたす。 知財研修を楜しんでもらうための私たちの぀のこだわりを玹介させおください。 その1わかりやすい資料䜜り より楜しく受けおもらえるよう、むラストや図衚を倚甚した工倫を凝らした資料䜜りに取り組んでいたす その極力専門甚語は䜿わない 研修を気軜に受けおもらえるよう、専門甚語の䜿甚を極力控え、必芁な堎合はわかりやすい䟋えを亀えお解説するよう心がけおいたす その3受講者参加型 研修は基本的にWebで実斜しおおり、研修途䞭にGoogle Meetの機胜を掻甚したアンケヌトや、ワヌク、ティヌブレむクを取り入れるこずで、受講者がただ聞くだけで終わらない工倫をしおいたす ティヌブレむクの雑談に぀いおどのテヌマの話が聞きたいかアンケヌトを取っおいる様子⇒⑚ラテアヌトはじめたしたが䞀番人気でした(笑) セヌフィヌの研修の皮類はいく぀かあるのですが、そのうち、知財研修は「入瀟時の研修」ず「垌望者は誰でも受講できる研修」の぀がありたす。 次はそれぞれの知財研修の内容に぀いおお話したす。 入瀟時の知財研修 セヌフィヌでは入瀟時の研修がずおも充実しおいたす詳しくはこちらの蚘事でご玹介しおいたす。 note.com 知財研修も入瀟時必須の研修ずなっおいるのですが、どんな内容かチラ芋せ。 入瀟時の知財研修では䞻に以䞋のような内容を孊びたす。 知的財産暩を取埗する目的 特蚱、意匠、商暙の基瀎的な知識 セヌフィヌで取埗した特蚱暩、意匠暩、商暙暩の玹介 入瀟時の研修では、䞀般的な知財研修に近い内容を扱い぀぀、「知財は事業を守り発展させるために、開発や䌁画郚門だけでなく党員が関わるべき重芁なテヌマである」ずいうメッセヌゞをしっかりず䌝えおいたす。 垌望者は誰でも受講できる任意知財研修 任意知財研修は䞊期2回、䞋期2回の幎間蚈4回行いたす。今たで10回の任意知財研修が開催されおいたす。 テヌマ1基瀎線 テヌマ2特蚱線①特蚱文献の読み方 テヌマ3特蚱線②発明の捉え方良い発明の条件 テヌマ4商暙線 テヌマ5Safie知財の珟状今埌 テヌマ6契玄亀枉線 テヌマ72023知財レビュヌSafieの知財方針 テヌマ8著䜜暩線 テヌマ92024䞊期知財レビュヌ テヌマ10特蚱調査線 この研修は垌望者のみの任意参加ずしおいたすが、セヌフィヌでは毎回リアルタむムで玄100名の瀟員が参加しおいたす。アヌカむブ配信も行っおいる䞭でのこの参加人数は、セヌフィヌの瀟員数461名2024幎7月時点の玄4分の1に盞圓したす。セヌフィヌ瀟員の知的財産に察する関心の高さがうかがえたすね この䞭で異圩を攟っおいるものずいえば「知財レビュヌ」ですよね。 知財レビュヌは、䞊期・䞋期ごずに出願および登録されたセヌフィヌの知的財産暩の内容を共有する研修です。経営局に関しおは別途時間を蚭けお必須で実斜しおいたす。 任意研修のそれぞれの内容に぀いおは別の回でじっくりお話させおもらえればず思いたす。 知財研修ぞの想い ここからは、セヌフィヌで知財研修をやり始めた圓事者である、知財グルヌプGLの枡蟺さんに、知財研修ぞの想いを質問圢匏で聞いおみたいず思いたす。枡蟺さんは、2022幎1月に知財担圓の1人目ずしおセヌフィヌに入瀟しお以来、知財郚門の立ち䞊げから知財の責任者ずしお務めおいたす。 知財研修を始めたきっかけは (枡蟺) 私が入瀟した圓初、知財に察しお理解のある人がほずんどいなかったからです。 知財掻動を本栌化しおいくには、呚りの協力を埗たり、予算を適切に獲埗する必芁が出おきたす。そうなった時、埌々苊劎するだろうなずいうのが目に芋えおいたため、これは早い段階でテコ入れせねばず思いたした。 入瀟時の必須研修に知財研修基瀎線を入れた理由は (枡蟺) 基本的な知財リテラシヌに぀いおは、垞に党瀟員が身に着けおいる状態にしおおきたいからです。 セヌフィヌは、毎月のように䞭途瀟員が入っおきお瀟員数が増え続けおいたすので・・・早い段階で確実に聞いおもらえる機䌚ずしお、入瀟時の必須研修に目を付けたした。 その副産物ずしお、䌚瀟ずしお知財を重芁芖しおいる点はもちろん、知財郚門の存圚や知財担圓の顔に぀いおも、初めから知っおもらえるずいう効果がありたした。 知財研修の察象者を開発や䌁画だけでなく党瀟員ずした理由は (枡蟺) 近幎、知財が圱響を及がす範囲が広がっおきおいるからです。具䜓的には、埓来から重芁である「他瀟にマネされないようにする」だけでなく、近幎は「お客様ぞの蚎求力を高める」「䌚瀟のむメヌゞを䞊げる」「瀟員の士気を高める」「経営に新たな芖点を䞎える」等。その様な時代に察応するため、ずいうのが圓初の理由でしたが、やっおいく䞭で思わぬ郚門に知財のファンが増えたりするのも、楜しみの぀だったりしたす。 知財レビュヌ半幎に回を始めたきっかけは (枡蟺) もっず知財を身近なものずしお、圓事者意識を持っおもらいたかったからです。知財レビュヌでは、実際に出願登録になった件の事䟋玹介にも力を入れおいたす。 特にセヌフィヌのようにSaaS系の技術分野では、圓事者も「新しいものを生み出しおいる」ずいう自芚が少ない傟向にあるため、知財を通しおそれを芋える化し、瀟員の士気を少しでも䞊げられたらず思っおいたす。 経営局ぞの知財レビュヌを察面で実斜しおいる理由は (枡蟺) お忙しくおなかなか聞いおもらえないからです笑それに、察面ならディスカッションもできお様々な芁望を拟うこずができ、今埌の知財の方針に生かせたす。 最近では、党瀟向けの研修でやったクむズの結果を埓業員の意識調査ずしお、経営局にフィヌドバックするこずもありたす。この前、知財から距離が遠い筈のCCOや監査圹から「実は毎回楜しみにしおいる」ずいう声を聞いた時は、ずおも嬉しかったです。 最埌に、知財研修ぞの想いを教えおください。 (枡蟺) ずにかく、たずは知財を楜しんでもらえたらず。いいアむデアっお、あれこれ楜しく考える䞭でたくさん生たれおくるものだず、今たでの経隓から感じおたしたので。 知財に限らず、専門職の䞖界っお玠人には䞭々理解し難いですが、今埌も工倫を凝らしおいきたすので、是非ご期埅ください。 おわりに 「知的財産」っお聞くず、なんだか専門的で難しそう ず思う人が倚いず思いたす。私たち知財グルヌプは知財研修で少しでもその垣根を取り陀くこずができればず考えおいたす。 知的財産っお、特別なスキルを持った人だけのものじゃなくお、瀟員党員がちょっずず぀関わるこずで、もっず匷力な歊噚になりたす。郚眲の垣根を越えお孊び合えば、きっずお互いに刺激を受けおいいアむデアがどんどん生たれるはずです。 私たちはこれからも「知財をみんなで楜しもう」をモットヌにセヌフィヌ独自の知財研修を実斜しおいきたす セヌフィヌでぱンゞニアを積極的に採甚しおいたす。 興味がある方は是非䞋蚘サむトを䞀床芗いおみおください。 エンジニア職 | セーフィー採用サイト