Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 13234] ファイルの概要

このコミットは、Go言語のダッシュボードアプリケーションの一部である misc/dashboard/app/build/build.gomisc/dashboard/app/build/notify.go の2つのファイルを変更しています。

  • misc/dashboard/app/build/build.go: ビルド結果やコミットの状態を管理するロジックが含まれていると推測されます。
  • misc/dashboard/app/build/notify.go: ビルドの失敗時に通知を行うロジックが含まれていると推測されます。

コミット

このコミットは、Go言語のビルドダッシュボードアプリケーションにおいて、以下の2つの主要な変更を行っています。

  1. notifyOnFailure 関数にデバッグログを追加し、ビルド失敗時の通知処理の可視性を向上させました。
  2. Result.OK という未使用の関数を削除し、コードベースの整理と冗長性の排除を行いました。

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/735ec945914e1a1e93ebbcf7a68f29b7179e7903

元コミット内容

misc/dashboard/app: add debug logging to notifyOnFailure; remove unused Result.OK function

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/6258064

変更の背景

このコミットの背景には、主に以下の2点があります。

  1. デバッグと可視性の向上: notifyOnFailure 関数は、Go言語のビルドダッシュボードにおいて、特定のビルドが失敗した際に通知を行う重要な役割を担っています。この関数内で何が起こっているのか、特にコミットの状態やビルド結果がどのように評価されているのかを詳細に把握することは、問題の診断やデバッグにおいて非常に重要です。デバッグログを追加することで、開発者が通知ロジックの動作をより深く理解し、潜在的な問題を特定しやすくなります。
  2. コードのクリーンアップと保守性の向上: Result.OK 関数は、コードベース内で定義されていましたが、実際にはどこからも呼び出されていませんでした。このような未使用のコードは、コードベースを不必要に複雑にし、将来の保守作業の妨げとなる可能性があります。未使用のコードを削除することで、コードベースがより簡潔になり、理解しやすくなり、長期的な保守性が向上します。

これらの変更は、Go言語のビルドインフラストラクチャの安定性と開発者の生産性を向上させることを目的としています。

前提知識の解説

このコミットを理解するためには、以下の技術的な前提知識があると役立ちます。

  • Go言語 (Golang):
    • 基本的な構文とデータ型: struct(構造体)、メソッド、変数宣言、条件分岐(if文)など、Go言語の基本的なプログラミング概念。
    • エラーハンドリング: Go言語におけるエラーの戻り値(errorインターフェース)と、fmt.Errorf を用いたエラー生成。
    • ポインタ: *Result のように、ポインタ型がどのように扱われるか。
  • Google App Engine (GAE):
    • appengine.Context: Google App Engineアプリケーションにおけるリクエストごとのコンテキストオブジェクト。これを通じて、ロギング、データストアへのアクセス、その他のApp Engineサービスが利用されます。
    • ロギング: c.Debugfappengine.Context のメソッドであり、App Engineのログにデバッグレベルのメッセージを出力するために使用されます。これは、アプリケーションの実行中に内部状態を監視するための重要なツールです。
  • Google Cloud Datastore:
    • datastore.NewQuery: Datastoreからエンティティをクエリするための関数。
    • Ancestor: Datastoreにおけるエンティティグループの概念。関連するエンティティをグループ化し、トランザクションの整合性を保証するために使用されます。ここでは、Commit エンティティが Package エンティティの子孫として扱われていることを示唆しています。
    • Filter: クエリ結果を特定の条件で絞り込むためのメソッド。
    • エンティティ: Datastoreに保存されるデータオブジェクトの単位。ここでは CommitResult がエンティティとして扱われています。
  • Go言語のビルドダッシュボード:
    • Go言語の公式ビルドシステムやダッシュボードは、様々なプラットフォームやアーキテクチャでのGoのビルド状況を監視し、テスト結果を報告するシステムです。このコミットは、そのダッシュボードアプリケーションの一部を修正しています。Commit は特定のコミットを表し、Result はそのコミットに対するビルド結果(成功/失敗など)を表すと考えられます。

技術的詳細

このコミットの技術的な変更は、主に2つの部分に分けられます。

1. Commit.OK メソッドの削除

misc/dashboard/app/build/build.go から Commit 型の OK メソッドが削除されました。

削除されたメソッドのシグネチャ:

func (c *Commit) OK(builder, goHash string) (ok, present bool)

このメソッドは、特定の buildergoHash(Goのバージョンハッシュ)に対するコミットのビルド状態が「OK」であるかどうか、そしてその結果が「存在するかどうか」をブール値で返していました。内部的には c.Result(builder, goHash) を呼び出し、その結果に基づいて okpresent を決定していました。

このメソッドが削除されたのは、notify.go 内で直接 Commit.Result メソッドを使用するように変更されたため、冗長になったためです。

2. notifyOnFailure 関数における変更

misc/dashboard/app/build/notify.go 内の notifyOnFailure 関数が変更されました。この関数は、ビルドが失敗した際に通知ロジックをトリガーする役割を担っています。

主な変更点:

  • Commit.OK の直接的な置き換え: 以前は com.OK(builder, "") を呼び出して okpresent の2つのブール値を取得していましたが、これが cr := com.Result(builder, "") となり、*Result 型のポインタを直接取得するようになりました。そして、結果が存在するかどうかのチェックは cr == nil で行われるようになりました。これにより、Commit.OK メソッドの削除が可能になりました。
  • Result.OK フィールドの直接参照: ビルド結果がOKかどうかを判断する際に、以前は ok 変数(Commit.OK の戻り値)を使用していましたが、変更後は cr.OKResult 構造体の OK フィールド)を直接参照するようになりました。
  • デバッグログの追加: appengine.Context.Debugf を使用して、通知ロジックの重要な分岐点にデバッグログが追加されました。これにより、特定のコミットがOKであると判断された場合や、次のコミットが壊れていると判断された場合など、通知がトリガーされる条件やその前後のコミット・結果オブジェクトの詳細がログに出力されるようになりました。これは、問題発生時の診断に非常に役立ちます。

これらの変更により、コードはより直接的になり、冗長な抽象化が排除され、同時にデバッグの容易性が向上しました。

コアとなるコードの変更箇所

misc/dashboard/app/build/build.go

--- a/misc/dashboard/app/build/build.go
+++ b/misc/dashboard/app/build/build.go
@@ -168,15 +168,6 @@ func partsToHash(c *Commit, p []string) *Result {
 	}
 }
 
-// OK returns the Commit's build state for a specific builder and goHash.
-// func (c *Commit) OK(builder, goHash string) (ok, present bool) {
-// 	r := c.Result(builder, goHash)
-// 	if r == nil {
-// 		return false, false
-// 	}
-// 	return r.OK, true
-// }
-
 // A Result describes a build result for a Commit on an OS/architecture.
 //
 // Each Result entity is a descendant of its associated Commit entity.

misc/dashboard/app/build/notify.go

--- a/misc/dashboard/app/build/notify.go
+++ b/misc/dashboard/app/build/notify.go
@@ -37,12 +37,12 @@ func notifyOnFailure(c appengine.Context, com *Commit, builder string) error {
 
 	p := &Package{Path: com.PackagePath}
 	var broken *Commit
-	ok, present := com.OK(builder, "")
-	if !present {
+	cr := com.Result(builder, "")
+	if cr == nil {
 		return fmt.Errorf("no result for %s/%s", com.Hash, builder)
 	}
 	q := datastore.NewQuery("Commit").Ancestor(p.Key(c))
-	if ok {
+	if cr.OK {
 		// This commit is OK. Notify if next Commit is broken.
 		next := new(Commit)
 		q.Filter("ParentHash=", com.Hash)
@@ -53,7 +53,9 @@ func notifyOnFailure(c appengine.Context, com *Commit, builder string) error {
 			}
 			return err
 		}
-		if ok, present := next.OK(builder, ""); present && !ok {
+		if nr := next.Result(builder, ""); nr != nil && !nr.OK {
+			c.Debugf("commit ok: %#v\nresult: %#v", com, cr)
+			c.Debugf("next commit broken: %#v\nnext result:%#v", next, nr)
 			broken = next
 		}
 	} else {
@@ -68,7 +70,9 @@ func notifyOnFailure(c appengine.Context, com *Commit, builder string) error {
 			}
 			return err
 		}
-		if ok, present := prev.OK(builder, ""); present && ok {
+		if pr := prev.Result(builder, ""); pr != nil && pr.OK {
+			c.Debugf("commit broken: %#v\nresult: %#v", com, cr)
+			c.Debugf("previous commit ok: %#v\nprevious result:%#v", prev, pr)
 			broken = com
 		}
 	}

コアとなるコードの解説

misc/dashboard/app/build/build.go の変更

  • 削除されたコード: Commit 型に定義されていた OK メソッドが完全に削除されました。このメソッドは、特定のビルド結果が存在するかどうか (present) と、その結果が成功 (ok) であるかどうかを返すヘルパー関数でした。
  • 理由: このメソッドは、後述する notify.go の変更により不要になったため、コードの冗長性を排除するために削除されました。

misc/dashboard/app/build/notify.go の変更

このファイルでは、notifyOnFailure 関数内のロジックが変更されています。この関数は、ビルドが失敗した際に通知をトリガーするかどうかを決定します。

  1. com.OK(builder, "") から com.Result(builder, "") への変更:

    • 変更前: ok, present := com.OK(builder, "")
      • Commit オブジェクトの OK メソッドを呼び出し、ビルド結果の成功状態 (ok) と存在状態 (present) を取得していました。
    • 変更後: cr := com.Result(builder, "")if cr == nil { ... }
      • Commit オブジェクトの Result メソッドを直接呼び出し、*Result 型のポインタ cr を取得します。
      • 結果が存在しない場合(crnil の場合)は、エラーを返します。
      • この変更により、build.go から Commit.OK メソッドを削除することが可能になりました。コードがより直接的になり、Result オブジェクトの存在チェックと成功状態のチェックが分離されました。
  2. if ok { ... } から if cr.OK { ... } への変更:

    • 変更前: if ok { ... }
      • Commit.OK メソッドから返された ok ブール値を使用して、現在のコミットが成功しているかどうかを判断していました。
    • 変更後: if cr.OK { ... }
      • com.Result から取得した Result オブジェクトの OK フィールドを直接参照して、現在のコミットが成功しているかどうかを判断します。これは、Result 構造体自体がビルドの成功状態を示す OK フィールドを持っているためです。
  3. next.OKprev.OK の置き換えとデバッグログの追加:

    • 同様に、次のコミット (next) や前のコミット (prev) の状態をチェックする際も、OK メソッドの呼び出しが Result メソッドの呼び出しに置き換えられました。
    • 変更前: if ok, present := next.OK(builder, ""); present && !ok { ... }
    • 変更後: if nr := next.Result(builder, ""); nr != nil && !nr.OK { ... }
      • next.Result から nr を取得し、nrnil でなく、かつ nr.OKfalse(つまりビルドが壊れている)場合に処理を進めます。
    • デバッグログの追加:
      • c.Debugf("commit ok: %#v\nresult: %#v", com, cr)
      • c.Debugf("next commit broken: %#v\nnext result:%#v", next, nr)
      • c.Debugf("commit broken: %#v\nresult: %#v", com, cr)
      • c.Debugf("previous commit ok: %#v\nprevious result:%#v", prev, pr)
      • これらの行は、appengine.ContextDebugf メソッドを使用して、現在のコミット、次のコミット、前のコミット、およびそれらのビルド結果の詳細をログに出力します。%#v フォーマット指定子は、Goの構造体の詳細な表現(フィールド名と値を含む)を出力するために使用され、デバッグ時に非常に役立ちます。これにより、通知ロジックがどのような状態のコミットに対して動作しているのかを、より詳細に追跡できるようになります。

これらの変更は、コードの簡素化、直接的なデータアクセス、そしてデバッグ情報の強化という点で、コードベースの品質を向上させています。

関連リンク

参考にした情報源リンク