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

Make DefaultOptions a function that produces new Options on every call #308

Merged
merged 1 commit into from
Jul 31, 2017

Conversation

unkaktus
Copy link
Contributor

At the moment DefaultOptions is a global struct that is being copied by value. Some of the fields are pointers, so they got copied as well while retaining their value and thus making these fields effectively global. This breaks logic of multiple operations with DefaultOptions which may be modified by other users (e.g. in tests).
This PR is making it a function that returns a fresh copy of DefaultOptions each time to use independently.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.03%) to 94.559% when pulling 29c0ba3 on nogoegst:default-options-func into 34c8842 on nats-io:master.

Copy link
Contributor

@tylertreat tylertreat left a comment

Choose a reason for hiding this comment

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

I'm in favor of this change, but it will require a major version bump since this would be a breaking change.

@kozlovic
Copy link
Member

To mitigate the compatibility issue, we could keep the DefaultOptions as it is right now and simply add the DefaultOptions() function. We would have to make sure to use the function in our tests, etc.. and in general users should use the option, but at least that would not break existing code. What do you guys think?

@tylertreat
Copy link
Contributor

tylertreat commented Jul 24, 2017

@kozlovic I don't think you can have a var and func with the same name in the same package? But yes, we could name it something different.

@wallyqs
Copy link
Member

wallyqs commented Jul 24, 2017

Another idea maybe, how about deprecating the fields which are pointers as part of DefaultOptions? Seems it is only Dialer the one that wouldn't be a copy while others are safe to use.

@aricart
Copy link
Member

aricart commented Jul 24, 2017

How about NewDefaultOptions(), and keep the struct the same.

@kozlovic
Copy link
Member

or GetDefaultOptions() like we have in NATS Streaming server.

@unkaktus
Copy link
Contributor Author

unkaktus commented Jul 24, 2017

Another idea maybe, how about deprecating the fields which are pointers as part of DefaultOptions? Seems it is only Dialer the one that wouldn't be a copy while others are safe to use.

@wallyqs, it does not feel like a good idea to me. You can't guarantee that all fields are primitive and do not contain any pointers.
Actually I got faced this issue while fixing TLS. tls.Config is full of pointers and other magic things. I don't think we can drop support for arbitrary fields just to work around broken API.

Personally I think it's better to drop deprecated API faster while bumping major version. Otherwise it will become a big mess where no one understands how it works (or will just keep going without fixing their code).

@wallyqs
Copy link
Member

wallyqs commented Jul 24, 2017

@nogoegst but tls.Config is not part of nats.DefaultOptions so sharing of tls.Config accidentally by calling opts := nats.DefaultOptions several times wouldn't be possible no?

@unkaktus
Copy link
Contributor Author

@wallyqs tls.Config is in the Options instance of which DefaultOptions is. This just defaults to nil. By now.

@@ -79,18 +79,21 @@ var (
ErrStaleConnection = errors.New("nats: " + STALE_CONNECTION)
)

var DefaultOptions = Options{
Copy link
Member

Choose a reason for hiding this comment

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

@nogoegst I am torn. Although I fully agree with you that using DefaultOptions as a struct may lead to errors, especially with the presence of pointers (there is already one, and others may be added in the future), making this change would break potentially lots of users (arguably, they should vendor if they are concerned about breaking changes). The worse, is that the use of DefaultOptions was safe until 1.2.2, where the pointer was added.

Leaving DefaultOptions and adding GetDefaultOptions() would avoid breaking users' existing code base. I was thinking that we could remove the Dialer from DefaultOptions structure, add a comment that DefaultOptions is deprecated and users should use GetDefaultOptions() instead, and make sure that nothing is ever added to DefaultOptions structure itself, but instead in GetDefaultOptions().

Removing the Dialer from DefaultOptions is not going to break users (the ones at 1.2.2) since the Connect() call is using the exact same net.Dialer with DefaultTimeout if no Dialer is set in Options.

I can do all these changes myself, but I wanted to give you the opportunity to discuss or implement those changes since you have originally submitted the PR. Let me know how you want to proceed.

@unkaktus unkaktus force-pushed the default-options-func branch from 29c0ba3 to 12ef716 Compare July 29, 2017 17:42
@unkaktus
Copy link
Contributor Author

@kozlovic agreed. Fixed by renaming to GetDefaultOptions().

@coveralls
Copy link

Coverage Status

Coverage increased (+0.03%) to 94.559% when pulling 12ef716 on nogoegst:default-options-func into 34c8842 on nats-io:master.

@kozlovic
Copy link
Member

Thanks for your contribution!

@kozlovic kozlovic merged commit 43abfaa into nats-io:master Jul 31, 2017
@unkaktus unkaktus deleted the default-options-func branch July 31, 2017 20:06
anxinyf added a commit to anxinyf/stan.go that referenced this pull request May 22, 2019
DEPRECATED: Use GetDefaultOptions() instead.
DefaultOptions is not safe for use by multiple clients.
For details see nats-io/nats.go#308.
DefaultOptions are the NATS Streaming client's default options

Signed-off-by: anxinyf <[email protected]>
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.

6 participants