-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signals sampling #1166
Signals sampling #1166
Conversation
🦋 Changeset detectedLatest commit: b8c6586 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@silesky does this method of cancelling signals make sense? Should the plugin be deregistered too? |
@@ -83,6 +83,12 @@ export class Signals implements ISignals { | |||
* - Registers custom signal generators. | |||
*/ | |||
async start(analytics: AnyAnalytics): Promise<void> { | |||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This stuff would be better suited toAnalyticsService
. i.e. have an analyticsService.signalsDisabled()
?
The analyticsService class is a mean to be a facade
to abstract away cdnSettings or analytics instance related logic, exposing that to our domain -- for testing, and to keep this initialization stuff tidier.
if ( | ||
!analytics.settings.cdnSettings.autoInstrumentationSettings || | ||
Math.random() > | ||
analytics.settings.cdnSettings.autoInstrumentationSettings.sampleRate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, I don't understand this Math.random() thing, maybe you could explain? I assumed we would just do:
analytics.settings.cdnSettings.autoInstrumentationSettings.sampleRate === 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a sample rate from [0,1] that we "roll against" to see if we should send signals or not (not just a boolean in the settings)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- If the sample rate is 0, we just want to stop from sending signals to Segment, right? We don't want to stop processing them. This early return will abort the entire signals initialization, so we don't send signals but we also won't process (create events) from them.
- The disabling of Signals completely (i.e. analytics.settings.cdnSettings.autoInstrumentationSetting) should probably not be in scope? Seems like a seperate scenario potentially?
* A sample rate to determine what percentage of sessions should send signals, from [0,1] | ||
*/ | ||
sampleRate: number | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd need a changeset for both signals and analytics =)
@danieljackins can we have a test / maybe an integration test for this? |
ab42130
to
cf6480d
Compare
this.setSignalIngestion(initialValue) | ||
} | ||
|
||
// setting ?segment_signals_debug=true will disable redaction, and set a key in local storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can probably delete this comment?
// this setting will persist across page loads (even if there is no query string) | ||
// in order to clear the setting, user must set ?segment_signals_debug=false | ||
const debugModeInQs = parseDebugModeQueryString() | ||
logger.debug('debugMode is set to true via query string') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need need to log this twice ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah sorry I'm going to refactor the whole debug part still
constructor(settings: SignalsIngestSettingsConfig) { | ||
this.flushAt = settings.flushAt ?? 5 | ||
this.apiHost = settings.apiHost ?? 'signals.segment.io/v1' | ||
this.flushInterval = settings.flushInterval ?? 2000 | ||
this.shouldDisableSignalRedaction = | ||
settings.shouldDisableSignalRedaction ?? (() => false) | ||
this.signalIngestion = settings.signalIngestion ?? (() => false) | ||
this.sampleRate = settings.sampleRate ?? 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, I don't think we want to expose sampleRate publicly, as it's strictly an implementation detail -- IMO, you shouldn't be able to customize the sample rate as a setting. Can we abstract this way completely as part of this.signalsIngestion? the sampleRate should be used to completely disable signals ingestion for a current user -- so it's basically about whether or not to send signals at all for a given session -- not something we recalculate everytime a new event comes through.
@@ -69,10 +75,25 @@ export class SignalsIngestClient { | |||
return analytics | |||
} | |||
|
|||
private shouldIngestSignals(): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we don't want to calculate this on a per event basis -- see comment above.
Plan Error
|
@@ -79,58 +93,80 @@ export class SignalGlobalSettings { | |||
* Add new URLs to the disallow list | |||
*/ | |||
disallowListURLs: (string | undefined)[] | |||
/** | |||
* Sample rate to determine sending signals | |||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this | undefined / optional, so update can be used atomically (one day?)
]) | ||
|
||
await waitForCondition( | ||
() => indexPage.signalsAPI.getEvents('interaction').length > 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is and everything below it is needed -- as long as signals api has flushed, test is good!
yarn changeset
. Read about changesets here).