Skip to content
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

spanconfig: teach the KVAccessor about system span configurations #76414

Merged
merged 2 commits into from
Feb 15, 2022

Conversation

arulajmani
Copy link
Collaborator

@arulajmani arulajmani commented Feb 11, 2022

First 3 commits are from #76219, this one's quite small -- mostly just tests.


This patch teaches the KVAccessor to update and get system span
configurations.

Release note: None

@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Contributor

@irfansharif irfansharif left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (looked at only the last commit here).

@@ -32,6 +32,10 @@ import (
// and "end" keys.
var spanRe = regexp.MustCompile(`^\[(\w+),\s??(\w+)\)$`)

// systemTargetRe matches strings of the form
// "{source=(<id>|system),target=(<id>|system)}".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify the grammar to drop "system". There are already too many "system" in our vocabulary and here used for two different meanings ("system tenant" and "system target"); there's no difference between tenant-id==1 and system, and the test cases render them differently. It would help simplify your parser below. I'd be ok exporting it now too (ParseSystemTarget) like we do for everything else -- we are going to use something like it in spanconfig.store tests shortly anyway.

default:
t.Fatalf("expected %s to match span or system target regex", target)
}
return spanconfig.Target{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could panic instead of this confusing return.

case target.IsSystemTarget():
return printSystemTarget(target.GetSystemTarget())
default:
t.Fatalf("unknown traget type")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: traget. Could panic below instead of the empty string return.

// Duplicate in toDelete with some span targets.
toDelete: []spanconfig.Target{
spanconfig.MakeTargetFromSpan(roachpb.Span{Key: roachpb.Key("a"), EndKey: roachpb.Key("c")}),
makeTenantClusterTarget(roachpb.SystemTenantID.InternalValue),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Applies to earlier commits as well I think) Should we be using InternalValue? The name and surrounding comment suggests we shouldn't:

// InternalValue should not be set or accessed directly; use ToUint64.
uint64 id = 1 [(gogoproto.customname) = "InternalValue"];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also make our helper take the TenantID type instead. If we got rid of type casting errors like suggested in the other review, some of this code could be simplified/inlined given there'd be no error handling needed.

ok

kvaccessor-get
system-target {source=system,target=10}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How exactly are we expecting the reconciler to get all system targets down the line? The API here suggests that each key is to be retrieved by naming it one-by-one. Will that continue to be the case?

Copy link
Collaborator Author

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @adityamaru, @ajwerner, @irfansharif, and @nvanbenschoten)


pkg/spanconfig/spanconfigtestutils/utils.go, line 36 at r4 (raw file):

Previously, irfansharif (irfan sharif) wrote…

Simplify the grammar to drop "system". There are already too many "system" in our vocabulary and here used for two different meanings ("system tenant" and "system target"); there's no difference between tenant-id==1 and system, and the test cases render them differently. It would help simplify your parser below. I'd be ok exporting it now too (ParseSystemTarget) like we do for everything else -- we are going to use something like it in spanconfig.store tests shortly anyway.

I agree, done. I only added it because that's how we stringify tenant IDs, but I instead ended up changing the String method on system targets instead. As for making it public, I agree we'll need it very soon, but I'll just do it then.


pkg/spanconfig/spanconfigtestutils/utils.go, line 98 at r4 (raw file):

Previously, irfansharif (irfan sharif) wrote…

Could panic instead of this confusing return.

Done.


pkg/spanconfig/spanconfigtestutils/utils.go, line 263 at r4 (raw file):

Previously, irfansharif (irfan sharif) wrote…

Typo: traget. Could panic below instead of the empty string return.

Done.


pkg/spanconfig/spanconfigkvaccessor/testdata/system_span_configs, line 72 at r4 (raw file):

Previously, irfansharif (irfan sharif) wrote…

How exactly are we expecting the reconciler to get all system targets down the line? The API here suggests that each key is to be retrieved by naming it one-by-one. Will that continue to be the case?

I was going to follow this PR with one that adds another method to the KVAccessor, something of the form GetAllHostTenantInstalledSystemSpanConfigs which wouldn't be accessible on the connector like we talked offline.


pkg/spanconfig/spanconfigkvaccessor/validation_test.go, line 155 at r4 (raw file):

Previously, irfansharif (irfan sharif) wrote…

Could also make our helper take the TenantID type instead. If we got rid of type casting errors like suggested in the other review, some of this code could be simplified/inlined given there'd be no error handling needed.

This just goes away once I rebased from the last PR. Good call on the internal value stuff -- tacked on a commit to fix that.


# Test with an empty slate.
kvaccessor-get
system-target {cluster}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend getting rid of this part of the grammar too. It's not adding anything that isn't represented by {source=1}, something our grammar can already represent. I also have misgivings about spanconfig.MakeClusterTarget. For one, despite the same name, it's wholly different conceptually to ptpb.MakeClusterTarget. We chatted a bit offline about this with @adityamaru, regardless of where we land, simplifying the testdata grammar itself is a good thing IMO.

line = strings.TrimPrefix(line, systemTargetPrefix)
default:
t.Fatalf(
"malformed line %q, expected to find spanPrefix %q or system target prefix %q",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] "expected to find %q or %q prefix" would avoid stuttering in your error message.

@@ -43,15 +43,36 @@ type SystemTarget struct {

// MakeSystemTarget constructs, validates, and returns a new SystemTarget.
func MakeSystemTarget(
sourceTenantID roachpb.TenantID, targetTenantID *roachpb.TenantID,
sourceTenantID roachpb.TenantID, targetTenantID roachpb.TenantID,
Copy link
Contributor

@irfansharif irfansharif Feb 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future PRs: worth reconsidering IMO these constructors, in addition to MakeClusterTarget. My preference:

MakeClusterTarget(roachpb.TenantID) SystemTarget // takes in what you call today "source"
MakeTenantsTarget([]roachpb.TenantID) []SystemTarget // doesn't take in the source, has to be system tenant, but takes in dests

Pick whatever names you want for these.

Copy link
Contributor

@adityamaru adityamaru Feb 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we ended up with for the time being is:

MakeClusterTarget() SystemTarget // returns a system target with only the sourceTarget set to the system tenant ID 
MakeTenantTarget(source, target roachpb.TenantID)

Then the SQLTranslator will:

	// Aggregate cluster target protections for the tenant.
	clusterProtections := ptsStateReader.getProtectionPoliciesForCluster()
	if len(clusterProtections) != 0 {
		var systemTarget spanconfig.SystemTarget
		var err error
		if sourceTenantID == roachpb.SystemTenantID {
			systemTarget = spanconfig.MakeClusterTarget()
		} else {
			systemTarget, err = spanconfig.MakeTargetTenant(sourceTenantID, sourceTenantID)
			if err != nil {
				return nil, err
			}
		}
		clusterSystemRecord := spanconfig.Record{
			Target: spanconfig.MakeTargetFromSystemTarget(systemTarget),
			Config: roachpb.SpanConfig{GCPolicy: roachpb.GCPolicy{ProtectionPolicies: clusterProtections}}}
		records = append(records, clusterSystemRecord)
	}

	// Aggregate tenant target protections.
	tenantProtections := ptsStateReader.getProtectionPoliciesForTenants()
	for _, protection := range tenantProtections {
		tenantProtection := protection
		tenantSystemRecord := spanconfig.Record{
			Target: spanconfig.MakeTargetFromSystemTarget(spanconfig.MakeTenantTarget(
				sourceTenantID, tenantProtection.tenantID)),
			Config: roachpb.SpanConfig{GCPolicy: roachpb.GCPolicy{
				ProtectionPolicies: tenantProtection.protections}},
		}
		records = append(records, tenantSystemRecord)
	}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we could make it simpler without complicating the client side:

	// Aggregate cluster target protections for the tenant.
	clusterProtections := ptsStateReader.getProtectionPoliciesForCluster()
	if len(clusterProtections) != 0 {
		clusterSystemRecord := spanconfig.Record{
			Target: spanconfig.MakeTargetFromSystemTarget(spanconfig.MakeClusterTarget(sourceTenantID)),
			Config: roachpb.SpanConfig{GCPolicy: roachpb.GCPolicy{ProtectionPolicies: clusterProtections}}}
		records = append(records, clusterSystemRecord)
	}

	// Aggregate tenant target protections.
	tenantProtections := ptsStateReader.getProtectionPoliciesForTenants()
	for _, protection := range tenantProtections {
		tenantProtection := protection
		tenantSystemRecord := spanconfig.Record{
			Target: spanconfig.MakeTargetFromSystemTarget(spanconfig.MakeTenantTarget(tenantProtection.tenantID)),
			Config: roachpb.SpanConfig{GCPolicy: roachpb.GCPolicy{
				ProtectionPolicies: tenantProtection.protections}},
		}
		records = append(records, tenantSystemRecord)
	}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to simplify the client side logic, it might be worth considering changing the ptsStateReader to return ptpb.Targets instead of protection policies like it does today. Then, we could write conversions to/from ptpb.Targets to spanconfig.Targets.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about simplifying client code, it's about concepts. We have a cluster concept in backup/pts, and we have another cluster concept here that means a wholly different thing. They both have the same MakeClusterTarget signature too. It's a bit difficult to see why.

This patch teaches the KVAccessor to update and get system span
configurations.

Release note: None
Copy link
Collaborator Author

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TFTR!

bors r+

Dismissed @irfansharif from a discussion.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @adityamaru, @ajwerner, @irfansharif, and @nvanbenschoten)


pkg/spanconfig/spanconfigtestutils/utils.go, line 157 at r8 (raw file):

Previously, irfansharif (irfan sharif) wrote…

[nit] "expected to find %q or %q prefix" would avoid stuttering in your error message.

Done.


pkg/spanconfig/spanconfigkvaccessor/testdata/system_span_configs, line 5 at r8 (raw file):

Previously, irfansharif (irfan sharif) wrote…

I'd recommend getting rid of this part of the grammar too. It's not adding anything that isn't represented by {source=1}, something our grammar can already represent. I also have misgivings about spanconfig.MakeClusterTarget. For one, despite the same name, it's wholly different conceptually to ptpb.MakeClusterTarget. We chatted a bit offline about this with @adityamaru, regardless of where we land, simplifying the testdata grammar itself is a good thing IMO.

I agree that the cluster target is just {source=1}, but I think having this {cluster} here does a bit for readability.

@adityamaru captured where the discussion around MakeClusterTarget went above.

@craig
Copy link
Contributor

craig bot commented Feb 15, 2022

Build succeeded:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants