Skip to content

diag: label agent goroutines with their aria id - #19

Open
jack-work wants to merge 1 commit into
mainfrom
perf/pprof-aria-labels
Open

jack-work wants to merge 1 commit into
mainfrom
perf/pprof-aria-labels

Conversation

@jack-work

Copy link
Copy Markdown
Owner

Independent of the rest of the stack; branches off main.

Why

A hung daemon is diagnosed from a goroutine dump. Ours was unattributable — eighty goroutines, a dozen of them agents, every agent stack byte-identical:

goroutine 1406 [sync.Cond.Wait, 4 minutes]:
  actor.(*Queue[...]).Recv
  figaro.(*Inbox).Recv
  figaro.(*Agent).act            agent.go:948
  figaro.(*Agent).actProtected   agent.go:941
  figaro.(*Agent).runWithRecovery

…and no way to tell which one belonged to the aria that was not answering. Diagnosing a real stall meant guessing from goroutine ages and correlating against timestamps in another file.

What

pprof.Do costs a map on one goroutine, and the label is inherited by every goroutine that one spawns: the turn loop, the tool dispatcher, the provider's stream reader. So the entire subtree of a stuck turn names itself — which is the case that matters, since the interesting frame is never the agent loop but whatever it is blocked inside three levels down.

go tool pprof -tagfocus=figaro.aria=94f0752b ...
curl --unix-socket .../pprof.sock 'http://x/debug/pprof/goroutine?debug=1'

Gotcha, documented in the comment

Labels render in debug=1. They do not render in the debug=2 full stack dump, which is the one people reach for first.

A hung daemon is diagnosed from a goroutine dump. Ours was unattributable:
eighty goroutines, a dozen of them agents, every agent stack byte-identical
(actor.Queue.Recv <- Inbox.Recv <- act <- actProtected <- runWithRecovery),
and no way to tell which one belonged to the aria that was not answering.
Diagnosing a real stall meant guessing from goroutine ages and correlating
against timestamps in another file.

pprof.Do costs a map on one goroutine, and the label is INHERITED by every
goroutine that one spawns: the turn loop, the tool dispatcher, the provider's
stream reader. So the entire subtree of a stuck turn names itself, which is
the case that matters - the interesting frame is never the agent loop, it is
whatever the agent is blocked inside three levels down.

Labels render in /debug/pprof/goroutine?debug=1 and in `go tool pprof
-tagfocus=figaro.aria`. They do NOT render in the debug=2 full stack dump,
which is the one people reach for first; the comment says so.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant