このファイルは、workshop各Phaseの実装で詰まったときに参照してください。
ログファイルを1つずつ順番に処理して、全体の結果を集計します。
- 結果を格納するスライス
- ファイルを1つずつ処理するループ
- エラーハンドリング(エラーが出ても処理を続ける)
- 結果の収集
- 結果を入れる空のスライスを作る
- ファイル一覧をループで回す
- 各ファイルを processFile() で処理
- エラーが出たら標準エラーに出力して次へ
- 成功したら結果をスライスに追加
- 全部終わったらスライスを返す
Phase 1では1つずつ順番に処理しましたが、Phase 2では全ファイルを同時に処理します。 goroutineを使って各ファイルを別々に処理し、結果をchannelで集めます。
- 結果を送受信するchannel
- 全goroutineの完了を待つWaitGroup
- 各ファイルに対するgoroutine
- channelのclose処理
- バッファ付きchannelを作る(ファイル数分)
- WaitGroupを作る
- 各ファイルに対してgoroutineを起動
- WaitGroupにAdd(1)
- goroutine内でdefer Done()
- processFile()を呼び出し
- 結果をchannelに送信
- 別のgoroutineでWaitGroupを待ち、完了したらchannelをclose
- channelから結果をfor rangeで全部受け取る `
Phase 2では全ファイルに対してgoroutineを作りましたが、Phase 3では固定数のワーカー(goroutine)を作り、 それらがファイルを順番に処理していきます。これにより大量のファイルでもgoroutine数を制御できます。
Go 1.25の新機能 WaitGroup.Go() を使います。
- ジョブ(ファイル名)を配布するchannel
- 結果を集めるchannel
- 固定数のワーカーgoroutine
- ワーカー数の決定(
runtime.NumCPU()) - ジョブのchannel投入とclose
- 結果のchannel受信
- jobsとresultsの2つのchannelを作る
- WaitGroupを作る
- ワーカー数分(CPU数分)だけgoroutineを起動
- 各ワーカーはjobsからファイル名を取り出して処理
- 結果をresultsに送信
- 全ファイル名をjobsに投入してclose
- 別のgoroutineで全ワーカーの完了を待ち、resultsをclose
- resultsから結果を全部受け取る
詰まったら気軽に solutions/ を参照してください。学習が目的なので、完璧を目指す必要はありません!