Skip to content
This repository has been archived by the owner on May 23, 2024. It is now read-only.

Fix the RemotelyControlledSampler so that it terminates go-routine on Close() #260

Conversation

skidder
Copy link
Contributor

@skidder skidder commented Feb 1, 2018

Fixes #259

Signed-off-by: Scott Kidder [email protected]

skidder and others added 4 commits January 31, 2018 20:35
…o-routine terminate when Close() is called

Signed-off-by: Scott Kidder <[email protected]>
Signed-off-by: Yuri Shkuro <[email protected]>
Signed-off-by: Yuri Shkuro <[email protected]>
@codecov
Copy link

codecov bot commented Apr 3, 2018

Codecov Report

Merging #260 into master will increase coverage by 0.49%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #260      +/-   ##
==========================================
+ Coverage   85.75%   86.25%   +0.49%     
==========================================
  Files          54       55       +1     
  Lines        2850     2968     +118     
==========================================
+ Hits         2444     2560     +116     
- Misses        285      287       +2     
  Partials      121      121
Impacted Files Coverage Δ
sampler.go 93.85% <100%> (+0.86%) ⬆️
internal/baggage/remote/restriction_manager.go 95.77% <0%> (-1.41%) ⬇️
config/config.go 92.91% <0%> (-1.16%) ⬇️
config/options.go 100% <0%> (ø) ⬆️
transport_udp.go 92.59% <0%> (ø) ⬆️
config/config_env.go 100% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c107110...f42b85e. Read the comment docs.

var wg sync.WaitGroup
wg.Add(1)
s.doneChan <- &wg
wg.Wait()
Copy link
Contributor

@vprithvi vprithvi Apr 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general, is there an advantage to waiting for the poller update to complete? (Wouldn't it be gc'd with simply with the return on L493?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a pattern we used in several places. The main objective is to ensure that the poller GR is about to exit and is guaranteed to not do any work, for example by receiving another ticket update and performing sampler update. We may not need this guarantee here, but I would leave it for symmetry with the remote reporter.

If such guarantee was not needed, a simpler pattern is to close the doneChan and not wait for the GR to report readiness to exit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation!

From my understanding of select case, only one case can be selected at a time. Selecting the case with doneChan would result in the GR cleanly returning without doing any additional work and maintaining the guarantee, no?

Is symmetry at the cost of additional complexity important?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

select runs in a loop in a different GR from the one that calls Close(). Without a barrier Close may return prior to the loop GR exiting, so if any tests rely on having no updates after a call to Close we might break them.

I am not adding new complexity, the wait group was already in the implementation. I think my change makes that implementation simpler by localizing several vars that were previously spread out in different methods (like the ticket and the wait group itself). It also makes Close safe to call >1, something that we've seen people had trouble with in the reporter.

@yurishkuro yurishkuro merged commit 996debd into jaegertracing:master Apr 4, 2018
}
}

func (s *RemotelyControlledSampler) getSampler() Sampler {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not following - what is your point?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/s/getSampler()/sampler() is the supposed "go way"

manager: &httpSamplingManager{serverURL: options.samplingServerURL},
doneChan: make(chan *sync.WaitGroup),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Most other times we've done this, we created a empty chan (chan struct{}) and closed it inside Close() and had the pollControllerWithTicker intercept the closing of the chan and then calling s.wg.Done() vs sending the actual wg inside chan to the go routine. Both work but I've not seen it done this way anywhere inside our codebase.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remote reporter uses similar pattern to this one, it sends a command to the channel and the command contains a WG. I think this is a better pattern than having WG as a member variable (leaking its scope unnecessarily).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants