-
Notifications
You must be signed in to change notification settings - Fork 15
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
Use remote limit as ceiling for network call limits and apply consistently #78
Conversation
Current dependencies on/for this PR: This stack of pull requests is managed by Graphite. |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #78 +/- ##
==========================================
+ Coverage 75.92% 76.03% +0.10%
==========================================
Files 313 313
Lines 10114 10097 -17
Branches 1461 1455 -6
==========================================
- Hits 7679 7677 -2
+ Misses 1843 1832 -11
+ Partials 592 588 -4
|
for (domain in local?.networking?.domains ?: return null) { | ||
if (domain.domain != null && domain.limit != null) { | ||
mergedLimits[domain.domain] = domain.limit | ||
val limitCeiling = getLimitCeiling() |
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.
The algo is:
- Use the remote settings as a base
- For domains where there is both a local and remote entry, apply the local setting per domain if the local limit is smaller than the remote one
- For domains with only a local entry, apply the local setting or the ceiling as defined by the default limit set on the remote, which ever is smaller.
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.
Consider leaving as a comment in the code?
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.
Good idea
|
||
private val untrackedNetworkCallCount = AtomicInteger(0) | ||
|
||
private var defaultPerDomainCallLimit = configService.networkBehavior.getNetworkCaptureLimit() |
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 want to maintain the same limits for each session, so we get it at init time, and update when we reset the service when the session ends. Previously, this is pulled every time at run time, and we can get into inconsistent states in the middle of a session if new remote limits are fetched.
} | ||
return | ||
} else if (!domainSetting.containsKey(domain)) { | ||
createLimitForDomain(domain) |
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 the fetching of the domain limits here to run before we record a network request. It was doing it after and I have no idea why.
logger.logDeveloper("EmbraceNetworkLoggingService", "no domain settings") | ||
storeNetworkCall(callId, networkCall) | ||
// Not sure how this is possible, but in case it is, limit logged logs where we can't figure out the settings to apply | ||
if (untrackedNetworkCallCount.getAndIncrement() < defaultPerDomainCallLimit) { |
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 should never happen so I don't know how to test it, but I've added code to catch and limit this in case it happens - it wasn't limiting that before.
Another option is just to ditch it like if we can't find a domain (which probably prevents this block from every running tbh), but this seems safer and who knows what funny refactoring in the future will bring. Safety first I guess.
) | ||
} | ||
} | ||
} | ||
|
||
private fun storeSettings(url: String) { | ||
private fun createLimitForDomain(domain: 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.
The old implementation is really wasteful in that it rebuild the domain limits map at every call, often unnecessarily. So we build and cache it for reuse at init time and redo it when the session ends instead.
@@ -68,8 +74,6 @@ | |||
logger.logError(msg, IllegalStateException(msg), true) | |||
} | |||
|
|||
// clear calls per domain and session network calls lists before be used by the next session |
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.
Lol is one line is probably the most important change in the PR. We were resetting this every time a session payload is built, which effectively nerfs the limit.
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.
Periodic session caching strikes again 💥
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.
LGTM
for (domain in local?.networking?.domains ?: return null) { | ||
if (domain.domain != null && domain.limit != null) { | ||
mergedLimits[domain.domain] = domain.limit | ||
val limitCeiling = getLimitCeiling() |
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.
Consider leaving as a comment in the code?
@@ -68,8 +74,6 @@ | |||
logger.logError(msg, IllegalStateException(msg), true) | |||
} | |||
|
|||
// clear calls per domain and session network calls lists before be used by the next session |
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.
Periodic session caching strikes again 💥
Goal
There were two problems that were addressed in this PR:
This PR addresses both issues by using the default limits in the remote config (or defaults implied by the absence of a config) to act as the ceiling to whatever is set locally. This make the local setting a way of further limit what is set on the remote, and won't allow the overriding of it. I also removed the erroneous limit clearing, which ironically is probably the source of the original customer issue anyway, just obscured by what I found with the local limits
Testing
Added more test cases to verify the fixed behaviour as well as corner cases not covered previously
Release Notes
WHAT:
Properly enforce network call per session limit and use the remote limit as a ceiling for any local limits set.
WHY:
Limiting the number of session calls recorded prevents session payloads from growing to an unhealthy size.