| 378 | } |
| 379 | |
| 380 | func (m *Manager) waitReload(ctx context.Context, ch <-chan reloadResult, timeout time.Duration) error { |
| 381 | // Prefer caller cancellation when it already happened before the |
| 382 | // wait. Otherwise select may choose a ready reload result instead. |
| 383 | if err := ctx.Err(); err != nil { |
| 384 | return err |
| 385 | } |
| 386 | |
| 387 | var timeoutC <-chan time.Time |
| 388 | if timeout > 0 { |
| 389 | timer := m.clock.NewTimer(timeout, "agentmcp", "tools_reload") |
| 390 | defer timer.Stop() |
| 391 | timeoutC = timer.C |
| 392 | } |
| 393 | |
| 394 | select { |
| 395 | case res := <-ch: |
| 396 | return res.Err |
| 397 | case <-ctx.Done(): |
| 398 | return ctx.Err() |
| 399 | case <-timeoutC: |
| 400 | return xerrors.Errorf("tools reload timed out after %s: %w", timeout, context.DeadlineExceeded) |
| 401 | case <-m.ctx.Done(): |
| 402 | if err := m.closeErr(); err != nil { |
| 403 | return err |
| 404 | } |
| 405 | return m.ctx.Err() |
| 406 | case <-m.closedCh: |
| 407 | return ErrManagerClosed |
| 408 | } |
| 409 | } |
| 410 | |
| 411 | func (m *Manager) closeErr() error { |
| 412 | m.mu.RLock() |