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

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

このコミットは、Go言語の標準ライブラリ net パッケージから、廃止されたネットワークポーラーに関連するコードを削除するものです。具体的には、src/pkg/net/fd_posix_test.go ファイルが削除され、src/pkg/net/net.go ファイルから deadline 構造体とその関連メソッドが削除されています。これにより、Goのネットワーク処理におけるデッドライン管理の内部実装がより現代的なアプローチに移行したことが示唆されます。

コミット

commit 02faa939d3e419b14db5d1da41de6147a2123238
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Sep 10 20:00:21 2013 +0900

    net: remove dreg of obsoleted network poller
    
    R=golang-dev, dave
    CC=golang-dev
    https://golang.org/cl/13396051

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

https://github.com/golang/go/commit/02faa939d3e419b14db5d1da41de6147a2123238

元コミット内容

net: remove dreg of obsoleted network poller

R=golang-dev, dave
CC=golang-dev
https://golang.org/cl/13396051

変更の背景

このコミットの背景には、Go言語のネットワークI/Oにおけるデッドライン(タイムアウト)処理の進化があります。初期のGoのネットワークポーラーは、ファイルディスクリプタ(FD)の準備状況を監視し、I/O操作がブロックされるのを防ぐ役割を担っていました。しかし、時間の経過とともに、より効率的でスケーラブルなポーリングメカニズムが導入され、特にGo 1.1以降では、runtime パッケージに統合された新しいネットワークポーラーが採用されました。

この新しいポーラーは、OSのネイティブな非同期I/Oメカニズム(Linuxのepoll、macOS/FreeBSDのkqueueなど)をより直接的に利用し、Goのゴルーチンとスケジューラと密接に連携するように設計されています。これにより、ネットワークI/Oのパフォーマンスが向上し、デッドライン処理もより効率的に、かつ統一的に扱えるようになりました。

このコミットで削除された deadline 構造体は、古いネットワークポーラーの設計の一部であり、各ネットワーク接続のデッドラインを個別に管理するためのものでした。新しいポーラーの導入により、この古いデッドライン管理の仕組みは不要となり、コードベースからその「残骸(dreg)」を削除することが目的となりました。これにより、コードの複雑性が減少し、メンテナンス性が向上します。

前提知識の解説

ネットワークポーラー (Network Poller)

ネットワークポーラーは、オペレーティングシステムが提供するI/O多重化メカニズム(例: select, poll, epoll, kqueue)を利用して、複数のネットワーク接続(ソケット)からのI/Oイベント(読み取り可能、書き込み可能など)を効率的に監視するコンポーネントです。Goのランタイムは、このポーラーを使用して、ブロックする可能性のあるネットワークI/O操作を非同期的に処理し、ゴルーチンがブロックされることなく他の処理を実行できるようにします。

Goのネットワークポーラーは、Goのスケジューラと連携し、I/O操作が完了するまでゴルーチンをブロック状態にし、I/Oが準備できたときにゴルーチンを再開させます。これにより、多数の同時接続を効率的に扱うことが可能になり、C10K問題(単一サーバーで1万以上の同時接続を処理する問題)のような課題に対応できます。

デッドライン (Deadline)

ネットワークプログラミングにおけるデッドラインは、特定のI/O操作(読み取り、書き込み、接続確立など)が完了しなければならない最大時間を指します。デッドラインが設定されている場合、その時間内に操作が完了しないと、操作はタイムアウトし、エラーが返されます。これは、ネットワークの遅延や相手側の応答がない場合に、アプリケーションが無限にブロックされるのを防ぐために重要です。

Goの net パッケージでは、SetReadDeadline, SetWriteDeadline, SetDeadline といったメソッドを通じてデッドラインを設定できます。これらのメソッドは、内部的にネットワークポーラーと連携し、指定された時間内にI/Oイベントが発生しない場合にタイムアウトをトリガーします。

Goの net パッケージと runtime パッケージの連携

Goの net パッケージは、TCP/IP、UDP、Unixドメインソケットなどのネットワークプロトコルを扱うための高レベルなAPIを提供します。これらのAPIの背後では、runtime パッケージが提供する低レベルなネットワークポーラーが動作しています。net パッケージは、ユーザーがデッドラインを設定したり、非同期I/Oを意識することなく、同期的なI/O操作を記述できるように抽象化を提供します。しかし、その実体は runtime のポーラーによって非同期的に処理され、ゴルーチンのスケジューリングと連携しています。

このコミットは、この netruntime の連携における内部的なデッドライン管理の仕組みが、より洗練された runtime 側のポーラーに完全に統合されたことを示しています。

技術的詳細

このコミットは、GoのネットワークI/Oにおけるデッドライン管理の内部実装のクリーンアップを目的としています。具体的には、以下の要素が削除されています。

  1. src/pkg/net/fd_posix_test.go の削除: このファイルは、deadline 構造体とその関連メソッド(setTime, expired, value, set)のテストコードを含んでいました。このファイルが削除されたということは、これらのデッドライン管理のロジックが net パッケージの外部、すなわち runtime パッケージのネットワークポーラーに完全に移行し、net パッケージ内で個別にテストする必要がなくなったことを意味します。

  2. src/pkg/net/net.go から deadline 構造体と関連メソッドの削除: net.go ファイルから以下のコードが削除されました。

    // deadline is an atomically-accessed number of nanoseconds since 1970
    // or 0, if no deadline is set.
    type deadline struct {
        sync.Mutex
        val int64
    }
    
    func (d *deadline) expired() bool {
        t := d.value()
        return t > 0 && time.Now().UnixNano() >= t
    }
    
    func (d *deadline) value() (v int64) {
        d.Lock()
        v = d.val
        d.Unlock()
        return
    }
    
    func (d *deadline) set(v int64) {
        d.Lock()
        d.val = v
        d.Unlock()
    }
    
    func (d *deadline) setTime(t time.Time) {
        if t.IsZero() {
            d.set(0)
        } else {
            d.set(t.UnixNano())
        }
    }
    

    この deadline 構造体は、sync.Mutex を使用してデッドライン値を保護し、UnixNano() 形式で時間を管理していました。expired() メソッドは、現在の時刻と設定されたデッドラインを比較して、デッドラインが過ぎたかどうかを判断していました。これらのメソッドは、ネットワーク接続の読み取り/書き込みデッドラインを設定・チェックするために使用されていました。

    これらのコードが削除されたことは、net パッケージがデッドラインの管理を直接行わず、より低レベルの runtime パッケージのネットワークポーラーにその責任を完全に委譲したことを示しています。runtime パッケージのポーラーは、OSのI/O多重化メカニズムと連携して、デッドラインの監視とタイムアウトのトリガーを効率的に処理します。これにより、net パッケージのコードは簡素化され、デッドライン処理のロジックが一元化されます。

この変更は、Goのネットワークスタックが成熟し、より堅牢で効率的な内部アーキテクチャへと進化している過程の一部です。

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

src/pkg/net/fd_posix_test.go

このファイルは完全に削除されました。

src/pkg/net/net.go

以下のコードブロックが削除されました。

--- a/src/pkg/net/net.go
+++ b/src/pkg/net/net.go
@@ -46,7 +46,6 @@ import (
 	"errors"
 	"io"
 	"os"
-	"sync"
 	"syscall"
 	"time"
 )
@@ -401,39 +400,6 @@ func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
 	return io.Copy(writerOnly{w}, r)
 }
 
-// deadline is an atomically-accessed number of nanoseconds since 1970
-// or 0, if no deadline is set.
-type deadline struct {
-	sync.Mutex
-	val int64
-}
-
-func (d *deadline) expired() bool {
-	t := d.value()
-	return t > 0 && time.Now().UnixNano() >= t
-}
-
-func (d *deadline) value() (v int64) {
-	d.Lock()
-	v = d.val
-	d.Unlock()
-	return
-}
-
-func (d *deadline) set(v int64) {
-	d.Lock()
-	d.val = v
-	d.Unlock()
-}
-
-func (d *deadline) setTime(t time.Time) {
-	if t.IsZero() {
-		d.set(0)
-	} else {
-		d.set(t.UnixNano())
-	}
-}
-
 // Limit the number of concurrent cgo-using goroutines, because
 // each will block an entire operating system thread. The usual culprit
 // is resolving many DNS names in separate goroutines but the DNS

コアとなるコードの解説

削除された deadline 構造体は、ネットワーク接続のデッドライン(タイムアウト)を管理するためのものでした。

  • type deadline struct { sync.Mutex; val int64 }: この構造体は、デッドラインの値を int64 型で保持していました。val はUnixエポックからのナノ秒単位の時刻を表し、デッドラインが設定されていない場合は 0 でした。sync.Mutex は、複数のゴルーチンからの同時アクセスに対して val を保護するために使用されていました。

  • func (d *deadline) expired() bool: このメソッドは、デッドラインが期限切れになったかどうかをチェックしていました。d.value() でデッドラインの時刻を取得し、それが 0 より大きく(デッドラインが設定されている場合)、かつ現在の時刻 (time.Now().UnixNano()) がデッドラインの時刻以上であれば true を返していました。

  • func (d *deadline) value() (v int64): このメソッドは、deadline 構造体内に保持されているデッドラインの値を安全に(ミューテックスで保護して)取得していました。

  • func (d *deadline) set(v int64): このメソッドは、デッドラインの値を安全に設定していました。

  • func (d *deadline) setTime(t time.Time): このメソッドは、time.Time 型のデッドラインを受け取り、それをUnixナノ秒に変換して set メソッドを呼び出すことで、デッドラインを設定していました。t.IsZero() の場合はデッドラインを 0 に設定し、デッドラインがないことを示していました。

これらのコードが削除されたことで、net パッケージはデッドラインの低レベルな管理から解放され、その責任は runtime パッケージのより洗練されたネットワークポーラーに完全に委譲されました。これにより、Goのネットワークスタック全体の設計がよりクリーンで効率的になったと言えます。

関連リンク

  • Go言語のネットワークポーラーに関する議論や進化の歴史は、Goの公式ブログやデザインドキュメント、メーリングリストのアーカイブで確認できます。特に、Go 1.1のリリースノートや、ネットワークI/Oの改善に関する記事が参考になります。
  • Goの net パッケージのドキュメント: https://pkg.go.dev/net
  • Goの runtime パッケージのドキュメント: https://pkg.go.dev/runtime

参考にした情報源リンク

  • https://golang.org/cl/13396051 (このコミットのChange-ID)
  • Go 1.1 Release Notes (特に "Network I/O" セクション): https://go.dev/doc/go1.1
  • Goのネットワークポーラーに関する一般的な情報(Goの内部動作を解説しているブログ記事や書籍など)

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

このコミットは、Go言語の標準ライブラリ net パッケージから、廃止されたネットワークポーラーに関連するコードを削除するものです。具体的には、src/pkg/net/fd_posix_test.go ファイルが削除され、src/pkg/net/net.go ファイルから deadline 構造体とその関連メソッドが削除されています。これにより、Goのネットワーク処理におけるデッドライン管理の内部実装がより現代的なアプローチに移行したことが示唆されます。

コミット

commit 02faa939d3e419b14db5d1da41de6147a2123238
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date:   Tue Sep 10 20:00:21 2013 +0900

    net: remove dreg of obsoleted network poller
    
    R=golang-dev, dave
    CC=golang-dev
    https://golang.org/cl/13396051

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

https://github.com/golang/go/commit/02faa939d3e419b14db5d1da41de6147a2123238

元コミット内容

net: remove dreg of obsoleted network poller

R=golang-dev, dave
CC=golang-dev
https://golang.org/cl/13396051

変更の背景

このコミットの背景には、Go言語のネットワークI/Oにおけるデッドライン(タイムアウト)処理の進化があります。初期のGoのネットワークポーラーは、ファイルディスクリプタ(FD)の準備状況を監視し、I/O操作がブロックされるのを防ぐ役割を担っていました。しかし、時間の経過とともに、より効率的でスケーラブルなポーリングメカニズムが導入され、特にGo 1.1以降では、runtime パッケージに統合された新しいネットワークポーラーが採用されました。

この新しいポーラーは、OSのネイティブな非同期I/Oメカニズム(Linuxのepoll、macOS/FreeBSDのkqueueなど)をより直接的に利用し、Goのゴルーチンとスケジューラと密接に連携するように設計されています。これにより、ネットワークI/Oのパフォーマンスが向上し、デッドライン処理もより効率的に、かつ統一的に扱えるようになりました。

このコミットで削除された deadline 構造体は、古いネットワークポーラーの設計の一部であり、各ネットワーク接続のデッドラインを個別に管理するためのものでした。新しいポーラーの導入により、この古いデッドライン管理の仕組みは不要となり、コードベースからその「残骸(dreg)」を削除することが目的となりました。これにより、コードの複雑性が減少し、メンテナンス性が向上します。

前提知識の解説

ネットワークポーラー (Network Poller)

ネットワークポーラーは、オペレーティングシステムが提供するI/O多重化メカニズム(例: select, poll, epoll, kqueue)を利用して、複数のネットワーク接続(ソケット)からのI/Oイベント(読み取り可能、書き込み可能など)を効率的に監視するコンポーネントです。Goのランタイムは、このポーラーを使用して、ブロックする可能性のあるネットワークI/O操作を非同期的に処理し、ゴルーチンがブロックされることなく他の処理を実行できるようにします。

Goのネットワークポーラーは、Goのスケジューラと連携し、I/O操作が完了するまでゴルーチンをブロック状態にし、I/Oが準備できたときにゴルーチンを再開させます。これにより、多数の同時接続を効率的に扱うことが可能になり、C10K問題(単一サーバーで1万以上の同時接続を処理する問題)のような課題に対応できます。

デッドライン (Deadline)

ネットワークプログラミングにおけるデッドラインは、特定のI/O操作(読み取り、書き込み、接続確立など)が完了しなければならない最大時間を指します。デッドラインが設定されている場合、その時間内に操作が完了しないと、操作はタイムアウトし、エラーが返されます。これは、ネットワークの遅延や相手側の応答がない場合に、アプリケーションが無限にブロックされるのを防ぐために重要です。

Goの net パッケージでは、SetReadDeadline, SetWriteDeadline, SetDeadline といったメソッドを通じてデッドラインを設定できます。これらのメソッドは、内部的にネットワークポーラーと連携し、指定された時間内にI/Oイベントが発生しない場合にタイムアウトをトリガーします。

Goの net パッケージと runtime パッケージの連携

Goの net パッケージは、TCP/IP、UDP、Unixドメインソケットなどのネットワークプロトコルを扱うための高レベルなAPIを提供します。これらのAPIの背後では、runtime パッケージが提供する低レベルなネットワークポーラーが動作しています。net パッケージは、ユーザーがデッドラインを設定したり、非同期I/Oを意識することなく、同期的なI/O操作を記述できるように抽象化を提供します。しかし、その実体は runtime のポーラーによって非同期的に処理され、ゴルーチンのスケジューリングと連携しています。

このコミットは、この netruntime の連携における内部的なデッドライン管理の仕組みが、より洗練された runtime 側のポーラーに完全に統合されたことを示しています。

技術的詳細

このコミットは、GoのネットワークI/Oにおけるデッドライン管理の内部実装のクリーンアップを目的としています。具体的には、以下の要素が削除されています。

  1. src/pkg/net/fd_posix_test.go の削除: このファイルは、deadline 構造体とその関連メソッド(setTime, expired, value, set)のテストコードを含んでいました。このファイルが削除されたということは、これらのデッドライン管理のロジックが net パッケージの外部、すなわち runtime パッケージのネットワークポーラーに完全に移行し、net パッケージ内で個別にテストする必要がなくなったことを意味します。

  2. src/pkg/net/net.go から deadline 構造体と関連メソッドの削除: net.go ファイルから以下のコードが削除されました。

    // deadline is an atomically-accessed number of nanoseconds since 1970
    // or 0, if no deadline is set.
    type deadline struct {
        sync.Mutex
        val int64
    }
    
    func (d *deadline) expired() bool {
        t := d.value()
        return t > 0 && time.Now().UnixNano() >= t
    }
    
    func (d *deadline) value() (v int64) {
        d.Lock()
        v = d.val
        d.Unlock()
        return
    }
    
    func (d *deadline) set(v int64) {
        d.Lock()
        d.val = v
        d.Unlock()
    }
    
    func (d *deadline) setTime(t time.Time) {
        if t.IsZero() {
            d.set(0)
        } else {
            d.set(t.UnixNano())
        }
    }
    

    この deadline 構造体は、sync.Mutex を使用してデッドライン値を保護し、UnixNano() 形式で時間を管理していました。expired() メソッドは、現在の時刻と設定されたデッドラインを比較して、デッドラインが過ぎたかどうかを判断していました。これらのメソッドは、ネットワーク接続の読み取り/書き込みデッドラインを設定・チェックするために使用されていました。

    これらのコードが削除されたことは、net パッケージがデッドラインの管理を直接行わず、より低レベルの runtime パッケージのネットワークポーラーにその責任を完全に委譲したことを示しています。runtime パッケージのポーラーは、OSのI/O多重化メカニズムと連携して、デッドラインの監視とタイムアウトのトリガーを効率的に処理します。これにより、net パッケージのコードは簡素化され、デッドライン処理のロジックが一元化されます。

この変更は、Goのネットワークスタックが成熟し、より堅牢で効率的な内部アーキテクチャへと進化している過程の一部です。

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

src/pkg/net/fd_posix_test.go

このファイルは完全に削除されました。

src/pkg/net/net.go

以下のコードブロックが削除されました。

--- a/src/pkg/net/net.go
+++ b/src/pkg/net/net.go
@@ -46,7 +46,6 @@ import (
 	"errors"
 	"io"
 	"os"
-	"sync"
 	"syscall"
 	"time"
 )
@@ -401,39 +400,6 @@ func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
 	return io.Copy(writerOnly{w}, r)
 }
 
-// deadline is an atomically-accessed number of nanoseconds since 1970
-// or 0, if no deadline is set.
-type deadline struct {
-	sync.Mutex
-	val int64
-}
-
-func (d *deadline) expired() bool {
-	t := d.value()
-	return t > 0 && time.Now().UnixNano() >= t
-}
-
-func (d *deadline) value() (v int64) {
-	d.Lock()
-	v = d.val
-	d.Unlock()
-	return
-}
-
-func (d *deadline) set(v int64) {
-	d.Lock()
-	d.val = v
-	d.Unlock()
-}
-
-func (d *deadline) setTime(t time.Time) {
-	if t.IsZero() {
-		d.set(0)
-	} else {
-		d.set(t.UnixNano())
-	}
-}
-
 // Limit the number of concurrent cgo-using goroutines, because
 // each will block an entire operating system thread. The usual culprit
 // is resolving many DNS names in separate goroutines but the DNS

コアとなるコードの解説

削除された deadline 構造体は、ネットワーク接続のデッドライン(タイムアウト)を管理するためのものでした。

  • type deadline struct { sync.Mutex; val int64 }: この構造体は、デッドラインの値を int64 型で保持していました。val はUnixエポックからのナノ秒単位の時刻を表し、デッドラインが設定されていない場合は 0 でした。sync.Mutex は、複数のゴルーチンからの同時アクセスに対して val を保護するために使用されていました。

  • func (d *deadline) expired() bool: このメソッドは、デッドラインが期限切れになったかどうかをチェックしていました。d.value() でデッドラインの時刻を取得し、それが 0 より大きく(デッドラインが設定されている場合)、かつ現在の時刻 (time.Now().UnixNano()) がデッドラインの時刻以上であれば true を返していました。

  • func (d *deadline) value() (v int64): このメソッドは、deadline 構造体内に保持されているデッドラインの値を安全に(ミューテックスで保護して)取得していました。

  • func (d *deadline) set(v int64): このメソッドは、デッドラインの値を安全に設定していました。

  • func (d *deadline) setTime(t time.Time): このメソッドは、time.Time 型のデッドラインを受け取り、それをUnixナノ秒に変換して set メソッドを呼び出すことで、デッドラインを設定していました。t.IsZero() の場合はデッドラインを 0 に設定し、デッドラインがないことを示していました。

これらのコードが削除されたことで、net パッケージはデッドラインの低レベルな管理から解放され、その責任は runtime パッケージのより洗練されたネットワークポーラーに完全に委譲されました。これにより、Goのネットワークスタック全体の設計がよりクリーンで効率的になったと言えます。

関連リンク

  • Go言語のネットワークポーラーに関する議論や進化の歴史は、Goの公式ブログやデザインドキュメント、メーリングリストのアーカイブで確認できます。特に、Go 1.1のリリースノートや、ネットワークI/Oの改善に関する記事が参考になります。
  • Goの net パッケージのドキュメント: https://pkg.go.dev/net
  • Goの runtime パッケージのドキュメント: https://pkg.go.dev/runtime

参考にした情報源リンク

  • https://golang.org/cl/13396051 (このコミットのChange-ID)
  • Go 1.1 Release Notes (特に "Network I/O" セクション): https://go.dev/doc/go1.1
  • Goのネットワークポーラーに関する一般的な情報(Goの内部動作を解説しているブログ記事や書籍など)