Skip to content

Commit 31b599f

Browse files
[FIXED] Respect consumer's starting seq, even if in the future
Signed-off-by: Maurice van Veen <github@mauricevanveen.com>
1 parent 87e32fe commit 31b599f

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

server/consumer.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -5366,12 +5366,18 @@ func (o *consumer) selectStartingSeqNo() {
53665366
o.sseq = o.cfg.OptStartSeq
53675367
}
53685368

5369-
if state.FirstSeq == 0 {
5369+
if state.FirstSeq == 0 && (o.cfg.Direct || o.cfg.OptStartSeq == 0) {
5370+
// If the stream is empty, deliver only new.
5371+
// But only if mirroring/sourcing, or start seq is unset, otherwise need to respect provided value.
53705372
o.sseq = 1
5373+
} else if o.sseq > state.LastSeq && (o.cfg.Direct || o.cfg.OptStartSeq == 0) {
5374+
// If selected sequence is in the future, clamp back down.
5375+
// But only if mirroring/sourcing, or start seq is unset, otherwise need to respect provided value.
5376+
o.sseq = state.LastSeq + 1
53715377
} else if o.sseq < state.FirstSeq {
5378+
// If the first sequence is further ahead than the starting sequence,
5379+
// there are no messages there anymore, so move the sequence up.
53725380
o.sseq = state.FirstSeq
5373-
} else if o.sseq > state.LastSeq {
5374-
o.sseq = state.LastSeq + 1
53755381
}
53765382
}
53775383

server/jetstream_cluster_1_test.go

+45
Original file line numberDiff line numberDiff line change
@@ -6984,6 +6984,51 @@ func TestJetStreamClusterDontSnapshotTooOften(t *testing.T) {
69846984
}
69856985
}
69866986

6987+
func TestJetStreamClusterRespectConsumerStartSeq(t *testing.T) {
6988+
c := createJetStreamClusterExplicit(t, "R3S", 3)
6989+
defer c.shutdown()
6990+
6991+
nc, js := jsClientConnect(t, c.randomServer())
6992+
defer nc.Close()
6993+
6994+
// Create replicated stream.
6995+
_, err := js.AddStream(&nats.StreamConfig{
6996+
Name: "TEST",
6997+
Subjects: []string{"foo"},
6998+
Replicas: 3,
6999+
})
7000+
require_NoError(t, err)
7001+
7002+
// We could have published messages into the stream that have not yet been applied on the follower.
7003+
// If we create a consumer with a starting sequence in the future, we must respect it.
7004+
ci, err := js.AddConsumer("TEST", &nats.ConsumerConfig{
7005+
DeliverPolicy: nats.DeliverByStartSequencePolicy,
7006+
OptStartSeq: 20,
7007+
})
7008+
require_NoError(t, err)
7009+
require_Equal(t, ci.Delivered.Stream, 19)
7010+
7011+
// Same thing if the first sequence is not 0.
7012+
err = js.PurgeStream("TEST", &nats.StreamPurgeRequest{Sequence: 10})
7013+
require_NoError(t, err)
7014+
7015+
ci, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
7016+
DeliverPolicy: nats.DeliverByStartSequencePolicy,
7017+
OptStartSeq: 20,
7018+
})
7019+
require_NoError(t, err)
7020+
require_Equal(t, ci.Delivered.Stream, 19)
7021+
7022+
// Only if we're requested to start at a sequence that's not available anymore
7023+
// can we safely move it up. That data is gone already, so can't do anything else.
7024+
ci, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
7025+
DeliverPolicy: nats.DeliverByStartSequencePolicy,
7026+
OptStartSeq: 5,
7027+
})
7028+
require_NoError(t, err)
7029+
require_Equal(t, ci.Delivered.Stream, 9)
7030+
}
7031+
69877032
//
69887033
// DO NOT ADD NEW TESTS IN THIS FILE (unless to balance test times)
69897034
// Add at the end of jetstream_cluster_<n>_test.go, with <n> being the highest value.

0 commit comments

Comments
 (0)