-
Notifications
You must be signed in to change notification settings - Fork 662
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
[changed] JetStream function to not lookup account info & moved it #739
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -170,6 +170,8 @@ type accountInfoResponse struct { | |
} | ||
|
||
// AccountInfo retrieves info about the JetStream usage from the current account. | ||
// If JetStream is not enabled, this will return ErrJetStreamNotEnabled | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This now has to be the case for every API call to the JS context, but I think that is ok. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wallyqs we need to probably go through our public calls and make sure that is so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes could happen if JS becomes disabled |
||
// Other errors can happen but are generally considered retryable | ||
func (js *js) AccountInfo(opts ...JSOpt) (*AccountInfo, error) { | ||
o, cancel, err := getJSContextOpts(js.opts, opts...) | ||
if err != nil { | ||
|
@@ -181,6 +183,10 @@ func (js *js) AccountInfo(opts ...JSOpt) (*AccountInfo, error) { | |
|
||
resp, err := js.nc.RequestWithContext(o.ctx, js.apiSubj(apiAccountInfo), nil) | ||
if err != nil { | ||
// todo maybe nats server should never have no responder on this subject and always respond if they know there is no js to be had | ||
if err == ErrNoResponders { | ||
err = ErrJetStreamNotEnabled | ||
} | ||
return nil, err | ||
} | ||
var info accountInfoResponse | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -496,9 +496,6 @@ type Conn struct { | |
respMux *Subscription // A single response subscription | ||
respMap map[string]chan *Msg // Request map for the response msg channels | ||
respRand *rand.Rand // Used for generating suffix | ||
|
||
// JetStream Contexts last account check. | ||
jsLastCheck time.Time | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we all agreed that JS contexts should be lightweight and easy to create. In many tests I create multiple ones with different characteristics. Question though, do we expect code to look like this all the time or folks will skip the AccountInfo and just check errors on the other API calls? nc, _ := nc.Connect("demo.nats.io")
js, _ := nc.JetStream()
if _, err := js.AccountInfo(); err != nil {} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Help me understand: can the enabled/disabled nature of JetStream for this connection change overtime? Meaning, after calling JetStream() (and lets say we still do an account check inside, and it returned ok), is there a possibility that JS may no longer be enabled for this account? What if the connection reconnects to a server where this account does not have JS enabled, which likely would be misconfiguration? If it can't change, then instead of a time check, it should be simply a "already checked and here is the result" type of things (say 2 booleans). If it can change overtime and since all APIs will return "not enabled" if JS is or no longer is enabled, not sure what we gain by doing it inside JetStream(). Say you already have the context, but then JS is disabled, then the context is "valid" and yet all other APIs call will fail with "not enabled". Same if you recently got a context and we use time-check, then if we are within the window, JetStream() would return a context (which won't work when calling APIs), but if you happen to ask after the time-check has passed, this call would return "not enabled". I am not against doing the account check inside JetStream() (with the time-check bug fixed), since it can give a "fail fast" behavior where if you get "not enabled", there is no need to proceed further, but it also can be non deterministic (as described above), and all APIs should be checked for success/failure anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. due to reload or jwt update Js can be legitimately enabled disabled on the fly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think for users that want to ensure that JS is ready and available, a bit more code would be needed which might be better to have outside of the creation of the nc, _ := nc.Connect("demo.nats.io")
js, _ := nc.JetStream()
ctx, done := context.WithTimeout(context.Background(), 5*time.Second)
defer done()
// IsJSAvailable()
for {
select {
case <-ctx.Done():
return
default:
}
if _, err := js.AccountInfo(); err != nil {
// Handle temporary errors:
//
// - Quorum not ready
// - JS API not yet ready
// - No responders (temporary while JS booting up)
// Then: timeout when too many failures or no response
}
} There would be some retries when this happens for example and backoff until is ready. |
||
} | ||
|
||
type natsReader struct { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that disappears, then above
jsLastCheck
should disappear too and be removed from theConn
object.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, existing code is broken: if one calls JetStream() for the first time and say the overall call fails (JetStream not enabled, or custom prefix leads nowhere), then the second call to JetStream() would succeed because we would not check for the AccountInfo().. so this is bad. At the very least if "time check" is maintained, we should record jsLastCheck only on success. But still, it means that the next call to JetStream() may succeed even if the underlying AccountInfo() would have failed because we passed a bad prefix, etc..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed. JetStream() is now a constructor only. because it can't reallly fail, we can use js.AccountInfo()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The time check bug was me, and agree we should only stamp (if we keep it) on success.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still not clear (and this is me, not the code) as to why we are doing this change vs an option like SkipAccountCheck().
This feels like it could jarring to only catch the you do not have JetStream enabled when you make a secondary call, but maybe that is ok here. Originally before domains and api prefixes it felt like the natural place to check this and return that error.