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

Add option to set memory storage to true for a consumer #1078

Merged
merged 3 commits into from Sep 15, 2022

Conversation

goku321
Copy link
Contributor

@goku321 goku321 commented Sep 14, 2022

This allows forcing memory storage through sub options while subscribing.

@coveralls
Copy link

coveralls commented Sep 14, 2022

Coverage Status

Coverage decreased (-0.02%) to 85.527% when pulling b64c208 on goku321:memory-option into 25b6392 on nats-io:main.

@@ -1357,6 +1357,9 @@ func checkConfig(s, u *ConsumerConfig) error {
if u.Replicas > 0 && u.Replicas != s.Replicas {
return makeErr("replicas", u.Replicas, s.Replicas)
}
if u.MemoryStorage && !s.MemoryStorage {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should be verifying it both ways, i.e. true -> false and false -> true. Right now check will pass even if u.MemoryStorage == false and s.MemoryStorage == true.

Suggested change
if u.MemoryStorage && !s.MemoryStorage {
if u.MemoryStorage != !s.MemoryStorage {

Copy link
Member

Choose a reason for hiding this comment

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

No we can't unfortunately, because we don't have a "3 states" value: true, false, not-specified. The point of this function is to check the user intent vs what is already configured in the server.
We have no way to express that the user does not want MemoryStorage, so if you call js.Subscribe() without specifying anything and the JS consumer happens to be configured on the server with MemoryStorage, you don't want to call to fail. Otherwise we would need an option that says "NoMemoryStorage", etc..

So this function for boolean is not great, but the best we can do is check when the intent was to set a boolean to true, then only we can check that it matches the server setting.

opts := natsserver.DefaultTestOptions
opts.Port = -1
opts.JetStream = true
s := natsserver.RunServer(&opts)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can just use s := RunBasicJetStreamServer() instead.

js.go Outdated
@@ -2485,6 +2488,14 @@ func ConsumerReplicas(replicas int) SubOpt {
})
}

// SetMemoryStorage sets the memory storage to true for a consumer.
func SetMemoryStorage() SubOpt {
Copy link
Collaborator

Choose a reason for hiding this comment

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

To be more in line with other sub options, I would suggest changing the name to MemoryStorage()

Copy link
Member

Choose a reason for hiding this comment

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

Yes. Also wonder when the name is "too generic", is going to be a problem if one day we need the same name for a different option? Meaning this is a SubOpt, but what if we need an option one day for JSOpt (or any other). For that reason, should we be more precise in the naming? Something like "ConsumerMemoryStorage()"? (not good, but you get the idea).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I named it "SetMemoryStorage" because the name "MemoryStorage" is already being used. Should I name it "ConsumerMemoryStorage" as @kozlovic suggested?

Copy link
Member

Choose a reason for hiding this comment

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

Yes please, go with ConsumerMemoryStorage() then, and this proves my point about possible name clashes unfortunately...

@@ -1357,6 +1357,9 @@ func checkConfig(s, u *ConsumerConfig) error {
if u.Replicas > 0 && u.Replicas != s.Replicas {
return makeErr("replicas", u.Replicas, s.Replicas)
}
if u.MemoryStorage && !s.MemoryStorage {
Copy link
Member

Choose a reason for hiding this comment

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

No we can't unfortunately, because we don't have a "3 states" value: true, false, not-specified. The point of this function is to check the user intent vs what is already configured in the server.
We have no way to express that the user does not want MemoryStorage, so if you call js.Subscribe() without specifying anything and the JS consumer happens to be configured on the server with MemoryStorage, you don't want to call to fail. Otherwise we would need an option that says "NoMemoryStorage", etc..

So this function for boolean is not great, but the best we can do is check when the intent was to set a boolean to true, then only we can check that it matches the server setting.

js.go Outdated
@@ -2485,6 +2488,14 @@ func ConsumerReplicas(replicas int) SubOpt {
})
}

// SetMemoryStorage sets the memory storage to true for a consumer.
func SetMemoryStorage() SubOpt {
Copy link
Member

Choose a reason for hiding this comment

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

Yes. Also wonder when the name is "too generic", is going to be a problem if one day we need the same name for a different option? Meaning this is a SubOpt, but what if we need an option one day for JSOpt (or any other). For that reason, should we be more precise in the naming? Something like "ConsumerMemoryStorage()"? (not good, but you get the idea).

t.Fatalf("Error on subscribe: %v", err)
}

consInfo, err := sub.ConsumerInfo()
Copy link
Member

Choose a reason for hiding this comment

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

Instead of repeating this code for the 3 types of consumers, I would have made it a small helper function inline:

checkCons := func(sub *Subscription) {
    t.Helper()
    consInfo, err := sub.ConsumerInfo()
    ...
}

then you would invoke it after each sub creation.


if !consInfo.Config.MemoryStorage {
t.Fatalf("Expected memory storage to be %v, got %+v", true, consInfo.Config.MemoryStorage)
}
Copy link
Member

Choose a reason for hiding this comment

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

What you may want to add is a test where a durable is created with MemoryStorage and call a js.SubscribeSync() with Durable() but without the memory storage option in the subscribe call and verifies that it actually works. That would catch the change the Piotr was suggesting that would - in my opinion - break things.

@kozlovic
Copy link
Member

@goku321 Do you think you could get the changes in soon? We are trying to release today or tomorrow (Friday) and since this is an addition it would be better to go in the 1.17.0 than in a 1.17.1 :-). The test could be changed/updated later, however it would be nice to change the name of the option now as @piotrpio suggested. Thanks!

@goku321
Copy link
Contributor Author

goku321 commented Sep 15, 2022

Sure @kozlovic I can change the name now and will update the tests later :)

@kozlovic
Copy link
Member

@goku321 Yes, please update the PR with the option name change and tests can be updated later on. Thanks!

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

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

LGTM

@kozlovic
Copy link
Member

@piotrpio The changes look good to me. Not sure if you want chime in or approve and merge the PR.

Copy link
Collaborator

@piotrpio piotrpio left a comment

Choose a reason for hiding this comment

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

LGTM as well

@piotrpio piotrpio merged commit 866ce08 into nats-io:main Sep 15, 2022
@goku321 goku321 deleted the memory-option branch September 16, 2022 05:49
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