Skip to content

Commit 6902961

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

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

server/consumer.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -5360,12 +5360,18 @@ func (o *consumer) selectStartingSeqNo() {
53605360
o.sseq = o.cfg.OptStartSeq
53615361
}
53625362

5363-
if state.FirstSeq == 0 {
5363+
if state.FirstSeq == 0 && (o.cfg.Direct || o.cfg.OptStartSeq == 0) {
5364+
// If the stream is empty, deliver only new.
5365+
// But only if mirroring/sourcing, or start seq is unset, otherwise need to respect provided value.
53645366
o.sseq = 1
5367+
} else if o.sseq > state.LastSeq && (o.cfg.Direct || o.cfg.OptStartSeq == 0) {
5368+
// If selected sequence is in the future, clamp back down.
5369+
// But only if mirroring/sourcing, or start seq is unset, otherwise need to respect provided value.
5370+
o.sseq = state.LastSeq + 1
53655371
} else if o.sseq < state.FirstSeq {
5372+
// If the first sequence is further ahead than the starting sequence,
5373+
// there are no messages there anymore, so move the sequence up.
53665374
o.sseq = state.FirstSeq
5367-
} else if o.sseq > state.LastSeq {
5368-
o.sseq = state.LastSeq + 1
53695375
}
53705376
}
53715377

server/jetstream_cluster_1_test.go

+54
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import (
3333
"testing"
3434
"time"
3535

36+
"github.com/nats-io/nats.go/jetstream"
37+
3638
"github.com/nats-io/jwt/v2"
3739
"github.com/nats-io/nats.go"
3840
)
@@ -6942,6 +6944,58 @@ func TestJetStreamClusterConsumerInfoAfterCreate(t *testing.T) {
69426944
require_NoError(t, err)
69436945
}
69446946

6947+
func TestJetStreamClusterRespectConsumerStartSeq(t *testing.T) {
6948+
c := createJetStreamClusterExplicit(t, "R3S", 3)
6949+
defer c.shutdown()
6950+
6951+
nc := clientConnectToServer(t, c.randomServer())
6952+
defer nc.Close()
6953+
js, err := jetstream.New(nc)
6954+
require_NoError(t, err)
6955+
6956+
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
6957+
defer cancel()
6958+
6959+
// Create replicated stream.
6960+
_, err = js.CreateStream(ctx, jetstream.StreamConfig{
6961+
Name: "TEST",
6962+
Subjects: []string{"foo"},
6963+
Replicas: 3,
6964+
})
6965+
require_NoError(t, err)
6966+
6967+
// We could have published messages into the stream that have not yet been applied on the follower.
6968+
// If we create a consumer with a starting sequence in the future, we must respect it.
6969+
consumer, err := js.OrderedConsumer(ctx, "TEST", jetstream.OrderedConsumerConfig{
6970+
DeliverPolicy: jetstream.DeliverByStartSequencePolicy,
6971+
OptStartSeq: 20,
6972+
})
6973+
require_NoError(t, err)
6974+
require_Equal(t, consumer.CachedInfo().Delivered.Stream, 19)
6975+
6976+
// Same thing if the first sequence is not 0.
6977+
stream, err := js.Stream(ctx, "TEST")
6978+
require_NoError(t, err)
6979+
err = stream.Purge(ctx, jetstream.WithPurgeSequence(10))
6980+
require_NoError(t, err)
6981+
6982+
consumer, err = js.OrderedConsumer(ctx, "TEST", jetstream.OrderedConsumerConfig{
6983+
DeliverPolicy: jetstream.DeliverByStartSequencePolicy,
6984+
OptStartSeq: 20,
6985+
})
6986+
require_NoError(t, err)
6987+
require_Equal(t, consumer.CachedInfo().Delivered.Stream, 19)
6988+
6989+
// Only if we're requested to start at a sequence that's not available anymore
6990+
// can we safely move it up. That data is gone already, so can't do anything else.
6991+
consumer, err = js.OrderedConsumer(ctx, "TEST", jetstream.OrderedConsumerConfig{
6992+
DeliverPolicy: jetstream.DeliverByStartSequencePolicy,
6993+
OptStartSeq: 5,
6994+
})
6995+
require_NoError(t, err)
6996+
require_Equal(t, consumer.CachedInfo().Delivered.Stream, 9)
6997+
}
6998+
69456999
//
69467000
// DO NOT ADD NEW TESTS IN THIS FILE (unless to balance test times)
69477001
// Add at the end of jetstream_cluster_<n>_test.go, with <n> being the highest value.

0 commit comments

Comments
 (0)