
なお、当社は同カンファレンスの会場スポンサーを務め、AbemaTowersにて参加者の皆さまをお迎えします。
登壇について
岩見彰太 / 15:50-16:10 (ROOM B)
・セッションタイトル
「Unified Diff 形式の差分から Go AST を構築して feature flag を自動計装する」
・概要
開発スピードの高速化とデプロイまでの時間短縮を可能にするトランクベース開発では、main branch を常に Production リリース可能な状態に保つ必要があります。開発段階であるがゆえに Production への反映を避けたい場合や、修正内容を Staging 環境で QAテストすることが必要な場合は、feature flag を用いた実装が必要です。feature flag とは、コードを変更せずにシステムの振る舞いを変更可能にする仕組みであり、主に環境変数やステータスを管理する外部サービスを通じて有効/無効を切り替えることができます。具体的には、flagの値に応じた分岐をあらかじめ実装することで、外部から入力されたfeature flagの値によってシステムの振る舞いを変えることができるようにします。
トランクベース開発での迅速な開発進行と同時にシステム品質を保証するためには、細かなQAプロセスが不可欠です。CIによるシステム的なチェックは必須ですが、それに加えて Staging 環境での QA も同様に非常に重要になってきます。これを実現するためには、適宜 feature flag を組み込んだ実装が必要になります。しかし feature flag の実装はコードを複雑化させるため、トランクベース開発においては長期間にわたる存在や同時に多数存在することは推奨されていません。したがって、QA で品質を保証しつつコードの複雑化を最小限に抑えるには、feature flag の迅速な組み込みと削除が必要です。しかし QA の品質を高めるためには頻繁に feature flag を組み込む必要があり、管理コストが増大するという課題があります。
この課題を解決するために、git diff で出力される Unified Diff 形式の差分情報から Go の抽象構文木(以下、AST) を構築し、AST の差分を利用して feature flag の自動計装を試みました。本セッションでは uber-go のリファクタリングツールである「gopatch」の内部実装を参考に、Unified Diffから有効なGoコードへの変換とASTの構築プロセスを通じて、適切なfeature flagの自動挿入方法を紹介します。参加者はこのセッションを通じて、Unified Diffを活用したツール作成のアイデアやfeature flagの効果的な活用方法を学ぶことができます。さらに、自動計装ツールの開発にこの知見を応用することが可能になります。
-----------------------------------------------------------------------
・登壇者
唐木稜生 / 16:50-17:10 (ROOM B)
・セッションタイトル
「詳解 "Fixing For Loops in Go 1.22" / 自作linterをgolangci-lintへコントリビュートした話」
・概要
Go1.22から(プレビューはGo1.21から)ループ変数のメモリ共有問題が解消されたことは皆様よくご存知かと思います。 cf. Fixing For Loops in Go 1.22
それではもう1歩踏み込んで、ループ変数に新しいメモリが割り当てられるのはどのような時なのでしょうか?以下2つの出力が異なる理由をどう説明できるでしょうか?
for i := range 3 { fmt.Print(&i) // [0x14000112018, 0x14000112030, 0x14000112038] // 異なるアドレス }
for i := range 3 { print(&i) // [0x1400010af18, 0x1400010af18, 0x1400010af18] // 同じアドレス }
新しいループとそれを取り巻くツールの実装は、既存コードでバグを生み出さない・パフォーマンスを落とさない工夫がされています。
本セッションでは、loopvarパッケージのコードリーディングを通して、これら変更の背後にある内部動作を解説します。 さらに、デザインドキュメントやコミュニティでの議論はもちろん、周辺ツールやアセンブリベースでの挙動変更なども併せて確認することで、ループ変数への理解をより深めたいと思います。
また、Go1.22から不要になったループ変数のコピーを検出する自作linter copyloopvar をgolangci-lintにコントリビュートした話もお伝えします。 このlinterが何をどのように検知するかを紹介する中で、Goにおける静的解析ツールの作成方法も解説します。 linterの自作やOSS貢献に一歩踏み出す際、本セッションがご参考になれば幸いです。
-----------------------------------------------------------------------
・登壇者
黒田尚輝 / 19:05-19:10 (ROOM A)
・セッションタイトル
「deadcode超解剖」
・概要
2023年末にGo公式が「Finding unreachable functions with deadcode」( https://go.dev/blog/deadcode )というブログを通して、使用されていない関数を見つけ出すためのdeadcodeというツールを紹介しました。
このブログでdeadcodeが紹介されたことをきっかけに、複数のlinterを同時に設定することができるツールであるgolangci-lint( https://github.com/golangci/golangci-lint )に対して、Go公式のものであるdeadcodeを採用するのはどうかというissueが複数挙げられました。
しかし、golangci-lintはこのdeadcodeを採用せず、代わりにunusedという類似の機能を持つlinterと比較してこの提案を棄却しました。その理由と2つのlinterの違いについて深ぼることで、それぞれのlinterの特徴と使い分けが理解できると思っています。
また、私自身deadcodeを使用し、あるOSSのコードをリファクタリングするPRを送りました。ただ、そのPRが不要なリファクタリングという指摘を受け、deadcodeで検知して削除するべきではないinterfaceの中のメソッドの役割を学びました。
そこで、その経験を通して、現段階のdeadcodeを使う際の注意点についてもお伝えしたいと思っています。
具体的にはこのセッションで以下の項目についてお話しします。
1. deadcodeの概要と内部の仕組み
2. golangci-lintのissueを通したdeadcodeとunusedの比較
3. 現段階でdeadcodeを使用する際の注意
このセッションは、Goで使用されていない関数をlintしたい方や、Goのlint自体に興味がある方に対して特にお話ししたい内容です。