setting: introduce setting classes#73937
Conversation
catj-cockroach
left a comment
There was a problem hiding this comment.
Reviewed 162 of 162 files at r1, all commit messages.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on @ajwerner, @dt, and @knz)
| // TenantWritable settings are visible to and can be modified by non-system | ||
| // tenants. The system can still override these settings; the overrides are | ||
| // propagated from the host cluster. | ||
| TenantWritable |
There was a problem hiding this comment.
just curios: is the purpose of this API change to ensure that each cluster setting is annotated with appropriate scope and that there is no way to forget to do so, like it'd be possible if "WithSystemOnly" was augmented with WithTeanantReadonly?
Have we considered linters perhaps to ensure that With* always applied when registering settings to enforce that (as an alternative to this change)?
Is it possible that at some point we would want to express more complex class of settings (perhaps TennantWritable that's not a System visible or overridable)? Seems like the "With*" approach might be more flexible...
|
Is there really a class-difference between TenantReadOnly and TenantWritable in code? isn't just sticking an override in the overrides table on the host cluster sufficient to make any setting TenantReadOnly? |
RaduBerinde
left a comment
There was a problem hiding this comment.
Is there really a class-difference between TenantReadOnly and TenantWritable in code? isn't just sticking an override in the overrides table on the host cluster sufficient to make any setting TenantReadOnly?
There will be a difference when there is no override. Having to maintain server-side overrides for all settings that we really don't want tenants to change (e.g. tenant_cpu_usage_allowance) is more error-prone. Also, these classes better document the expected usage.
Reviewable status:
complete! 1 of 0 LGTMs obtained (waiting on @ajwerner, @dt, @knz, and @miretskiy)
pkg/settings/setting.go, line 106 at r1 (raw file):
Previously, miretskiy (Yevgeniy Miretskiy) wrote…
just curios: is the purpose of this API change to ensure that each cluster setting is annotated with appropriate scope and that there is no way to forget to do so, like it'd be possible if "WithSystemOnly" was augmented with
WithTeanantReadonly?Have we considered linters perhaps to ensure that With* always applied when registering settings to enforce that (as an alternative to this change)?
Is it possible that at some point we would want to express more complex class of settings (perhaps TennantWritable that's not a System visible or overridable)? Seems like the "With*" approach might be more flexible...
Yes, it is to force you to think about the proper class whenever you add a setting. What would be the advantage of forcing use of .WithSomething() with a linter? This syntax is cleaner and more concise.
Generally the .WithSomething() things should be used when there is a reasonable default (preferably that's used for most settings).
Adding more classes should be similar with both patterns. I don't see us having "parameterized" classes that require arguments (though you could make that work in this register-against-the-class model too).
Well, I can think of few cases. For one, it's not changing the existing API, so, the familiar usage patterns
Well, I guess that was the crux of my question. I prefer With because it maintains status quo (wrt to the APIs -- just one builder like pattern), but I understand the need to document the type of setting... So, I suggested a linter. But come to think, if you're changing 100s of call sites anyway, why not just have an argument for settings class when registering? RegisterBoolSetting(settings.ForTenant, ...)? |
|
I'm pretty strongly against using With for non-optional arguments (imagine if we used that pattern for eg the description). I started with the plan to make it an argument, but thought this way was nicer (and more concise, only one "settings."). Obviously it is subjective, and I don't mind switching if folks prefer an argument. But I'd like to understand why do you prefer it? Is calling against the class confusing / too magicy? As a general note, when suggesting an alternative, you should say why you prefer it rather than asking "why not?" :) |
b825315 to
b84f52d
Compare
RaduBerinde
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner, @catj-cockroach, @dt, @knz, and @miretskiy)
docs/RFCS/20211106_multitenant_cluster_settings.md, line 220 at r1 (raw file):
Previously, dt (David Taylor) wrote…
apologies for this off-topic drive-by comment, that is also late and should have been raised on the RFC (so feel free to just hit "Resolve Converation" here if this is too off-topic for this pr), but should't this "when in doubt the first choice" be
tenant-rw, nottenant-ro? like, by default a tenant should have the same controls and capabilities as any other user over the behavior of their cluster, and we should only reach for the more restrictive ones, that apply to tenants differently than non-tenants, when we need them, right? particularly in the the world where we can override from host with a value at runtime if we need to with no code change, even if it is tenant-rw in the code?
Agreed, I think I wrote that before we added overrides for all of them.
Allow me to disagree. I think this PR proposes an alternative mechanism to already well established pattern of using Few more reasons (some stylistical) for me are:
At any rate, I already gave LG -- so, it's more about understanding why we haven't used existing mechanisms. |
|
It was agreed (as part of the RFC) that the class would be mandatory when defining a setting, so that IMO rules out the With mechanism which is designed for optional modifiers. As for using an argument, those are reasonable points; thanks for spelling them out. I am ok switching to an argument but I want to hear what @dt, @knz, @ajwerner think before I go back modifying 500 call sites. |
No strong opinions -- I suppose if I have to choose, I have mild preference for a regular required function argument vs the receiver factories. (while aesthetically it feels like it'd go after description, putting it first, before the name arg, could keep this a simple find/replace, since we'd just need to put |
|
Right, the proposed change is: - intervalBaseSetting = settings.TenantWritable.RegisterFloatSetting(
+ intervalBaseSetting = settings.RegisterFloatSetting(
+ settings.TenantWritable,
intervalBaseSettingKey,
"the base multiplier for other intervals such as adopt, cancel, and gc",
defaultIntervalBase, |
b84f52d to
00d9fac
Compare
|
Ok, I updated the change to pass the class as the first argument. |
This commit introduces the three setting classes in the RFC (cockroachdb#73349): `SystemOnly`, `TenantReadOnly`, and `TenantWritable`. The `SystemOnly` class replaces the existing `WithSystemOnly()`. In this change we don't yet implement the advertised semantics. We mechanically use `TenantWritable` for all settings except those that were using `WithSystemOnly()` which use `SystemOnly`; this should not change any existing behavior. The classes will be revisited in a separate change, after we implement the semantics. Release note: None
00d9fac to
52c2df4
Compare
knz
left a comment
There was a problem hiding this comment.
Reviewed 1 of 1 files at r2, 154 of 156 files at r3, 2 of 2 files at r4, all commit messages.
Reviewable status:complete! 2 of 0 LGTMs obtained (waiting on @ajwerner, @dt, and @miretskiy)
|
TFTRs! bors r+ |
|
Build succeeded: |
This commit introduces the three setting classes in the RFC (#73349):
SystemOnly,TenantReadOnly, andTenantWritable. TheSystemOnlyclass replaces the existing
WithSystemOnly().In this change we don't yet implement the advertised semantics. We
mechanically use
TenantWritablefor all settings except those thatwere using
WithSystemOnly()which useSystemOnly; this should notchange any existing behavior. The classes will be revisited in a
separate change, after we implement the semantics.
Release note: None