GODRIVER-3037 Support internal-only options.#2023
GODRIVER-3037 Support internal-only options.#2023qingyang-hu merged 5 commits intomongodb:masterfrom
Conversation
API Change Report./v2/mongo/optionscompatible changesClientOptions.Custom: added ./v2/x/mongo/driver/xoptionscompatible changespackage added |
mongo/options/internaloptions.go
Outdated
| // SetInternalClientOptions sets internal options for ClientOptions. | ||
| // | ||
| // Deprecated: This function is for internal use only. It may be changed or removed in any release. | ||
| func SetInternalClientOptions(opts *ClientOptions, custom map[string]any) (*ClientOptions, error) { |
There was a problem hiding this comment.
Could this function live in the experimental API? What is the pattern for future custom data? Should ClientOptions be extended with a Custom field of type map[string]any?
There was a problem hiding this comment.
Consider the following pattern:
type ClientOptions struct {
custom map[string]any
}
func WithCustomValue(co ClientOptions, key string, val any) ClientOptions {}
func CustomValue(co ClientOptions key string) any {}Then in x/mongo/driver:
const someExperimentKey = "x/mongo/driver:myExperiment"
func WithSomeExperimentValue(co options.ClientOptions, on bool) options.ClientOptions {
return options.WithCustomValue(co, someExperimentKey, on)
}
func SomeExperimentValue(co options.ClientOptions) bool {
val := options.CustomValue(co, someExperimentKey)
if b, ok := val.(bool); ok {
return b
}
return false
}The usage would look something like this:
clientOpts, _ := options.Client()
clientOpts = driver.WithSomeExperimentValue(clientOpts, true)
// ...And we would check it internally like this:
expVal := driver.SomeExperimentValue(clientOpts)
// ...There was a problem hiding this comment.
Instead of an expressive interface, I'd prefer a map-style interface without any hint other than a user-provided option name to add obfuscation to discourage general users from using it. However, it makes sense to wrap the map[string]any in a struct and move it to "x/mongo/driver" to emphasize it is "experimental".
I can stack another PR for GODRIVER-3429 (internal-only "AuthenticateToAnything") on top of this one to demonstrate future custom data.
There was a problem hiding this comment.
I think this solution is fine for now, we can update if needed later.
x/mongo/driver/options/options.go
Outdated
| // not use this file except in compliance with the License. You may obtain | ||
| // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| package options |
There was a problem hiding this comment.
Should we name this package something different to avoid import conflicts? Perhaps xoptions?
| // SetInternalClientOptions sets internal options for ClientOptions. | ||
| // | ||
| // Deprecated: This function is for internal use only. It may be changed or removed in any release. | ||
| func SetInternalClientOptions(opts *options.ClientOptions, key string, option any) error { |
There was a problem hiding this comment.
Do we need this to return an error? Should we just do nothing if an unsupported option is set?
There was a problem hiding this comment.
I prefer to keep the return to avoid silent errors, for example, a typo in the key name. Otherwise, these errors would be difficult to find.
GODRIVER-3037
Summary
Support setting internal-only options with a helper function.
Background & Motivation
This proposal does not change the current interface.
The option names are not publicly exposed to the user, so it is less likely to be used without internal knowledge.
We can add a
map[string]anynamedcustominClientOptionsstruct for future internal options, such as AuthenticateToAnything.The
CryptandDeploymentfields inClientOptionswill be merged into the aforementioned map in v3.