sitateru tech blog: プルリクエスト

sitateru tech blog

シタテルの技術やエンジニアの取り組みを紹介するテックブログです。

ラベル プルリクエスト の投稿を表示しています。 すべての投稿を表示
ラベル プルリクエスト の投稿を表示しています。 すべての投稿を表示

2018年12月18日火曜日

FirebaseのSDKのプルリクを追ってみた

12月 18, 2018

こんにちは、シタテルの鶴巻です。 devops&インフラ担当です。

最近、firebase/firebase-admin-goの実装で気になったところがあり、プルリクエストから経緯を知ることができました。

GitHub上のソースコードで気になった箇所の経緯を追うことは今後もあると思うので、整理がてら方法を紹介します。

要約

  • firebase/firebase-admin-goの実装で気になったところがあった
  • git blameコマンドで、ソースコードが最後に編集されたhashを特定
  • 対象のソースコードが追加されたプルリクエストで経緯が分かった

firebase-admin-sdk-goの実装で気になった箇所

firebase-admin-sdk-goは、名前の通りFirebaseサービスをGolangから扱うためのSDKです。

Firebase Authenticationを試してみた際に、弊社で使用しているRubyのSDKがなかったため、GolangのSDKの実装を少し読んでみました。

そこで、Googleのサーバから公開鍵を取得するメソッドの中で排他制御が行われていることに着目しました。
私はここで排他制御を実施している理由がわからなかったので、経緯を調べることにしました。

該当ソースコードは以下です。
https://github.com/firebase/firebase-admin-go/blob/master/auth/token_verifier.go#L66-L76

func (k *httpKeySource) Keys(ctx context.Context) ([]*publicKey, error) {
    k.Mutex.Lock()
    defer k.Mutex.Unlock()
    if len(k.CachedKeys) == 0 || k.hasExpired() {
        err := k.refreshKeys(ctx)
        if err != nil && len(k.CachedKeys) == 0 {
            return nil, err
        }
    }
    return k.CachedKeys, nil
}

プルリクエストを見つける手順

1. git blameコマンドで、対象のソースコードが最後に編集されたcommitのHash値を特定

  • 対象のソースコードが最後に変更されたcommiのHash値はf3174984ということが特定できます
    $ git blame auth/token_verifier.go | grep -e "k.Mutex.Lock()" -e "defer k.Mutex.Unlock()"
    f3174984 auth/crypto.go         (Hiranya Jayathilaka 2017-05-18 13:45:30 -0700  67)     k.Mutex.Lock()
    f3174984 auth/crypto.go         (Hiranya Jayathilaka 2017-05-18 13:45:30 -0700  68)     defer k.Mutex.Unlock()

2. GitHubの対象レポのプルリクエストをHash値で検索

実装の理由は?

  • プルリクエストのコメントにありました

  • 複数のスレッドが共有している公開鍵のキャッシュを同時に更新するのを防ぐためにmutexを導入したみたいです。

Introduced a mutex to prevent multiple threads from updating the shared cache concurrently.

  • ソースコードを追うと、公開鍵取得のメソッドは httpKeySource構造体に定義されており、さらにhttpKeySourceはClient構造体に定義されています。SDKを使う際に最初にClientの初期化を行いますが、初期化した同一のClientで公開鍵取得メソッドがconcurrencyに実行されても安全なように実装されているのかなと考察しました。

firebase-admin-sdk-goはgit-flow

firebase-admin-sdk-goはgit-flowで開発されているようです。

そのため、masterのソースコードのcommitのHash値がプルリクエストがマージされた時のHash値と同じで、プルリクエストが見つけやすかったです。

おまけ(nodejsの実装)

Node.jsのSDKの同じ箇所の実装についても少し覗いてみました。

Node.jsを書いたことはありませんが、見る限り排他制御はしていないように見えます。

Node.jsはシングルスレッド推奨だから排他制御しなくていいのか・・・など思い、言語の特性の違いが垣間見えて面白いですね。

まとめ

  • オープンソース文化いいですね。今回の例だとfirebaseの中の人が書いたソースコードや、そのプルリクを見ることができています(もしかしたら中の人じゃないかもしれませんが)。エンジニアとしては当たり前な文化ですが、ブラックボックス化されている業界が多いなか改めて良い文化だと思いました。
  • シタテルはRailsを使用しているので、RubyのSDKがあればFirebase Auth導入してみたかったのですが残念です。