Make the merges consumer before the events consumer narrows, from the old one's ack floor, so no merge is lost to the change (issue 973)
mesh/merge-gate head 20e14872ef1e merged into trunk b0d489a86c23 — pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus…
mesh/repo-check head 20e14872ef1e merged into trunk b0d489a86c23 — fail: its merge-check.sh failed: --- FAIL: TestSSHClientOwnsTheOperatorsSSHConfig (0.07s…
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate head 20e14872ef1e merged into trunk b0d489a86c23 — pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus…
mesh/repo-check head 20e14872ef1e merged into trunk b0d489a86c23 — fail: its merge-check.sh failed: --- FAIL: TestSSHClientOwnsTheOperatorsSSHConfig (0.07s…
mesh/delivery superseded: a newer head of the same pull request
This commit is contained in:
@@ -343,6 +343,9 @@ func (j *JetStream) EnsureConsumer(c Consumer) error {
|
||||
if c.FromNow {
|
||||
want.DeliverPolicy = nats.DeliverNewPolicy
|
||||
}
|
||||
if from := j.ackFloorOfTheConsumerItTakesOver(c); from > 0 {
|
||||
want.DeliverPolicy, want.OptStartSeq = nats.DeliverByStartSequencePolicy, from
|
||||
}
|
||||
if _, err := j.js.AddConsumer(c.Stream, want); err != nil {
|
||||
return fmt.Errorf("creating consumer %s on %s: %w", c.Name, c.Stream, err)
|
||||
}
|
||||
@@ -352,6 +355,26 @@ func (j *JetStream) EnsureConsumer(c Consumer) error {
|
||||
}
|
||||
}
|
||||
|
||||
// ackFloorOfTheConsumerItTakesOver is the stream sequence a consumer made now starts at so as to lose nothing the
|
||||
// consumer it takes over from (Consumer.TakesOverFrom) has not acknowledged: that consumer's ack floor plus one, when
|
||||
// it exists and still filters this one's subject; zero otherwise.
|
||||
func (j *JetStream) ackFloorOfTheConsumerItTakesOver(c Consumer) uint64 {
|
||||
if c.TakesOverFrom == "" || len(c.Filters) != 1 {
|
||||
return 0
|
||||
}
|
||||
have, err := j.js.ConsumerInfo(c.Stream, c.TakesOverFrom)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
filters := append([]string{have.Config.FilterSubject}, have.Config.FilterSubjects...)
|
||||
for _, f := range filters {
|
||||
if f == c.Filters[0] {
|
||||
return have.AckFloor.Stream + 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// ConsumerState is what a reset says about a consumer, before and after.
|
||||
type ConsumerState struct {
|
||||
DeliverPolicy string
|
||||
|
||||
Reference in New Issue
Block a user