ref(relay): Stop sending unnecessary fields in project config#45124
ref(relay): Stop sending unnecessary fields in project config#45124
Conversation
Some fields that are not being sent by Sentry when they are empty are serialized by Relay. Align with Sentry and do not serialize these fields if they have default values. Reasons: * The main reason is that #1860 introduced a validation function that can be used Sentry-side to check if Sentry accidentally produces any fields that Relay cannot use. This has already surfaced some inconsistencies (see getsentry/sentry#45124), but it requires that Sentry and Relay produce the same fields. * Reduced payload size when sending configs to downstream Relays.
| return [] | ||
| else: | ||
| for rule in rules: | ||
| rule.pop("active") |
| ), | ||
| "end": datetime.utcfromtimestamp( | ||
| boosted_release.timestamp + boosted_release.platform.time_to_adoption | ||
| ).strftime(self.date_format), |
There was a problem hiding this comment.
This change is not necessary functionally, but it makes sure that Relay's serialized project config look the same as Sentry's serialized project config.
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #45124 +/- ##
==========================================
- Coverage 80.22% 80.15% -0.07%
==========================================
Files 4724 4725 +1
Lines 198815 198865 +50
Branches 12006 12006
==========================================
- Hits 159506 159408 -98
- Misses 39047 39195 +148
Partials 262 262
|
…to test/validate-project-config
…to test/validate-project-config
|
|
||
| class BoostLatestReleasesRulesGenerator(BiasRulesGenerator): | ||
|
|
||
| date_format = "%Y-%m-%dT%H:%M:%SZ" |
There was a problem hiding this comment.
nit
| date_format = "%Y-%m-%dT%H:%M:%SZ" | |
| datetime_format = "%Y-%m-%dT%H:%M:%SZ" |
| class Rule(ActiveRule): | ||
| active: bool |
There was a problem hiding this comment.
I don't really like this change. I understand the practicality, but this says a rule is a type of an active rule. Same with ActiveDecayingRule below.
There was a problem hiding this comment.
I wouldn't know how to change this, except maybe by improving the names. This type's fields are a superset of the other type's, which is solved by inheritance.
There was a problem hiding this comment.
The naming here confuses me, especially considering we have inheritance in place. I would do something like this:
class Rule(TypedDict):
samplingValue: SamplingValue
type: str
condition: Condition
id: int
class StatefulRule(Rule):
active: boolWhat do you think?
src/sentry/relay/config/__init__.py
Outdated
| # Sort extractMetrics to be consistent with Relay serialization: | ||
| metrics.sort() |
There was a problem hiding this comment.
nit: I'm not sure if this is a good change. I don't think having the same order as what relay serializes is important; and if this is for tests, that's something tests should care about (not prod).
There was a problem hiding this comment.
Agreed, moved the sorting to tests now.
| else: | ||
| for rule in rules: | ||
| rule.pop("active") # type: ignore |
There was a problem hiding this comment.
active should just not be added to rules, instead of generating it and removing it later. I understand, however, that this may be out of the scope of your PR.
There was a problem hiding this comment.
I agree, but I found it hard to follow in what places it was still needed, so I went for this hack instead. @iambriccardo maybe you can improve on this in a follow-up PR if you have time.
There was a problem hiding this comment.
Inside rules/biases/ you can find all the rules formats, you can easily remove active from them. To my understanding of Relay sampling, the active field is unused.
There was a problem hiding this comment.
# src/sentry/dynamic_sampling/rules/biases/boost_latest_releases_bias.py
class BoostLatestReleasesRulesGenerator(BiasRulesGenerator):
def _generate_bias_rules(self, bias_data: BiasData) -> List[PolymorphicRule]:
boosted_releases = bias_data["boostedReleases"]
return cast(
List[PolymorphicRule],
[
{
"samplingValue": {
"type": "factor",
"value": bias_data["factor"],
},
"type": "trace",
"active": True, # Remove this here
...
tests/sentry/dynamic_sampling/rules/biases/test_boost_latest_releases_bias.py
Show resolved
Hide resolved
|
|
||
|
|
||
| def generate_rules(project: Project) -> List[PolymorphicRule]: | ||
| def generate_rules(project: Project) -> Sequence[PolymorphicActiveRule]: |
There was a problem hiding this comment.
Why would you change the return to a Sequence? Is there a specific reasoning?
There was a problem hiding this comment.
mypy started complaining because List is invariant while Sequence is covariant (docs). With your suggestion to just remove active, I was able to revert this change though.
iambriccardo
left a comment
There was a problem hiding this comment.
I am a bit confused of why we are keeping the active field in the TypedDicts definition. The active field should be removed and that shouldn't cause any issues.
| class Condition(TypedDict): | ||
| op: str | ||
| inner: List[Inner] | ||
| op: Literal["and", "or"] |
| class Rule(ActiveRule): | ||
| active: bool |
There was a problem hiding this comment.
The naming here confuses me, especially considering we have inheritance in place. I would do something like this:
class Rule(TypedDict):
samplingValue: SamplingValue
type: str
condition: Condition
id: int
class StatefulRule(Rule):
active: boolWhat do you think?
@iambriccardo You are right, I thought it was being used internally but I confused it with |
@jjbayer you are free to remove it also from the hash. The role of the hash is just to maintain an in-memory map to calculate rules diffs for logging purposes. Considering that the hash is recreated on deployment, we won't have any issues. |
iker-barriocanal
left a comment
There was a problem hiding this comment.
🚀
I'm curious how many GB (and $) we save with this PR 👀.
Make sure that the project configs that Sentry generates are consistent with what Relay serializes for downstream usage:
activefield, so stop sending it.globsampling rules do not have options, so stop sending them.Why?
Note: This PR will fail a lot of tests until getsentry/relay#1887 has been merged and released to the Python library.