GoConference2019Spring参加記

5/18(土)に東京で開催されたGoConferenceというイベントに、メルカリさんのスカラーシップで参加させて頂きました!

gocon.jp

このイベントは1年に2回東京で開催されており、メルカリさんをはじめとする有志企業によって運営されているそうです。400人を超える参加者を抱えながら参加費を無料に抑えて開催してくださっているというのはすごいことで、本当にスポンサーさんに感謝するばかりです。

tech.mercari.com

今回はメルカリさんのスカラーシッププログラムに申し込ませて頂き、交通費・宿泊費の補助だけでなく、イベント前日にはGoogle本社からのGoTeamの方々も交えたランチ、オフィスツアーや社内勉強会への参加まで提供頂きました。本当に盛りだくさんの内容で良い経験になりました。

Sessions

早速ですが、特に興味を持ったセッションについていくつかご紹介したいと思います。

Keynote

Keynote(オープニングトーク的なやつ)はGoTeamのKatie HockmanさんによるGoProxyに関する話題でした。go getした時に実はソースコード取ってくるのではなく、GoogleProxyサーバーを挟んで色々やってくれているというお話です。

Julieさんも一緒に来て頂いていたGoTeamの一人です。

Modules

go modで生成したgo.modとgo.sumをレポジトリにおいておくと、go get時に関連モジュールを(依存関係を解消する形で)勝手に取ってきてくれるというもの。例えば別の依存パッケージが同じパッケージの別バージョンを参照している場合でも、それらを全て満たすバージョンのものを取ってきてくれるようです。

Mirrors

参照先のソースコードは消えてたり変更される可能性があるので、Proxyサーバーを挟んで1つのパッケージのあるバージョンのソースコードが同一であることを保証しているという内容。具体的にgo getの挙動は次のようになるみたいです。

  1. 対象パッケージの存在するバージョン一覧を取得
  2. 最新のバージョンのソースコードとその情報を取得
  3. go.modを取得して依存先のライブラリを再帰的に取得
  4. 全体のコードをzipとして取得

Checksum Database

取得したソースコードの正当性(第三者によって改竄されていないこと)を保証するためにチェックサムを照合するが、その照合先のチェックサムを1つのデータベースで管理しているという内容です。

www.certificate-transparency.org

上の通りGoの照合システムではマークルツリーという二分木構造を導入しており、それぞれの親ノードのハッシュ値を子ノードのハッシュ値から計算するようにすることで、全体の整合性を保ちながら大量のチェックサムを管理します。GoProxyでは"Trust on One's Use"という考え方に基づき、データベースにレコードがない場合は最初のリクエスト時のハッシュ値を信用してデータベースに保存します。

エラー設計について/Designing Errors

docs.google.com

メルカリの@morikuniさんによるエラー処理の設計に関するトーク。ベストプラクティスだけでなく、そこに行き着くまでのエラー処理そのものの根本的な考え方にも触れられていてすごく参考になりました。

未知のエラーを既知とするための方法がエラーハンドリングである

エラーとは、アプリケーションの実行時に起こる想定外の事態です。そのような未知のエラーを明示的にハンドリングし、自分のアプリケーションの一部として取り込むことがエラーハンドリングだという考え方です。

複数の関係者がエラーにそれぞれ異なる情報を求めている

一口にエラーと言っても処理の階層・エラーを表示する対象によって必要な情報は異なり、それぞれの相手に必要十分な情報を提供できるようにエラーを管理しなければいけないということです。

僕自身もWebAPIをGoで書くにあたりエラー処理が一番の悩みの種で、なかなかこれといった方法論を確立できておらず、それが今回の参加の理由の一つでもありました。特に

「階層的なアーキテクチャを採用している場合レイヤーによってエラーの粒度が異なるが、レイヤーごとに別々のエラーを定義して順次変換していった方がいいのか、同じエラーをレイヤー間で共有してしまっていいのか」

ということについて悩んでいたのですが、今回の「同じエラーでも相手によって提供すべきエラーが異なる」という前提の元では、できるだけ大まかなエラーのみをアプリケーション全体で定義して、詳細やレイヤーごとのメッセージ・情報はレイヤーごとに付加していくのが最善なのかなと思いました。

紹介して頂いたfailure/xerrorsライブラリと合わせて近いうちにリファクタリングしてみたいと思います。

Design considerations for Container based Go application

speakerdeck.com

@hgsgtkさんによる、コンテナアプリケーションをGoで構築するときに考慮すべき事項をまとめたセッションです。こちらも具体的な実装に至るまでの思考過程が整理されており、

という流れが明確でわかりやすく、コンテナアプリケーションに限らず多くの場面で使える考え方であると思いました。

また技術面では

  • テストのしやすさも考慮した環境変数の扱い方
  • ロガーを抽象化してイベントストリームとして扱う
  • ヘルスチェック用のエンドポイントは、API自体だけでなく依存先のサービスのヘルスチェックも行う

などすぐに実践できるテクニックが盛り込まれていたのがとても参考になりました。

CPU, Memory and Go

speakerdeck.com

@sonatardさんによるトーク。GoのCPU・メモリ周りの話から始まり、Goの軽量さの理由や効率的なメモリ管理について紹介して頂きました。

  • appendはスライスのサイズが不足しているときに追加のタイミングでメモリを確保する。ヒープのメモリ確保はとても遅いので、あらかじめサイズがわかっている時は初期化時にまとめて確保する方が望ましい。メモリの空間局所性の観点からも、まとめて確保した方がキャッシュのヒット率が上がるので高速化が期待できる。
  • Escape Analysis: 関数内の変数はスタック領域に確保されるが、関数を抜けるときに必要な変数(他のスコープに渡したポインタなど)はヒープ領域に移される。
  • 変数はメモリアラインメント (64bit/8byte)の単位に沿って確保され、アラインメントを跨ぐような変数確保が発生する場合はパディングにより次のアラインメントに書き込まれる

などのGoの言語仕様を知りました。特に普段何気なく使っている構造体のポインタ渡しなど、メモリ管理など細かい内部処理がうまく隠蔽されており、ユーザーが細かい部分を気にせずとも処理系が自動的に最適化・高速化してくれる使い勝手の良さにGoの人気の一因を垣間見た気がしました。

感想

今回のGoConferenceでは自分の知らない様々な技術を知ることができました。

  • go modによる依存関係・チェックサム管理
  • Builder PatternとFunctional Optional Pattern
  • failure/xerrorsによるエラーハンドリング
  • pprofでのプロファイリング・パフォーマンス解析
  • APIの実装を簡単にするimpl/wire/gotests/fillstructといったパッケージ

同時に自分の知識のなさを痛感し、これから一層頑張って勉強していかないといけないという大きな刺激になりました。学んだことを書き残すだけでなく、今後自分のコードのリファクタリングを通して実践していければと思っています。

おまけ:前日・当日の様子

前日はまずメルカリの社員さん(@tenntennさん、@codehexさん)、Google@ymotongpooさん、さらにGoogleの本社からのGoTeamからの3人とご一緒させて頂きました。会話は全て英語で、Go2(Generics/Contract)やエラー処理のノウハウについて、色々質問させて頂きました。英語力不足で踏み込んだ話がなかなかできなかったのが残念なところです...ちなみにGoTeamで多く使われているエディタはVSCodeVimだそうです。

その後はオフィスツアーと社内勉強会に案内して頂きました。社内勉強会は何か1つのトピックについて話すというよりはそれぞれが持ち寄った話題を共有するという雰囲気でした。今回はスカラーシップ生の質問を中心に色々教えて頂きました。ちなみにメルカリのGoTeamで多く使われているエディタはGoLandとVim、ついで VSCodeやPlayground(嘘です)だそうです。

f:id:ey_nosukeru:20190521151355j:plain:w400
メルカリのオフィス玄関

当日はリクルートさんのオフィス(グラン東京サウスタワー)が会場でした。きれい・広い・眺めがいいと素晴らしい会場でした。

スポンサーさんによるフリースペースもあり、Gopherくん特製カップのコーヒも提供して頂けました。

f:id:ey_nosukeru:20190520113420j:plain:w450
各スポンサーさんのグッズが置かれたフリースペース

f:id:ey_nosukeru:20190520113804j:plain:w450
Gopherくん特製カップ

f:id:ey_nosukeru:20190521151746j:plain:w450
突如始まるGo Quiz

f:id:ey_nosukeru:20190521151904j:plain:w450
懇親会の様子。DeNAさんに提供して頂いたビールがとても飲みやすかったです

参加記は以上になります。最後までお読み頂きありがとうございました!