giftee Tech Blog

ギフティの開発を支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信しています。

Go Conference 2024 セッションレポート『試してわかるGo ModulesとMinimal Version Selection』

こんにちは、ギフティでエンジニアをやっている中屋(@nakaryo79)です!

2024年6月8日に渋谷の Abema Towers で開催された Go Conference 2024 に参加してきました! 今年は久しぶりのオフライン開催だったのですが、400人もの Gopher が会場に集まった様子は壮観でした。

この記事ではのびしーさんによる『試してわかるGo ModulesとMinimal Version Selection』を聞いた感想と自分が調べたことを書きたいと思います。

セッション『試してわかるGo ModulesとMinimal Version Selection』の感想

発表のお題目は以下で、Go Modules がどのように依存ライブラリ(モジュール)のバージョンを決定しているか、が主なテーマとなっていました。

  • SemVer(Semantic Versioning)のおさらい
  • 試してわかるMinimal Version Selection
  • おまけ: go.sumはlockファイルではない

そもそも Go Modules ってなんなのという話ですが、Go の依存関係を管理してくれる機構で、これは Go の公式が詳細なドキュメントを出してくれています(めっちゃ長い)。

https://go.dev/ref/mod

Go Modules の機構が入ったのは Go1.11 からで、Go1.13 から実質デフォルトになりました。 自分が Go を触り始めた時期はちょうど Go Modules への移行の過渡期で、当初はローカルに GOPATH を設定して、dep ensure するなどしていた記憶があります。 今では、Go で開発するなら当然のように Go Modules を使うことになるわけですが、go installgo mod コマンドが必要な依存を自動でいい感じにインポートしてくれるので、インポートするモジュールバージョンをどのように決めているかについてちゃんと調べたことがありませんでした。

Minimal Version Selection(MVS)

セッションではセマンティックバージョニングについて簡単におさらいした後、3つの例題を見ながら依存関係管理の仕組みを説明してくれました。

Go のビルドシステムでは使用するモジュールのバージョンを決定するのに、Minimal Version Selection(MVS)というアルゴリズムを使用しているそうです。これは指定されているバージョンの中で最小のバージョンを使うというものです。例えば、とあるモジュールに対して v1.1 が指定されている場合、そのモジュールの最新バージョンが v1.4 であっても、一番低い v1.1 が使われます。常に一番低いバージョンが選択されるため、lock ファイルが不要で、かつアルゴリズムもシンプルになるらしいです。一方で、要求するまではバージョンが上がらないということは、新しいバージョンがリリースされていてもその使用がされないということで、セキュリティパッチなどの恩恵を受けるのが遅れるリスクもあります。

MVS とは逆に、Maximal Version Selection(MaVS)というアルゴリズムもあります。Ruby の bundler や npm などはこの考え方に基づいており、指定されている中で最新のバージョンをインポートしようとします(バージョンを固定指定されている場合は除く)。

さて、3つの例題の一つ目ですが、

MVS に則って、この挙動はすんなり理解できます。

例題の二つ目も、まあそうだよねという感じです。

ただ、例題の3つ目は思っていた挙動と異なりました。

c1.4への依存が外れたので、c1.1に戻すのかと思っていたら、どうやらc1.4に依存したままになるらしいです。 セッション中では、前回ビルドした状態となるべく近い状態でビルドする、と説明されていました。そういうもんなのかーと思いましたが、ビルドキャッシュなどの問題からそのようにしているということでしょうか。

ちなみに、この例題のモジュールセットは Go Team の一員である Russ Cox のブログから引用されているようです。こちらのブログでは当時のアルゴリズムの問題点と、ビルドの再現可能性の高さ(Russ Cox はそれを High-Fidelity Builds と呼んでいる)の重要性について詳しく説明しています。go.devにはそれをサマリしたような記述もあります。こちらには Downgrade や Exclude など普段の開発であまり使わない機能も載っていて、勉強になりました。

終わりに

本記事はセッションレポートという形になりましたが、Go Conference の全体的な感想としては、どのセッションも実に聞きごたえがあり、企業ブースでのお話も楽しく、とても良い経験になったと思います。中にはあるあるな話だったり、今まさに自分が業務で直面しているのと同じ課題感について話している人もいて、やっぱそこみんな悩むよねえ〜という勝手な共感を感じたりもしていました。

プロダクトの開発に集中していると、(業務的に)Go の内部実装まで踏み込んで見てみることはそう多くはありません。しかし、セッションを聞いて、そのサイドエフェクトで色々と調べるきっかけになるというのも勉強会やカンファレンスのいいところです。

自分は Go という言語が好きです。より Go について研鑽し、コミュニティにより多くを還元できるよう頑張りたいなと改めて思いました。

We Are Hiring!