From 2b8a94a5c4e83b645c3865e9ccea280200bbd358 Mon Sep 17 00:00:00 2001 From: Aliaksandr Hrechny <8013455+grechny@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:06:54 +0200 Subject: [PATCH] fix(events/natsjs): default to auto ack Match the documented events contract and other stream implementations. Fixes #164 Signed-off-by: Aliaksandr Hrechny <8013455+grechny@users.noreply.github.com> --- v4/events/natsjs/nats.go | 3 +- v4/events/natsjs/nats_test.go | 70 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/v4/events/natsjs/nats.go b/v4/events/natsjs/nats.go index 3deadfde..ac279d2c 100644 --- a/v4/events/natsjs/nats.go +++ b/v4/events/natsjs/nats.go @@ -160,7 +160,8 @@ func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (<-chan eve // parse the options options := events.ConsumeOptions{ - Group: uuid.New().String(), + Group: uuid.New().String(), + AutoAck: true, } for _, o := range opts { o(&options) diff --git a/v4/events/natsjs/nats_test.go b/v4/events/natsjs/nats_test.go index 6be9053c..7a29691a 100644 --- a/v4/events/natsjs/nats_test.go +++ b/v4/events/natsjs/nats_test.go @@ -10,6 +10,7 @@ import ( "github.com/go-micro/plugins/v4/events/natsjs" nserver "github.com/nats-io/nats-server/v2/server" + "github.com/nats-io/nats.go" "github.com/stretchr/testify/assert" "github.com/test-go/testify/require" "go-micro.dev/v4/events" @@ -20,6 +21,75 @@ type Payload struct { Name string `json:"name"` } +func TestConsumeAckPolicy(t *testing.T) { + ctx, cancel := context.WithCancel(context.TODO()) + defer cancel() + + clusterName := "test-cluster" + natsAddr := getFreeLocalhostAddress() + natsPort, _ := strconv.Atoi(strings.Split(natsAddr, ":")[1]) + + go natsServer(ctx, + t, + &nserver.Options{ + Host: strings.Split(natsAddr, ":")[0], + Port: natsPort, + Cluster: nserver.ClusterOpts{ + Name: clusterName, + }, + }, + ) + + time.Sleep(1 * time.Second) + + client, err := natsjs.NewStream( + natsjs.Address(natsAddr), + natsjs.ClusterID(clusterName), + ) + require.NoError(t, err) + + tests := []struct { + name string + topic string + group string + opts []events.ConsumeOption + expected nats.AckPolicy + }{ + { + name: "defaults to auto ack", + topic: "default-auto-ack", + group: "default-auto-ack-consumer", + expected: nats.AckNonePolicy, + }, + { + name: "allows manual ack", + topic: "manual-ack", + group: "manual-ack-consumer", + opts: []events.ConsumeOption{events.WithAutoAck(false, time.Second)}, + expected: nats.AckExplicitPolicy, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := append([]events.ConsumeOption{events.WithGroup(tt.group)}, tt.opts...) + _, err := client.Consume(tt.topic, opts...) + require.NoError(t, err) + + nc, err := nats.Connect(natsAddr) + require.NoError(t, err) + defer nc.Close() + + js, err := nc.JetStream() + require.NoError(t, err) + + info, err := js.ConsumerInfo(tt.topic, tt.group) + require.NoError(t, err) + assert.Equal(t, tt.expected, info.Config.AckPolicy) + }) + } +} + func TestSingleEvent(t *testing.T) { ctx, cancel := context.WithCancel(context.TODO()) defer cancel()