Skip to content
This repository has been archived by the owner on Aug 30, 2019. It is now read-only.

Make Backend a MemoryBackend of a Backend interface #362

Merged
merged 2 commits into from
Feb 20, 2018

Conversation

LotharSee
Copy link

Make Backend an interface.
It should make the code more explicit about what it exposes, and will allow a better reusability/flexibility.

Copy link
Contributor

@gbbr gbbr left a comment

Choose a reason for hiding this comment

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

Looks good, just some minor documentation and styling comments...

CountSignature(signature Signature)

// GetTotalScore returns the TPS of all traces ingested
GetTotalScore() float64
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be awesome if we could rid ourselves of the Get* prefix for these methods. In "Effective Go" you can see in the corresponding section that it is advised to not use this prefix in Go. Unless there is a good reason for it, would be great to remove it.

Copy link
Author

Choose a reason for hiding this comment

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

Absolutely and that's my plan ; I don't wanted to mix goals so I wanted to keep it for a future PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

If you want, I am happy to make these changes for you within this PR.

// GetAllSignatureScores returns the TPS of traces ingested for all signatures
GetAllSignatureScores() map[Signature]float64

// get the number of different signatures seen
Copy link
Contributor

Choose a reason for hiding this comment

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

Please start the documentation name with the name of the method, e.g.:

GetCardinality returns the number of distinct signatures seen.

GetSampledScore() float64
// GetUpperSampledScore is similar to GetSampledScore, but with the upper approximation
GetUpperSampledScore() float64
// GetSignatureScore returns the TPS of traces ingested of a given signature
Copy link
Contributor

@gbbr gbbr Feb 19, 2018

Choose a reason for hiding this comment

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

Unless the TPS concept is explained elsewhere in another doc, I think it would be great to say "traces per second" instead of TPS here, at least once.


// CountSample counts that 1 trace is going through the sampler
CountSample()
// CountSignature counts that 1 signature is going through the sampler
Copy link
Contributor

Choose a reason for hiding this comment

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

In some places throughout the definition of this interface you've left a blank line between the method and the documentation of the next method. Please try and keep consistency. As a personal preference I prefer to have the blank line, but you can chose whichever version you like as long as it's consistent (ideally throughout the package but at the minimum on the interface level).

Copy link
Author

Choose a reason for hiding this comment

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

Right, they were grouped by "nature", but that's not explicit and a bit arbitrary.

b.totalScore /= b.decayFactor
b.sampledScore /= b.decayFactor
b.mu.Unlock()
// Backend stores and count traces and signatures ingested by a sampler
Copy link
Contributor

Choose a reason for hiding this comment

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

s/count/counts

Would be awesome if we could end each sentence with a period.

func (b *MemoryBackend) CountSignature(signature Signature) {
b.mu.Lock()
b.scores[signature]++
b.totalScore++
Copy link
Contributor

Choose a reason for hiding this comment

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

You could use sync/atomic both here and in the method below.

Copy link
Author

Choose a reason for hiding this comment

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

Right, the use of atomic could be considered for most of the unique counters of the MemoryBackend. I don't want to mix purposes in this PR but that's certainly something which could be addressed (with benchmarks?) in future work.


// GetSignatureScore returns the score of a signature.
// It is normalized to represent a number of signatures per second.
func (b *MemoryBackend) GetSignatureScore(signature Signature) float64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be simplified without the local variable, but I don't feel strongly about it:

b.mu.RLock()
defer b.mu.RUnlock()

return b.scores[signature] / b.countScaleFactor

Copy link
Contributor

Choose a reason for hiding this comment

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

You may do the same in all the below methods to get rid of the extra local variable.

Copy link
Author

Choose a reason for hiding this comment

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

I have no strong opinion either.
At some places we aren't using defer, and from what I recall it isn't to micro-optimize but mostly because they are trivial situations that don't require it.
I'll be fine if we change it in a way or another in the future.

// GetSignatureScore returns the TPS of traces ingested of a given signature
GetSignatureScore(signature Signature) float64
// GetAllSignatureScores returns the TPS of traces ingested for all signatures
GetAllSignatureScores() map[Signature]float64
Copy link
Contributor

Choose a reason for hiding this comment

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

It think it would be no problem nor would it make it more confusing to remove "All" from this name.


// GetCardinality returns the number of different signatures seen recently.
func (b *MemoryBackend) GetCardinality() int64 {
b.mu.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this was meant to be a "read lock".

Copy link
Author

Choose a reason for hiding this comment

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

Good catch!

b.mu.Lock()
for sig := range b.scores {
score := b.scores[sig]
if score > b.decayFactor*minSignatureScoreOffset {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since you only use score here, on this condition, it might be easier as:

if score := b.scores[sig]; score > b.decayFactor*minSignatureScoreOffset {

...or even not having it at all

Copy link
Contributor

@gbbr gbbr left a comment

Choose a reason for hiding this comment

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

Thank you Benjamin. I'm approving this as being checked for code quality and as a gross review. A second, deeper technical review should be done by someone else.

@LotharSee LotharSee force-pushed the benjamin/sampler-backend-interface branch from 6d2757a to e94ef0c Compare February 19, 2018 12:38
@LotharSee LotharSee merged commit e94ef0c into master Feb 20, 2018
@dtilghman dtilghman deleted the benjamin/sampler-backend-interface branch February 21, 2018 05:17
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.

2 participants