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

sql: mark use of Gossip as deprecated #47972

Merged
merged 1 commit into from
Apr 28, 2020
Merged

Conversation

tbg
Copy link
Member

@tbg tbg commented Apr 23, 2020

This commit wraps Gossip in a wrapper when it is used in SQL. This small
wrapper helpfully keeps track, in code, of work that needs to be done to
enable multi-tenancy, and ensures that any deprecated use of Gossip is
associated with a Github issue. The wrapper also makes sure we're not
introducing new dependencies on Gossip.

Release note: None

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@tbg tbg added the A-multitenancy Related to multi-tenancy label Apr 23, 2020
@blathers-crl

This comment has been minimized.

@blathers-crl
Copy link

blathers-crl bot commented Apr 23, 2020

❌ The GitHub CI (Cockroach) build has failed on d0896b5c.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

Copy link
Contributor

@asubiotto asubiotto left a comment

Choose a reason for hiding this comment

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

Reviewed 31 of 31 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @nvanbenschoten and @tbg)


pkg/gossip/gossip.go, line 1621 at r1 (raw file):

// MakeDeprecatedGossip initializes a DeprecatedGossip instance. See
// MakeTenantSQLDeprecatedWrapper for details.
func MakeDeprecatedGossip(g *Gossip, tenant bool) DeprecatedGossip {

What can we do about disallowing new uses of Gossip?


pkg/util/errorutil/tenant_deprecated_wrapper.go, line 31 at r1 (raw file):

// be available in a SQL tenant server for the time being. Such calls may also
// point at work items that may obviate the use of the wrapper in the future.
func MakeTenantSQLDeprecatedWrapper(v interface{}, tenant bool) TenantSQLDeprecatedWrapper {

After reading this comment I'm still not 100% sure what the tenant boolean is specifying. I guess I'm confused by the "indicates whether the object is part of a SQL tenant server". What exactly does that mean? Based on the behavior below I guess it's whether the wrapped object is unavailable in a SQL tenant server? I think it might be clearer if you make the behavior more explicit e.g. s/tenant/forceUnavailability.

Copy link
Member

@nvanbenschoten nvanbenschoten left a comment

Choose a reason for hiding this comment

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

Reviewed 31 of 31 files at r1.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @asubiotto and @tbg)


pkg/gossip/gossip.go, line 1631 at r1 (raw file):

//
// See the comments on TenantSQLDeprecatedWrapper for details.
type DeprecatedGossip struct {

nit: is type DeprecatedGossip errorutil.TenantSQLDeprecatedWrapper a cleaner pattern to start with these option types?


pkg/sql/distsql/server.go, line 51 at r1 (raw file):

const minFlowDrainWait = 1 * time.Second

const distSQLGossipIssueNo = 47900

nit: consider commenting with the URL so that it's easier to jump to.


pkg/util/errorutil/tenant.go, line 33 at r1 (raw file):

		}
	}
	return errors.New("operation is unsupported in multi-tenancy mode" + buf.String())

nit: might as well avoid the string concatenation by pulling up a buf.WriteString("operation is unsupported in multi-tenancy mode"). That will also make this easier to read.


pkg/util/errorutil/tenant_deprecated_wrapper.go, line 31 at r1 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

After reading this comment I'm still not 100% sure what the tenant boolean is specifying. I guess I'm confused by the "indicates whether the object is part of a SQL tenant server". What exactly does that mean? Based on the behavior below I guess it's whether the wrapped object is unavailable in a SQL tenant server? I think it might be clearer if you make the behavior more explicit e.g. s/tenant/forceUnavailability.

I agree. After reading this file, I'm still not sure I understand the difference between tenant and v == nil. Is there one? Is the idea that we'll still keep providing dependencies even when in a SQL tenant server, but we'll slowly get rid of calls to Deprecated which use them and only then will the difference be immaterial?

I'd also consider inverting the condition so that the zero value of this struct can be used to indicate that the optional value is not present.


pkg/util/errorutil/tenant_deprecated_wrapper.go, line 50 at r1 (raw file):

// A list of related issues can optionally be provided, in case there is a
// desire to make the functionality available to tenants in the future.
func (w TenantSQLDeprecatedWrapper) Optional(issueNos ...int) (interface{}, error) {

Do we want a second form of this that return a boolean instead of an error when the dependency is not provided? I'd hate for us to feel like we can't add conditional logic in hot paths due to the cost of calling this method.

@tbg
Copy link
Member Author

tbg commented Apr 23, 2020 via email

Copy link
Member Author

@tbg tbg 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 @asubiotto and @nvanbenschoten)


pkg/gossip/gossip.go, line 1621 at r1 (raw file):

Previously, asubiotto (Alfonso Subiotto Marqués) wrote…

What can we do about disallowing new uses of Gossip?

I don't think we need to do more. If you wanted to use Gossip, you would have to get it from the DeprecatedGossip, and it will pretty much force you to realize that you are setting yourself up for failure unless the new use is optional (and even then, it cautions you away from it). Did you have something else in mind or do you think this isn't enough?


pkg/gossip/gossip.go, line 1631 at r1 (raw file):

Previously, nvanbenschoten (Nathan VanBenschoten) wrote…

nit: is type DeprecatedGossip errorutil.TenantSQLDeprecatedWrapper a cleaner pattern to start with these option types?

When I first read this suggestion I thought so, but I'm less sure now. It allows you to cast back to the wrapper type, which has the Deprecated method which I want to remove from DeprecatedGossip as soon as I can. Theoretical concern, but it's a concern and I don't see anything in the other choice that would outweigh it.


pkg/util/errorutil/tenant_deprecated_wrapper.go, line 31 at r1 (raw file):

Previously, nvanbenschoten (Nathan VanBenschoten) wrote…

I agree. After reading this file, I'm still not sure I understand the difference between tenant and v == nil. Is there one? Is the idea that we'll still keep providing dependencies even when in a SQL tenant server, but we'll slowly get rid of calls to Deprecated which use them and only then will the difference be immaterial?

I'd also consider inverting the condition so that the zero value of this struct can be used to indicate that the optional value is not present.

I re-worked the commentary to (hopefully) clear this confusion up for all future readers. WDYT?


pkg/util/errorutil/tenant_deprecated_wrapper.go, line 50 at r1 (raw file):

Previously, nvanbenschoten (Nathan VanBenschoten) wrote…

Do we want a second form of this that return a boolean instead of an error when the dependency is not provided? I'd hate for us to feel like we can't add conditional logic in hot paths due to the cost of calling this method.

I added it but I don't really like it. These are harder to track, and they allow inconsistent errors of the form

if g, ok := w.Optional(); !ok {
  return errors.New("thing I wanted is missing")
}

That said, you're probably right that we'll see something pop up in the hot path that actually needs to stick around. I'll leave it in and we can revisit. When we give the NodeID a similar treatment (#48009) we'll probably need it.

@tbg tbg force-pushed the deprecate-gossip branch 2 times, most recently from 01e51b9 to ed47ce0 Compare April 24, 2020 10:43
This commit wraps Gossip in a wrapper when it is used in SQL. This small
wrapper helpfully keeps track, in code, of work that needs to be done to
enable multi-tenancy, and ensures that any deprecated use of Gossip is
associated with a Github issue. The wrapper also makes sure we're not
introducing new dependencies on Gossip.

Note that this wrapper is more than an option type: it wraps an object
that is always there (at least at the beginning), but we can configure
the wrapper to pretend that it isn't there (for callers that can handle
that).

Release note: None
Copy link
Contributor

@asubiotto asubiotto left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 6 of 13 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @asubiotto, @nvanbenschoten, and @tbg)


pkg/gossip/gossip.go, line 1621 at r1 (raw file):

Previously, tbg (Tobias Grieger) wrote…

I don't think we need to do more. If you wanted to use Gossip, you would have to get it from the DeprecatedGossip, and it will pretty much force you to realize that you are setting yourself up for failure unless the new use is optional (and even then, it cautions you away from it). Did you have something else in mind or do you think this isn't enough?

SGTM

Copy link
Member

@nvanbenschoten nvanbenschoten left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 10 of 13 files at r2.
Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @asubiotto, @nvanbenschoten, and @tbg)

@tbg
Copy link
Member Author

tbg commented Apr 28, 2020

TFTRs!

bors r=asubiotto,nvanbenschoten

@craig
Copy link
Contributor

craig bot commented Apr 28, 2020

Build succeeded

@craig craig bot merged commit 8eb6a3f into cockroachdb:master Apr 28, 2020
tbg added a commit to tbg/cockroach that referenced this pull request Apr 29, 2020
With the advent of multi-tenancy, SQL servers can optionally be
decoupled from the (and share a) KV backend. As a consequence, the
NodeID may not be available and its use across all components that need
to function in a multi-tenant setup is deprecated. Yet, some components
require a similar unique identifier for the SQL server they're a part
of.

This new identifier is the SQLInstanceID. At the time of writing, since
we're not yet able to start true SQL tenant servers and only exercise
parts of this functionality in unit testing, it is a randomized integer.
It's possible that we'll replace it with a per-tenant or even global
counter in production, putting it truly on par with the NodeID, to be
able to give the simple guarantee that these IDs are never reused
between different incarnations of the SQL process for a given tenant.
This final decision is kicked down the road, see cockroachdb#48009.

This commit introduces an IDContainer which will aid this process by
wrapping both the NodeID and SQLInstanceID, very similar to the work
carried out for Gossip in cockroachdb#47972. We do not yet audit all of the call
sites to keep the initial diff container. Instead, IDContainer has a
Get() method that makes it a drop-in replacement for the previously used
NodeIDContainer. `Get ` will be removed in a future commit while moving
all callers to either the `Optional{,Err}` or `DeprecatedNodeID`
methods.

Release note: None
tbg added a commit to tbg/cockroach that referenced this pull request May 1, 2020
With the advent of multi-tenancy, SQL servers can optionally be
decoupled from the (and share a) KV backend. As a consequence, the
NodeID may not be available and its use across all components that need
to function in a multi-tenant setup is deprecated. Yet, some components
require a similar unique identifier for the SQL server they're a part
of.

This new identifier is the SQLInstanceID. At the time of writing, since
we're not yet able to start true SQL tenant servers and only exercise
parts of this functionality in unit testing, it is a randomized integer.
It's possible that we'll replace it with a per-tenant or even global
counter in production, putting it truly on par with the NodeID, to be
able to give the simple guarantee that these IDs are never reused
between different incarnations of the SQL process for a given tenant.
This final decision is kicked down the road, see cockroachdb#48009.

This commit introduces an IDContainer which will aid this process by
wrapping both the NodeID and SQLInstanceID, very similar to the work
carried out for Gossip in cockroachdb#47972. We do not yet audit all of the call
sites to keep the initial diff container. Instead, IDContainer has a
Get() method that makes it a drop-in replacement for the previously used
NodeIDContainer. `Get ` will be removed in a future commit while moving
all callers to either the `Optional{,Err}` or `DeprecatedNodeID`
methods.

Release note: None
craig bot pushed a commit that referenced this pull request May 1, 2020
48110: base: introduce SQLInstanceID (and container) r=asubiotto,nvanbenschoten a=tbg

With the advent of multi-tenancy, SQL servers can optionally be
decoupled from the (and share a) KV backend. As a consequence, the
NodeID may not be available and its use across all components that need
to function in a multi-tenant setup is deprecated. Yet, some components
require a similar unique identifier for the SQL server they're a part
of.

This new identifier is the SQLInstanceID. At the time of writing,
since we're not yet able to start true SQL tenant servers and only
exercise parts of this functionality in unit testing, it is a
randomized integer. It's possible that we'll replace it with
a per-tenant counter in production, putting it truly on par with
the NodeID, to be able to give the simple guarantee that these IDs
are never reused between different incarnations of the SQL process
for a given tenant. (Note that initially, at most one SQL tenant
server will be active per tenant at any given time).

This commit introduces an IDContainer which will aid this process by
wrapping both the NodeID and SQLInstanceID, very similar to the work
carried out for Gossip in #47972. We do not yet audit all of the call
sites to keep the initial diff container. Instead, IDContainer has a
Get() method that makes it a drop-in replacement for the previously used
NodeIDContainer. `Get ` will be removed in a future commit while moving
all callers to either the `Optional{,Err}` or `DeprecatedNodeID`
methods.

Release note: None

Co-authored-by: Tobias Schottdorf <tobias.schottdorf@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-multitenancy Related to multi-tenancy
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants