Conversation
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 058a669. Configure here.
mjq
marked this pull request as ready for review
September 23, 2026 14:46
`GetFlamegraphFromCandidates`'s design: - create an unbuffered `results` channel - spin up a goroutine to dispatch one job per candidate (possibly a transaction profile or a continuous profile) to `jobs` (actually the global `readJobs` channel). Each job includes a reference to `results` so the result can be written back. - read from the `results` channel once per candidate and add its data to the flamegraph - return the flamegraph (This relies on an assumption that every job submitted to `readJobs` will write its result to `results`, which is handled elsewhere). There are two minor gaps: 1. Although the `unexpected result from storage` error is never expected to happen, it's an error and not a panic. But, it may result in a panic anyway: it will cause a `return`, which will trigger the deferred `close(results)`, which will panic the next time a `readJobs` worker finishes a job and tries to write to it. Even if we fixed the panic, we would still need to drain `results` to avoid blocking `readJobs` workers while they write their results. 2. The dispatch goroutine may not finish before `GetFlamegraphFromCandidates` finishes, for example when there are no candidates. To fix this issue and clarify the flow: - Completely drain `results` even if we get an unexpected error, so that we can't block the `readJobs` workers. We still return the error. - Don't `close(results)`. It isn't necessary for signalling (since we always read one result per submitted candidate) and closing it risks a panic if any worker writes after the receiver returns. - Wait for the dispatch goroutine to finish, ensuring both the goroutine and its dispatch span finish before `GetFlamegraphFromCandidates` returns.
mjq
force-pushed
the
mjq/flamegraph-concurrent-structure
branch
from
September 23, 2026 14:57
058a669 to
275a6e5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GetFlamegraphFromCandidates's design:resultschanneljobs(actually the globalreadJobschannel). Each job includes a reference toresultsso the result can be written back.resultschannel once per candidate and add its data to the flamegraph(This relies on an assumption that every job submitted to
readJobswill write its result toresults, which is handled elsewhere).There are two minor gaps:
unexpected result from storageerror is never expected to happen, it's an error and not a panic. But, it may result in a panic anyway: it will cause areturn, which will trigger the deferredclose(results), which will panic the next time areadJobsworker finishes a job and tries to write to it. Even if we fixed the panic, we would still need to drainresultsto avoid blockingreadJobsworkers while they write their results.GetFlamegraphFromCandidatesfinishes, for example when there are no candidates.To fix this issue and clarify the flow:
resultseven if we get an unexpected error, so that we can't block thereadJobsworkers. We still return the error.close(results). It isn't necessary for signalling (since we always read one result per submitted candidate) and closing it risks a panic if any worker writes after the receiver returns.GetFlamegraphFromCandidatesreturns.