Upgrade to Pro — share decks privately, control downloads, hide ads and more …

アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介

アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介

小島 夏海 @replu5
2025 年 6 月 18 日
golang.tokyo #39

アンドパッドの社内勉強会の一つ "gopher 会" では技術顧問の tenntenn さんを招き、 Go に対しても知見を深めています。今回は gopher 会をどのように運営しているかや、そこで得られた知見を紹介します。

Avatar for ANDPAD inc

ANDPAD inc

June 18, 2025
Tweet

More Decks by ANDPAD inc

Other Decks in Programming

Transcript

  1. © 2024 ANDPAD All Rights Reserved. 2 自己紹介 小島 夏海

    (こじま なつみ) : replu : replu5 geminiに読みを聞いたら「リプル」 • 2021 年にアンドパッド入社 • Go Conference 2023/2024で登壇 • 「gopher」会の運営 • ポケモン Go/読書/🍺/☕ 2023年の発表 2024年の発表
  2. © 2024 ANDPAD All Rights Reserved. Confidential ANDPADとは 社内 現場

    営業 / 監督 / 設計 事務 / 管理職 職人 / 業者 メーカー / 流通 現場の効率化から経営改善まで一元管理できる クラウド型建設プロジェクト管理サービス 案件管理 資料 工程表 写真 報告 チャット 黒板 図面 受発注 • • • 
 
 3
  3. © 2024 ANDPAD All Rights Reserved. Confidential Go を間接的に使っているプロダクト ANDPAD

    の Go のプロダクト Go がメインのプロダクト 施工管理 引合粗利管理 受発注 検査 図面 黒板 ボード 資料承認 おうちノート … 4 請求管理 リモート通話
  4. © 2024 ANDPAD All Rights Reserved. 6 gopher会とは 当初は「プログラミング言語Go完全入門」の静的解析とコード生成[1]につ いて説明してもらいながら問題を解いていた

    現在はproposal: review meeting minutes[2] 眺めるのを中心にしつつ、go に関連する話題について雑談する会になっている [1] https://docs.google.com/presentation/d/1I4pHnzV2dFOMbRcpA-XD0TaLcX6PBKpls6WxGHoMjOg [2] https://github.com/golang/go/issues/33502
  5. © 2024 ANDPAD All Rights Reserved. 最近の話題 7 • range

    over funcのハンズオン開催 ◦ tenntenn Conference 2024で実際されていたものを社内でも開催 • 新しいエラーハンドリングについてわいわい ◦ 「discussion: spec: reduce error handling boilerplate using ?」についてみんなで 眺めながらわいわい • gRPC Streamのテストどうしよう ◦ gRPC Streamのテスト書いたことないけどいいサンプルないかな • Context に何入れよう ◦ t.OutputがAccept[1]された話からcontextに入れたい情報と入れたくない情報の話に ついてわいわい • t.Fatalとt.Errorの違い ◦ testと別のgoroutineでt.Fatal使うとおかしくなる ◦ t.Fatalはruntime#Goexitが呼ばれるmainのgoroutineじゃなくなる [1] https://github.com/golang/go/issues/59928
  6. © 2024 ANDPAD All Rights Reserved. 最近の話題 8 • API以外の用途でk8s上にデプロイしたPodのヘルスチェックをどうするか

    ◦ ヘルスチェック用のエンドポイントを準備するのがお手軽 • CACHEPROG ◦ 結局使い時はいつなのか ▪ この時は結論でなかった ▪ ビルドよりもテストで時間かかってる • https://pkg.go.dev/golang.org/x/[email protected]/cover を使って変更したいとこだけにテスト絞るとよさそう • 開発時だけ使用するツールの管理のベストプラクティス ◦ tool ディレクティブがでたよ ◦ golangci-lintはgo get非推奨だからどうするのがいいか • go の smtpのリクエストにタイムアウトを設定したい ◦ net/smtpのpkgはフリーズされている #36209[1] ◦ 利用しているサービスにHTTPのエンドポイントがあるならそちらにしたほうがよさげ [1] https://github.com/golang/go/issues/36209
  7. © 2024 ANDPAD All Rights Reserved. 最近の話題 • 「A Tour

    of Go」の次に何を見ればいいのかわからない 9
  8. © 2024 ANDPAD All Rights Reserved. 最近の話題 10 • Connect

    Serverでtyped nilが返ってくる ◦ 簡単にいうと値は空だが、型情報をもっているnilに対して if value == nil が trueに ならない ◦ 基本的にtyped nilは避けるようにするのがいい ◦ issue[1]あげたが、if err != nil と先にエラー確認すれば問題ないので対応しないという 結論でドキュメントに追記する方針 [1] https://github.com/connectrpc/connect-go/issues/827
  9. © 2024 ANDPAD All Rights Reserved. 11 package main import

    "fmt" type ( myInterface interface { f() } myType struct{} ) func (m *myType) f() {} func f() myInterface { var v *myType return v } func main() { v := f() if v == nil { fmt.Println("v is nil") } fmt.Printf("v value is: %v\n", v) } >> go run ./main.go v value is: <nil> typed nilの例
  10. © 2024 ANDPAD All Rights Reserved. 問題になった実装 12 connect serverのインターセプター

    func sampleInterceptor() connect.UnaryInterceptorFunc { return func(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { res, err := next(ctx, req) if res != nil { res.Header().Add("example", "example") } return res, err } } }
  11. © 2024 ANDPAD All Rights Reserved. 問題になった実装 13 connect serverのインターセプター

    func sampleInterceptor() connect.UnaryInterceptorFunc { return func(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { res, err := next(ctx, req) if res != nil { res.Header().Add("example", "example") <- ここでresがnilのためpanicになる } return res, err } } }
  12. © 2024 ANDPAD All Rights Reserved. 実際はどうなっているのか 15 untyped :=

    UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) { if err := ctx.Err(); err != nil { return nil, err } typed, ok := request.(*Request[Req]) if !ok { return nil, errorf(CodeInternal, "unexpected handler request type %T", request) } res, err := unary(ctx, typed) if res == nil && err == nil { // This is going to panic during serialization. Debugging is much easier // if we panic here instead, so we can include the procedure name. panic(procedure + " returned nil *connect.Response and nil error") //nolint: forbidigo } return res, err })
  13. © 2024 ANDPAD All Rights Reserved. 実際はどうなっているのか 16 untyped :=

    UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) { if err := ctx.Err(); err != nil { return nil, err } typed, ok := request.(*Request[Req]) if !ok { return nil, errorf(CodeInternal, "unexpected handler request type %T", request) } res, err := unary(ctx, typed) <- ここでtyped nilが返ってくることがあり if res == nil && err == nil { // This is going to panic during serialization. Debugging is much easier // if we panic here instead, so we can include the procedure name. panic(procedure + " returned nil *connect.Response and nil error") //nolint: forbidigo } return res, err <-ここで戻り値をそのまま返すので typed nilを返すことがある })
  14. © 2024 ANDPAD All Rights Reserved. 実際はどうなっているのか 17 untyped :=

    UnaryFunc(func(ctx context.Context, request AnyRequest) (AnyResponse, error) { if err := ctx.Err(); err != nil { return nil, err } typed, ok := request.(*Request[Req]) if !ok { return nil, errorf(CodeInternal, "unexpected handler request type %T", request) } res, err := unary(ctx, typed) if res == nil && err == nil { // This is going to panic during serialization. Debugging is much easier // if we panic here instead, so we can include the procedure name. panic(procedure + " returned nil *connect.Response and nil error") //nolint: forbidigo }  if err != nil { return nil, err } return res, nil })
  15. © 2024 ANDPAD All Rights Reserved. 4年間開催して 18 • 目的は特に定めていないが無くてはない会になっている

    ◦ Goについて困ったらここで聞けばいいという場の提供 ◦ 事前準備が必要ないので継続しやすい ◦ メンバーは流動的だがコアメンバー的な人が自然と生まれ上手く回っている ▪ コアメンバーも特に何かをしているわけではない • 最先端のことを喋っているので知らない間に詳しくなっている ◦ さらに深掘りするきっかけになっている ◦ Go Conference の採択率が高いプロポーザルがかけている ▪ 4/4で通ってる