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

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

このコミットは、Go言語の標準ライブラリ net パッケージ内の lookup.go ファイルに対する変更です。主な目的は、コードの可読性と整理を向上させるために、IPアドレスのルックアップに関連する関数群を論理的にまとめること、およびインポート宣言の記述スタイルを統一することです。

コミット

commit 29de03adf38a1a813500e3fa2953740282b9a1e5
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Sat Aug 31 16:29:50 2013 +0900

    net: keep lookup IP stuff close
    
    Also flattens import declaration.
    
    R=golang-dev, alex.brainman
    CC=golang-dev
    https://golang.org/cl/13373046

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

https://github.com/golang/go/commit/29de03adf38a1a813500e3fa2953740282b9a1e5

元コミット内容

net: keep lookup IP stuff close Also flattens import declaration.

変更の背景

このコミットは、Go言語の標準ライブラリ net パッケージのコードベースの保守性と可読性を向上させることを目的としています。具体的な背景としては、以下の点が挙げられます。

  1. コードの局所性(Locality)の向上: LookupHostLookupIP という、ホスト名やIPアドレスのルックアップに関連する公開関数が、ファイル内の異なる場所に散らばっていました。これらの関数を関連性の高い他の変数(protocols マップや lookupGroup)の近くに配置することで、コードを読む人が関連する定義やロジックを一度に見つけやすくなります。これは、コードの理解を深め、将来的な変更やデバッグを容易にする上で重要です。
  2. インポート宣言の統一: Goのコードスタイルガイドラインでは、単一のパッケージをインポートする場合、import "package" の形式を推奨しています。このコミット以前は、time パッケージのインポートが複数行のブロック形式で記述されていましたが、これを単一行形式に修正することで、コードベース全体のスタイルの一貫性を保ち、Goの慣習に沿った記述にしています。
  3. リファクタリングの一環: このような変更は、機能追加やバグ修正とは異なり、既存のコードの構造を改善する「リファクタリング」の一環として行われます。リファクタリングは、長期的なソフトウェア品質を維持するために不可欠な活動です。

前提知識の解説

このコミットを理解するためには、以下のGo言語およびネットワークに関する基本的な知識が役立ちます。

  • Go言語のパッケージとインポート: Go言語では、関連する機能は「パッケージ」としてまとめられます。他のパッケージの機能を利用するには、import キーワードを使ってそのパッケージをインポートする必要があります。インポート宣言には、複数行で複数のパッケージをインポートする形式と、単一行で一つのパッケージをインポートする形式があります。Goの慣習として、単一インポートの場合は単一行形式が好まれます。
  • net パッケージ: Goの標準ライブラリの一部であり、ネットワークI/Oのプリミティブインターフェースを提供します。TCP/IP、UDP、DNSルックアップなど、様々なネットワーク関連の機能が含まれています。
  • DNSルックアップ: ドメイン名(例: google.com)をIPアドレス(例: 172.217.160.142)に変換するプロセスです。LookupHostLookupIP といった関数は、このDNSルックアップを実行するために使用されます。
  • singleflight パッケージ(概念): Goの標準ライブラリには直接 singleflight というパッケージは存在しませんが、golang.org/x/sync/singleflight パッケージとして提供されています。これは、複数のゴルーチンが同じキーで同じ関数を呼び出そうとしたときに、その関数が実際に実行されるのは一度だけで、すべての呼び出し元にその結果を共有させるためのメカニズムです。これにより、重複する作業を防ぎ、リソースの消費を抑えることができます。lookupGroup singleflight という変数名から、このコミットの対象ファイルでも同様のパターンが使われていることが示唆されます。DNSルックアップのような操作は、同じホスト名に対して何度も実行される可能性があるため、singleflight パターンは非常に有効です。

技術的詳細

このコミットは、src/pkg/net/lookup.go ファイルに対して行われました。このファイルは、主にDNSルックアップやポートルックアップといった、ネットワークアドレス解決に関する機能を提供しています。

変更の技術的な詳細は以下の通りです。

  1. インポート宣言の変更:

    • 変更前:
      import (
      	"time"
      )
      
    • 変更後:
      import "time"
      

    これは、Goのツール goimportsgofmt が推奨するスタイルに合わせたもので、コードの自動整形ツールとの整合性を高めます。機能的な変更は一切ありません。

  2. LookupHost および LookupIP 関数の移動:

    • 変更前は、LookupHost 関数は lookupIPMerge の後に、LookupIP 関数は lookupIPDeadline の後に定義されていました。
    • 変更後は、これらの関数が protocols マップと lookupGroup 変数の直後に移動されました。
      • protocols は、プロトコル名と番号のマッピングを定義しています。
      • lookupGroup は、singleflight パターンを実装するための変数で、重複するルックアップリクエストをまとめる役割を担っています。 この移動により、LookupHostLookupIP が、それらが利用する内部的なメカニズム(lookupGroup を介した重複排除など)や関連データ(protocols)の近くに配置され、コードの論理的なまとまりが強化されました。

これらの変更は、Goのコードベース全体で一貫したスタイルと構造を維持するための継続的な取り組みの一部です。機能的な振る舞いは一切変更されていませんが、将来のメンテナンスや新規開発において、開発者がコードをより迅速に理解し、変更を加えることを容易にします。

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

--- a/src/pkg/net/lookup.go
+++ b/src/pkg/net/lookup.go
@@ -4,9 +4,7 @@
 
  package net
  
 -import (
 -	"time"
 -)
 +import "time"
  
  // protocols contains minimal mappings between internet protocol
  // names and numbers for platforms that don't have a complete list of
@@ -21,6 +19,18 @@ var protocols = map[string]int{
  	"ipv6-icmp": 58, "IPV6-ICMP": 58, "IPv6-ICMP": 58,
  }
  
 +// LookupHost looks up the given host using the local resolver.
 +// It returns an array of that host's addresses.
 +func LookupHost(host string) (addrs []string, err error) {
 +	return lookupHost(host)
 +}
 +
 +// LookupIP looks up host using the local resolver.
 +// It returns an array of that host's IPv4 and IPv6 addresses.
 +func LookupIP(host string) (addrs []IP, err error) {
 +	return lookupIPMerge(host)
 +}
 +
  var lookupGroup singleflight
  
  // lookupIPMerge wraps lookupIP, but makes sure that for any given
@@ -42,12 +52,6 @@ func lookupIPMerge(host string) (addrs []IP, err error) {
  	return addrs, nil
  }
  
 -// LookupHost looks up the given host using the local resolver.
 -// It returns an array of that host's addresses.
 -func LookupHost(host string) (addrs []string, err error) {
 -	return lookupHost(host)
 -}
 -
  func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
  	if deadline.IsZero() {
  		return lookupIPMerge(host)
@@ -85,12 +89,6 @@ func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
  	return
  }
  
 -// LookupIP looks up host using the local resolver.
 -// It returns an array of that host's IPv4 and IPv6 addresses.
 -func LookupIP(host string) (addrs []IP, err error) {
 -	return lookupIPMerge(host)
 -}
 -
  // LookupPort looks up the port for the given network and service.
  func LookupPort(network, service string) (port int, err error) {
  	return lookupPort(network, service)

コアとなるコードの解説

このコミットのコアとなる変更は、src/pkg/net/lookup.go ファイル内の以下の2点です。

  1. インポート宣言の簡素化:

    • 元のコードでは、time パッケージのインポートが複数行のブロック形式で記述されていました。
    • 変更後、これが単一行の import "time" に修正されました。
    • これはGoの慣習に沿ったもので、単一のパッケージをインポートする際にはこの形式が推奨されます。コードの見た目をすっきりとさせ、gofmtgoimports といったGoの標準的なフォーマッタとの整合性を高めます。機能的な影響は全くありません。
  2. LookupHostLookupIP 関数の移動:

    • LookupHostLookupIP は、それぞれホスト名からアドレスを解決するための公開関数です。
    • 元のコードでは、これらの関数はファイル内の比較的離れた位置に定義されていました。
    • このコミットでは、これらの関数が protocols マップと lookupGroup 変数の直後に移動されました。
      • protocols は、ネットワークプロトコルに関する定数を定義しています。
      • lookupGroup は、singleflight パッケージ(golang.org/x/sync/singleflight)のインスタンスであり、同じDNSルックアップリクエストが複数回発行された場合に、実際のルックアップ処理を一度だけ実行し、その結果を共有することで効率化を図るためのものです。
    • この移動の意図は、これらの公開関数が内部的に利用するデータ構造やヘルパー(lookupGroup を介した重複排除ロジックなど)の近くに配置することで、コードの局所性を高め、関連するコードがまとまって読めるようにすることです。これにより、開発者がlookup.goファイルを見たときに、IPルックアップに関する主要な公開APIとその背後にある主要なメカニズムをより迅速に把握できるようになります。

これらの変更は、コードの機能的な振る舞いには影響を与えませんが、Goのコードベース全体の品質、特に可読性と保守性を向上させるための重要なリファクタリングです。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のソースコード(src/pkg/net/lookup.go
  • Goコミュニティでの一般的なコーディングスタイルとリファクタリングのプラクティス
  • singleflight パッケージの概念に関する一般的な情報