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

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

このコミットは、Go言語の標準ライブラリ net パッケージにおけるUnixドメインソケット関連のコードに対する修正です。具体的には、UnixAddr 型のドキュメントを修正し、ResolveUnixAddr 関数の実装を簡素化しています。

コミット

commit 8b6d50170463e402e94eab9f260c5e09fa8b0146
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Sat Mar 23 07:39:43 2013 +0900

    net: fix documentation for UnixAddr

    Also simplifies ResolveUnixAddr.

    R=golang-dev, dave, rsc, bradfitz
    CC=golang-dev
    https://golang.org/cl/7510047

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

https://github.com/golang/go/commit/8b6d50170463e402e94eab9f260c5e09fa8b0146

元コミット内容

net: fix documentation for UnixAddr

Also simplifies ResolveUnixAddr.

変更の背景

このコミットの背景には、Go言語の net パッケージが提供するUnixドメインソケットのサポートにおける、ドキュメントの不正確さとコードの冗長性がありました。

Unixドメインソケットは、同じホスト上のプロセス間通信(IPC)メカニズムとして広く利用されています。Goの net パッケージは、TCP/IPソケットと同様に、Unixドメインソケット(unix)、データグラムソケット(unixgram)、シーケンスパケットソケット(unixpacket)をサポートしています。

コミット前の UnixAddr.Network() メソッドのドキュメントは、サポートするネットワークタイプとして "unix""unixgram" のみを記載しており、実際にはサポートされている "unixpacket" が欠落していました。これはドキュメントの不備であり、ユーザーが UnixAddr 型の Network() メソッドが返す可能性のあるすべての値を正確に理解する上で障害となっていました。

また、ResolveUnixAddr 関数は、指定されたネットワークタイプに基づいて UnixAddr 構造体を解決する役割を担っていますが、その実装は switch 文内で各ケースを個別に記述しており、冗長性がありました。サポートされるネットワークタイプが複数ある場合、これらをまとめて処理できるにもかかわらず、個別に return 文を記述する必要がありました。このコミットは、これらの問題を解決し、コードの正確性と簡潔性を向上させることを目的としています。

前提知識の解説

このコミットを理解するためには、以下の概念を把握しておく必要があります。

  • Unixドメインソケット (Unix Domain Sockets - UDS):

    • 同じホストマシン上で動作するプロセス間で通信を行うためのIPC(プロセス間通信)メカニズムです。
    • ネットワークスタックを介さず、カーネル内で直接通信が行われるため、TCP/IPソケットに比べてオーバーヘッドが少なく、高速です。
    • ファイルシステム上のパス名(例: /tmp/my_socket)をアドレスとして使用します。
    • Go言語の net パッケージでは、以下の3種類のUnixドメインソケットがサポートされています。
      • "unix": ストリーム指向のソケット(TCPに相当)。信頼性があり、順序付けされたバイトストリームを提供します。
      • "unixgram": データグラム指向のソケット(UDPに相当)。メッセージの境界を保持しますが、信頼性や順序付けは保証されません。
      • "unixpacket": シーケンスパケット指向のソケット。データグラムソケットと同様にメッセージの境界を保持しますが、信頼性があり、順序付けも保証されます。これは、一部のUnix系システムで利用可能な特殊なソケットタイプです。
  • Go言語の net パッケージ:

    • ネットワークI/Oプリミティブを提供するGoの標準ライブラリです。
    • net.Addr インターフェースは、ネットワークアドレスの汎用的な表現を提供します。
    • net.UnixAddr 構造体は、Unixドメインソケットのアドレスを表します。
      type UnixAddr struct {
          Name string // ソケットのパス名
          Net  string // ネットワークタイプ ("unix", "unixgram", "unixpacket")
      }
      
    • Network() string メソッド: net.Addr インターフェースの一部であり、アドレスのネットワークタイプ(例: "tcp", "udp", "unix")を文字列で返します。UnixAddr 型の場合、Net フィールドの値を返します。
    • ResolveUnixAddr(net, addr string) (*UnixAddr, error) 関数: 指定されたネットワークタイプとアドレス文字列から *UnixAddr を解決(構築)します。

技術的詳細

このコミットは、src/pkg/net/unixsock.go ファイルに対して2つの主要な変更を加えています。

  1. UnixAddr.Network() メソッドのドキュメント修正:

    • 変更前: // Network returns the address's network name, "unix" or "unixgram".
    • 変更後: // Network returns the address's network name, "unix", "unixgram" or // "unixpacket".
    • この変更は、UnixAddr がサポートするネットワークタイプに "unixpacket" が含まれることを明確にするために行われました。これにより、ドキュメントが実際のコードの振る舞いと一致し、ユーザーが Network() メソッドの戻り値として "unixpacket" が返される可能性があることを認識できるようになります。これは、特に unixpacket ソケットを使用するアプリケーションを開発する際に重要です。
  2. ResolveUnixAddr 関数の簡素化:

    • 変更前は、switch 文で "unix", "unixpacket", "unixgram" の各ケースを個別に記述し、それぞれで return &UnixAddr{addr, net}, nil を実行していました。
    • 変更後: case "unix", "unixgram", "unixpacket": のように、複数のケースをカンマで区切ってまとめて記述し、共通の処理 return &UnixAddr{Name: addr, Net: net}, nil を実行するように変更されました。
    • この変更は、コードの冗長性を排除し、可読性を向上させます。複数のネットワークタイプが同じロジックで処理される場合、このようにまとめることで、コードがより簡潔になり、将来的に新しいネットワークタイプが追加された場合でも、変更が容易になります。default ケースは、未知のネットワークタイプが指定された場合にエラーを返すという既存の振る舞いを維持しています。

これらの変更は、Goの net パッケージの品質と保守性を向上させるための小さな、しかし重要な改善です。

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

--- a/src/pkg/net/unixsock.go
+++ b/src/pkg/net/unixsock.go
@@ -12,7 +12,8 @@ type UnixAddr struct {
 	Net  string
 }
 
-// Network returns the address's network name, "unix" or "unixgram".
+// Network returns the address's network name, "unix", "unixgram" or
+// "unixpacket".
 func (a *UnixAddr) Network() string {
 	return a.Net
 }
@@ -36,11 +37,9 @@ func (a *UnixAddr) toAddr() Addr {
 // "unixpacket".
 func ResolveUnixAddr(net, addr string) (*UnixAddr, error) {
 	switch net {
-\tcase "unix":
-\tcase "unixpacket":
-\tcase "unixgram":
+\tcase "unix", "unixgram", "unixpacket":
+\t\treturn &UnixAddr{Name: addr, Net: net}, nil
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-\treturn &UnixAddr{addr, net}, nil
 }\n

コアとなるコードの解説

src/pkg/net/unixsock.go

このファイルは、Go言語の net パッケージにおけるUnixドメインソケット関連の型と関数を定義しています。

UnixAddr.Network() メソッドのドキュメント修正

 // Network returns the address's network name, "unix", "unixgram" or
 // "unixpacket".
 func (a *UnixAddr) Network() string {
 	return a.Net
 }
  • 変更前: コメントは "unix""unixgram" のみを列挙していました。
  • 変更後: コメントに "unixpacket" が追加されました。
  • 解説: UnixAddr 構造体の Net フィールドは、Unixドメインソケットのネットワークタイプ("unix", "unixgram", "unixpacket")を保持します。Network() メソッドはこの Net フィールドの値をそのまま返します。この変更は、ドキュメントが実際のコードの振る舞いと一致するように、"unixpacket" も有効なネットワークタイプとして明記したものです。これにより、このメソッドの利用者が、返される可能性のあるすべてのネットワークタイプを正確に理解できるようになります。

ResolveUnixAddr 関数の簡素化

 func ResolveUnixAddr(net, addr string) (*UnixAddr, error) {
 	switch net {
-\tcase "unix":
-\tcase "unixpacket":
-\tcase "unixgram":
+\tcase "unix", "unixgram", "unixpacket":
+\t\treturn &UnixAddr{Name: addr, Net: net}, nil
 	default:
 		return nil, UnknownNetworkError(net)
 	}
-\treturn &UnixAddr{addr, net}, nil
 }
  • 変更前:
    	switch net {
    	case "unix":
    	case "unixpacket":
    	case "unixgram":
    	default:
    		return nil, UnknownNetworkError(net)
    	}
    	return &UnixAddr{addr, net}, nil
    
    このコードでは、"unix", "unixpacket", "unixgram" の各ケースが個別に記述されており、それぞれのケースで何も処理を行わず、switch 文の後に共通の return 文がありました。これは、switch 文のフォールスルー(Goでは明示的な fallthrough が必要ですが、ここでは各ケースが空であるため、実質的に次のケースに処理が移るかのように見えます)を利用しているわけではなく、単に各ケースが空で、最終的に共通の return に到達するという冗長な書き方でした。
  • 変更後:
    	switch net {
    	case "unix", "unixgram", "unixpacket":
    		return &UnixAddr{Name: addr, Net: net}, nil
    	default:
    		return nil, UnknownNetworkError(net)
    	}
    
  • 解説: 複数の case ラベルをカンマで区切って記述することで、それらのいずれかに一致した場合に続くコードブロックが実行されます。この変更により、"unix", "unixgram", "unixpacket" のいずれかのネットワークタイプが指定された場合、直接 &UnixAddr{Name: addr, Net: net}, nil を返します。これにより、コードが大幅に簡素化され、同じロジックを繰り返す必要がなくなりました。default ケースは、サポートされていないネットワークタイプが渡された場合に UnknownNetworkError を返すという既存の振る舞いを維持しており、関数の堅牢性は損なわれていません。

関連リンク

参考にした情報源リンク