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

persistent session interface #595

Merged
merged 38 commits into from
Oct 29, 2021
Merged

persistent session interface #595

merged 38 commits into from
Oct 29, 2021

Conversation

max-hoffman
Copy link
Contributor

No description provided.

server/server.go Outdated Show resolved Hide resolved
@@ -159,11 +173,48 @@ func (sv *globalSystemVariables) SetGlobal(name string, val interface{}) error {
return nil
}

// init initializes SystemVariables as it functions as a global variable.
func init() {
func DecodeSystemVar(name string, val string) (interface{}, error) {
Copy link
Contributor Author

@max-hoffman max-hoffman Oct 21, 2021

Choose a reason for hiding this comment

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

it's just annoying to call this repetitively, maybe GetAndDecodeSystemVariable because it validates and decodes?

Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't have this at all, make the integrator responsible for all encoding / decoding

server/server.go Outdated
NoDefaults bool
}

func (c Config) WithDefaults(conf config.ReadableConfig) (Config, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is awkward, but i don't have access to the decoding in Dolt. We don't streamline config merging right now in general. Need key constants for the system variables, well documented process for cli overrides -> server config -> persisted defaults -> static defaults. And same thing for everywhere else we would access Dolt specifc config.

Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

In general this PR tries to do too much. You have two different interfaces with overlapping functionality: persisted session and config. The new session interface type is clearly necessary and proper, but I'm not convinced that ReadableConfig / WritableConfig needs to be defined in the engine at all, as opposed to details that integrators need to care about. And you have several implementations of these interfaces that aren't currently used and whose purpose I don't understand.

Start smaller. You need a persisted session interface and a test implementation that you can use for unit tests, which you have. You need a way for integrators to add system variables, which already exists (sql.SystemVariables.AddSystemVariables). It makes sense to have a method similar to InitSystemVariablesWithDefaults, but you don't want a ReadableConfig there, you want a collection (or maybe just a slice) of SystemVariables.

I would consider pruning the Config interfaces altogether. If you don't (because you want to support file-based config for people running the in memory server), then move the PersistedSession type into the memory package instead, and consider moving the file-based config implementation there as well.

@@ -53,6 +53,7 @@ type SessionManager struct {
builder SessionBuilder
sessions map[uint32]sql.Session
pid uint64
noDefaults bool
Copy link
Member

Choose a reason for hiding this comment

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

As a general rule, don't name boolean variables with a negative, makes it harder to reason about their meaning

so useDefaults here, flip the case

Copy link
Member

Choose a reason for hiding this comment

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

not resolved :)

Copy link
Member

Choose a reason for hiding this comment

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

Not actually used, it seems, just remove

server/server.go Outdated Show resolved Hide resolved
nameToConfig map[string]ReadWriteConfig
}

var _ ReadableConfig = &ConfigHierarchy{}
Copy link
Member

Choose a reason for hiding this comment

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

Nil pointer is more idiomatic (just because it saves an allocation)

var ErrConfigParamNotFound = errors.New("Param not found")

// ReadableConfig interface provides a mechanisms for getting key value pairs from a config
type ReadableConfig interface {
Copy link
Member

Choose a reason for hiding this comment

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

Main comment on these interfaces is that they should not work in strings like this. They should be interface{} valued just like like the session variable interfaces on session:

	SetSessionVariable(ctx *Context, sysVarName string, value interface{}) error
	GetSessionVariable(ctx *Context, sysVarName string) (interface{}, error)

Copy link
Member

Choose a reason for hiding this comment

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

Implementer should be responsible for storing an appropriate type and returning it, then the engine can coerce it into a more appropriate SQL type as necessary


// GetStringOrDefault retrieves a string from the config hierarchy and returns it if available. Otherwise it returns
// the default string value
GetStringOrDefault(key, defStr string) string
Copy link
Member

Choose a reason for hiding this comment

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

Would remove this, add an ok return param to the Get method instead

ResetPersistAll(ctx *Context) error
}

type PersistedSession struct {
Copy link
Member

Choose a reason for hiding this comment

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

Larger comment is: why is this a struct? Integrators should implement this.

If we provide one as part of GMS, it should be a file-based one, using the file-based config store you wrote

Copy link
Member

Choose a reason for hiding this comment

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

If you want an in-memory one for testing the set plan node, that seems fair, put one in the plan_test package

sql/plan/set.go Outdated
persistSess, ok := ctx.Session.(sql.PersistableSession)
if !ok {
// todo find old error
return sql.ErrUnsupportedFeature.New("PERSIST")
Copy link
Member

Choose a reason for hiding this comment

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

Probably not the right error here. It's not that the feature is unsupported, it's that the session doesn't support persistence

@@ -159,11 +173,48 @@ func (sv *globalSystemVariables) SetGlobal(name string, val interface{}) error {
return nil
}

// init initializes SystemVariables as it functions as a global variable.
func init() {
func DecodeSystemVar(name string, val string) (interface{}, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't have this at all, make the integrator responsible for all encoding / decoding

return decoded, nil
}

func InitSystemVariablesWithDefaults(defaults config.ReadableConfig) error {
Copy link
Member

Choose a reason for hiding this comment

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

This is probably not functionality that the engine should be providing. If you want to provide this as a utility method that takes a ReadableConfig and puts all of its values into a session, that's fine.

return decoded, nil
}

func InitSystemVariablesWithDefaults(defaults config.ReadableConfig) error {
for _, sysVar := range systemVars {
SystemVariables.sysVarVals[sysVar.Name] = sysVar.Default
Copy link
Member

Choose a reason for hiding this comment

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

This seems misplaced in the context of this function. Setting up the system vars and their defaults is not the same as initializing a session with a config store.

@max-hoffman
Copy link
Contributor Author

@zachmu Responding to a couple of the points just for documentation, I think we're mostly in alignment but the cross-package code muddies the waters. Will follow up in person tomorrow:

  • The config interfaces are wholesale transplanted from Dolt, the only one I modified is PrefixConfig to make my life easier for namespacing. I don't disagree with your individual critiques of the configs, but I do disagree that the config portion is overcomplicating; refactoring all of the config code is considerably harder than moving it over. If I implemented your suggestions I'd have to refactor all of how Dolt uses those interfaces.
  • The alternative is accomplishing this without moving config from Dolt to GMS. In general, sysVar access is mostly private to GMS. If we persist as part of a sysVar set, GMS needs a handle to an interface for writing those changes. I think this is my most lingering question after reading your comments: an alternative plan of: intercepting plan.Set in Dolt, persisting vars there, and having GMS be blind to Persist queries is doable, I think. But I immediately veered away from that given the structuring of current Set logic, and how this is a MySQL feature that I think makes sense as part of our MySQL server logic.
  • Also, having the integrator do encoding/decoding is appealing, but all of the typing logic lives in GMS already. I originally wrote duplicate encoders for the listener configs, but then found the encoder/decoder typing logic and refactored.

@max-hoffman max-hoffman marked this pull request as ready for review October 25, 2021 19:31
@max-hoffman max-hoffman changed the title Max/sql config sql config persistence in dolt config.json Oct 26, 2021
@max-hoffman max-hoffman changed the title sql config persistence in dolt config.json persistent session interface Oct 26, 2021
Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

LGTM, just a couple comments

memory/persisted_session.go Outdated Show resolved Hide resolved
@@ -53,6 +53,7 @@ type SessionManager struct {
builder SessionBuilder
sessions map[uint32]sql.Session
pid uint64
noDefaults bool
Copy link
Member

Choose a reason for hiding this comment

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

not resolved :)

server/server_config.go Outdated Show resolved Hide resolved
varToSet := expression.NewSystemVar(setExpr.Name.String(), sql.SystemVariableScope_PersistOnly)
res[i] = expression.NewSetField(varToSet, innerExpr)
// TODO reset persist
//case sqlparser.SetScope_ResetPersist:
Copy link
Member

Choose a reason for hiding this comment

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

You have this handled in plan/set.go

e := NewEngine(t, harness)
ctx := NewContext(harness)

for _, tt := range q {
Copy link
Member

Choose a reason for hiding this comment

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

Need tests of reset here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no parser support for RESET yet

@@ -53,6 +53,7 @@ type SessionManager struct {
builder SessionBuilder
sessions map[uint32]sql.Session
pid uint64
noDefaults bool
Copy link
Member

Choose a reason for hiding this comment

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

Not actually used, it seems, just remove

sql/session.go Show resolved Hide resolved
sql/session.go Outdated Show resolved Hide resolved
@max-hoffman max-hoffman merged commit 62885d6 into main Oct 29, 2021
@max-hoffman max-hoffman deleted the max/sql-config branch October 29, 2021 16:30
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.

2 participants