はじめに
現在、GoとgRPCを扱っている案件に参画しています。
そこでgRPCを更新し、取り込んで実装を進めて、Goでテストを走らせた時に、題名のエラーに遭遇しました。
解決までに少し時間がかかったため、同じような状態になっている方のお役に立てればと思います!
結論
環境変数に、GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
を追記して、エラーを回避した形になります。
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
何が起こったのか?
テストを走らせた時に、以下のエラーが発生しました。
panic: proto: file "〇〇.proto" is already registered
previously from: "github.com/△△/△△"
currently from: "github.com/□□/□□"
See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
〇〇などには、ファイル名やリポジトリ名が入っています。
今回の実装では、gRPCは別リポジトリで実装しており、それをGo側のリポジトリにrequireで取り込んでいる形となっています。
原因の特定
エラー文を見てみると、〇〇.proto
が既に登録されているとあります。
previously
とcurrently
のそれぞれのリポジトリを見にいくと、確かに〇〇.proto
がありました。
ただ、See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
とあったので、見に行くことにしました。
英語で記載されていますが、よく見てみると、以下の記述があります。
At program execution. The behavior for handling conflicts when executing a particular Go binary can be set with an environment variable:
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main
訳:プログラム実行時。特定の Go バイナリを実行するときの競合を処理するための動作は、環境変数で設定できます。
調べてみると、登録されている名前が同じだと、競合してpanicエラーを起こすのはどうやら仕様のようです。
https://github.com/protocolbuffers/protobuf-go/blob/b0a9446/reflect/protoregistry/registry.go#L44-L65
ただ、競合は起こしますが、実装自体に影響は及ばさないため、このpanicエラーを回避するために、環境変数を設定して回避することにしました。
対応方法
今回の実装で環境変数を追加するには、Dockerfileとci.ymlに記載が必要でした。
ENV GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
- run: make test
env:
GOLANG_PROTOBUF_REGISTRATION_CONFLICT: warn
記載後、テストを走らせると、無事エラーを回避することができました。
WARNING: proto: file "〇〇.proto" is already registered
previously from: "github.com/△△/△△"
currently from: "github.com/□□/□□"
See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
まとめ
環境変数の追加以外に、解決方法としては、.proto
のファイル名を変更することが挙げられます。
ただ、実装の影響範囲が広かったため、今回は環境変数を追加する形とさせていただきました。
同じエラーに遭遇した際は、参考にしていただけますと幸いです。
最後までお読みいただきありがとうございました!