-
Notifications
You must be signed in to change notification settings - Fork 948
Switch performance event traffic to transport endpoint #2593
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
Conversation
packages/performance/src/services/remote_config_service.test.ts
Outdated
Show resolved
Hide resolved
packages/performance/src/services/remote_config_service.test.ts
Outdated
Show resolved
Hide resolved
packages/performance/src/services/remote_config_service.test.ts
Outdated
Show resolved
Hide resolved
state === 'INSTANCE_STATE_UNSPECIFIED' || | ||
state === 'NO_TEMPLATE' | ||
) { | ||
if (NO_TEMPLATE_CONFIGS.shouldSendToTransport !== undefined) { |
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.
Since there is no risk of shouldSendToTransport being one of the js falsey values, we can drop the "!== undefined" in the checks.
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.
NO_TEMPLATE_CONFIGS.shouldSendToTransport
can be false as boolean value. If changing the check above into if (NO_TEMPLATE_CONFIGS.shouldSendToTransport)
, then this check will return false if shouldSendToTransport
is false. It will cause boolean value assignment inside the if
block being skipped. Please correct me if I was wrong understanding the comment. Thank you!
packages/performance/src/services/remote_config_service.test.ts
Outdated
Show resolved
Hide resolved
interface BatchEvent { | ||
message: string; | ||
eventTime: number; | ||
} | ||
|
||
/* eslint-disable camelcase */ | ||
// CC accepted log format. | ||
interface CcBatchLogFormat { | ||
// CC/Transport accepted log format. |
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.
Rather than "transport" let's call it Firelog to make it clear what it is.
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.
Happy to continue discussion on naming convention.
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.
+1 on changing it to Firelog.
Transport is a mechanism and Clearcut
and Firelog
are the different types of it IMO.
Note: If you plan to change it please update at other places as well to have the distinction between Transport
and Firelog
clear.
However, if you want to have it Transport for abstraction reason where other parts of the SDK doesn't need to care about what's the underlying technology is (Clearcut
, Firelog
etc) than I am OK with that with 2 caveats:
-
To external world (other parts of Web SDK) the API would be
sendEventsToTransport()
(or something along the lines) -
Internally (within this class) we need a way to know which transport mechanism are we using. I see the internal APIs doesn't talk about Firelog at all.
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.
After discussion, I have changed the name of Transport
to FL
to avoid confusion. Please take a look and see whether it makes sense to you. Thank you both!
Binary Size ReportAffected SDKs
Test Logs |
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.
Still reviewing...
@@ -301,5 +302,78 @@ describe('Performance Monitoring > perf_logger', () => { | |||
EXPECTED_NETWORK_MESSAGE | |||
); | |||
}); | |||
|
|||
it('skips performance collection if domain is cc', () => { |
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.
Why we want to skip the collection in this case?
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.
Fireperf automatically collects network request (including request to cc). However, to avoid infinite loop of network request collection (request to CC -> request is captured as performance resource -> another request to CC), if the domain is cc, then we will not collect the network request.
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.
Thanks James. Based on our offline discussion this is validating that we don't instrument Network Request to CC/FL sent by our own SDK.
Since it took a while to understand this scenario it would be good to add some documentation to make it clear.
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.
Thank you Raman! Added comments to explain that we don't instrument requests sent from SDK itself in both production code and test code.
'tp:/ieaeogn-agolai.o/1frlglgc/o' | ||
); | ||
|
||
transportKey = mergeStrings('AzSC8r6ReiGqFMyfvgow', 'Iayx0u-XT3vksVM-pIV'); |
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.
Since Web SDK is an Open Source project, I am wondering how difficult it would be for any intruder to crack our API?
Do we want to get a review from Firelog team to see if it's OK to expose this API Key even if it's juggled (considering the encoding logic is also public, so anyone can decode it very easily)?
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.
Storing plain text key on GitHub will automatically trigger alert to the owner, therefore we cannot store plain text key directly. Current approach is to align with mobile SDK change for interleave encoding. We have previously confirmed with the team for this approach.
interface BatchEvent { | ||
message: string; | ||
eventTime: number; | ||
} | ||
|
||
/* eslint-disable camelcase */ | ||
// CC accepted log format. | ||
interface CcBatchLogFormat { | ||
// CC/Transport accepted log format. |
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.
+1 on changing it to Firelog.
Transport is a mechanism and Clearcut
and Firelog
are the different types of it IMO.
Note: If you plan to change it please update at other places as well to have the distinction between Transport
and Firelog
clear.
However, if you want to have it Transport for abstraction reason where other parts of the SDK doesn't need to care about what's the underlying technology is (Clearcut
, Firelog
etc) than I am OK with that with 2 caveats:
-
To external world (other parts of Web SDK) the API would be
sendEventsToTransport()
(or something along the lines) -
Internally (within this class) we need a way to know which transport mechanism are we using. I see the internal APIs doesn't talk about Firelog at all.
): Promise<void> { | ||
// Gradually rollout traffic from cc to transport using remote config. | ||
if (SettingsService.getInstance().shouldSendToTransport) { | ||
return sendEventsToTransport(data, staged); |
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.
FYI: https://github.com/firebase/firebase-js-sdk/pull/2593/files#r403797030
One example is this.
function getHashPercent(seed: string): number { | ||
let hash = 0; | ||
for (let i = 0; i < seed.length; i++) { | ||
hash = (hash << 3) + hash - seed.charCodeAt(i); |
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.
Any reference to where we chose to pick this logic? I think good to callout the source for this one.
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.
Added comment to call out the source.
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.
Am I missing something? I still don't see the reference link to the algorithm.
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.
This is at the function comment: Implementation from String.hashCode() in Java.
. This will keep the comment concise and we can find reference online.
if (iid.length === 0) { | ||
return false; | ||
} | ||
return getHashPercent(iid) < rolloutPercent; |
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.
Should we check for the rolloutPercent ranges?
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.
SDK will honor the percentage because we don't perform special handling if it is out of valid range, backend can inspect and control flag value if this is not correct.
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.
Sure, even if BE does that, having a range check would make the SDK cleaner.
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.
Currently we don't have range check for all RC fetch result. We can add them but I don't expect SDK to handle this differently if the value is out-of-range, therefore not adding additional check for now and revisit it in the future.
'Custom metric name {$customMetricName} is invalid' | ||
'Custom metric name {$customMetricName} is invalid', | ||
[ErrorCode.INVALID_STRING_MERGER_PARAMETER]: | ||
'Input for String merger is invalid' |
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.
This is quite a cryptic message for the developers. Can we make this message a bit more contextual? Eg. Unable to form API Key/URL?
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.
This message is not planned for developers to resolve by themselves, it is useful to identify the issue quickly when developer takes this message to Firebase customer support.
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.
Sure, but still the developer looking at that message would be confused as to how to act on that message.
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.
Added more information to let developer know about the next step.
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.
Overall it looks good to me except for the URL API usage.
Will we eventually replace cc with fl? The perf SDK is very sensitive to size and this PR increases it (It'd be interesting to see the actual increase in percentage - Currently the size check is broken for this PR, but I will fix it so we can get the number).
|
||
// Do not log the js sdk's call to transport service domain to avoid unnecessary cycle. | ||
// Need to blacklist both old and new endpoints to avoid migration gap. | ||
const networkRequestHostName = new URL(networkRequest.url).hostname; |
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.
URL API is not available in IE11. Are you able to just use string parsing? I'm reluctant to ask people to add an additional polyfill unless there is a strong reason.
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.
Thank you for the heads-up! Decided not to use URL API and match the full URL without search parameter for cc and fl endpoints.
/** | ||
* True if event should be sent to Fl transport endpoint rather than CC transport endpoint. | ||
* rolloutPercent is in range [0.0, 100.0]. | ||
* @param {string} iid Installation ID which identifies a web app installed on client. |
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.
no need to specify the parameter type in Typescript
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.
Removed parameter type from comments.
Thank you Fei! I have removed the URL API usage. We are expecting to remove cc usage completely after 2 releases. Expecting the SDK size to decrease by then. |
@@ -271,9 +271,6 @@ function shouldLogAfterSampling(samplingRate: number): boolean { | |||
/** | |||
* True if event should be sent to Fl transport endpoint rather than CC transport endpoint. | |||
* rolloutPercent is in range [0.0, 100.0]. | |||
* @param {string} iid Installation ID which identifies a web app installed on client. |
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.
hm, actually I suggested to only remove the type information in the comment, that is e.g. {string}
, and we should keep the rest of the comments.
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.
Thanks for the callout! I overlooked your message about parameter type
instead of parameter
.
1. If hash < rollout percentage, send to transport.
2. If hash >= rollout percentage, send to cc.