-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
(2.11) JetStream API routed queue changes #6342
base: main
Are you sure you want to change the base?
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 |
---|---|---|
|
@@ -890,9 +890,30 @@ func (js *jetStream) apiDispatch(sub *subscription, c *client, acc *Account, sub | |
// Copy the state. Note the JSAPI only uses the hdr index to piece apart the | ||
// header from the msg body. No other references are needed. | ||
// Check pending and warn if getting backed up. | ||
retry: | ||
pending, _ := s.jsAPIRoutedReqs.push(&jsAPIRoutedReq{jsub, sub, acc, subject, reply, copyBytes(rmsg), c.pa}) | ||
limit := atomic.LoadInt64(&js.queueLimit) | ||
if pending >= int(limit) { | ||
if _, ok := s.jsAPIRoutedReqs.popOne(); ok { | ||
// If we were able to take one of the oldest items off the queue, then | ||
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 the code is no longer properly updating the You have introduced quite recently ability to limit the ipQueue with making the push() fail when above that limit, why not using this instead of some arbitrary limit leading to a drain? |
||
// retry the insert. | ||
s.rateLimitFormatWarnf("JetStream API queue limit reached, dropping oldest request") | ||
s.publishAdvisory(nil, JSAdvisoryAPILimitReached, JSAPILimitReachedAdvisory{ | ||
TypedEvent: TypedEvent{ | ||
Type: JSAPILimitReachedAdvisoryType, | ||
ID: nuid.Next(), | ||
Time: time.Now().UTC(), | ||
}, | ||
Server: s.Name(), | ||
Domain: js.config.Domain, | ||
Dropped: 1, | ||
}) | ||
goto retry | ||
} | ||
|
||
// It's likely not possible to get to this point, but if for some reason we have got here, | ||
// then something is wrong for us to be both over the limit but unable to pull entries, so | ||
// throw everything away and hope we recover from it. | ||
s.rateLimitFormatWarnf("JetStream API queue limit reached, dropping %d requests", pending) | ||
s.jsAPIRoutedReqs.drain() | ||
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. Clearly the |
||
|
||
|
@@ -922,8 +943,10 @@ func (s *Server) processJSAPIRoutedRequests() { | |
for { | ||
select { | ||
case <-queue.ch: | ||
reqs := queue.pop() | ||
for _, r := range reqs { | ||
// Only pop one item at a time here, otherwise if the system is recovering | ||
// from queue buildup, then one worker will pull off all the tasks and the | ||
// others will be starved of work. | ||
for r, ok := queue.popOneLast(); ok && r != nil; r, ok = queue.popOneLast() { | ||
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 was going to say that this seems wrong: picture a |
||
client.pa = r.pa | ||
start := time.Now() | ||
r.jsub.icb(r.sub, client, r.acc, r.subject, r.reply, r.msg) | ||
|
@@ -932,7 +955,6 @@ func (s *Server) processJSAPIRoutedRequests() { | |
} | ||
atomic.AddInt64(&js.apiInflight, -1) | ||
} | ||
queue.recycle(&reqs) | ||
case <-s.quitCh: | ||
return | ||
} | ||
|
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.
nit:
popLast()
may be enough.Adding a test for this new API would be a good thing, for instance making sure that we can do popOne() and popLast() mixed for instance.