Skip to content
This repository was archived by the owner on Jun 4, 2021. It is now read-only.

Commit 3de76f3

Browse files
use SyncProducer to guarantee at least once delivery on the producer side (#181) (#1668)
1 parent 1c66947 commit 3de76f3

File tree

2 files changed

+14
-41
lines changed

2 files changed

+14
-41
lines changed

kafka/channel/pkg/dispatcher/dispatcher.go

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type KafkaDispatcher struct {
4646
receiver *eventingchannels.MessageReceiver
4747
dispatcher *eventingchannels.MessageDispatcherImpl
4848

49-
kafkaAsyncProducer sarama.AsyncProducer
49+
kafkaSyncProducer sarama.SyncProducer
5050
channelSubscriptions map[eventingchannels.ChannelReference][]types.UID
5151
subsConsumerGroups map[types.UID]sarama.ConsumerGroup
5252
subscriptions map[types.UID]Subscription
@@ -86,9 +86,10 @@ func NewDispatcher(ctx context.Context, args *KafkaDispatcherArgs) (*KafkaDispat
8686
conf := sarama.NewConfig()
8787
conf.Version = sarama.V2_0_0_0
8888
conf.ClientID = args.ClientID
89-
conf.Consumer.Return.Errors = true // Returns the errors in ConsumerGroup#Errors() https://godoc.org/github.com/Shopify/sarama#ConsumerGroup
89+
conf.Consumer.Return.Errors = true // Returns the errors in ConsumerGroup#Errors() https://godoc.org/github.com/Shopify/sarama#ConsumerGroup
90+
conf.Producer.Return.Successes = true // Must be enabled for sync producer
9091

91-
producer, err := sarama.NewAsyncProducer(args.Brokers, conf)
92+
producer, err := sarama.NewSyncProducer(args.Brokers, conf)
9293
if err != nil {
9394
return nil, fmt.Errorf("unable to create kafka producer against Kafka bootstrap servers %v : %v", args.Brokers, err)
9495
}
@@ -99,7 +100,7 @@ func NewDispatcher(ctx context.Context, args *KafkaDispatcherArgs) (*KafkaDispat
99100
channelSubscriptions: make(map[eventingchannels.ChannelReference][]types.UID),
100101
subsConsumerGroups: make(map[types.UID]sarama.ConsumerGroup),
101102
subscriptions: make(map[types.UID]Subscription),
102-
kafkaAsyncProducer: producer,
103+
kafkaSyncProducer: producer,
103104
logger: args.Logger,
104105
topicFunc: args.TopicFunc,
105106
}
@@ -117,8 +118,15 @@ func NewDispatcher(ctx context.Context, args *KafkaDispatcherArgs) (*KafkaDispat
117118

118119
kafkaProducerMessage.Headers = append(kafkaProducerMessage.Headers, serializeTrace(trace.FromContext(ctx).SpanContext())...)
119120

120-
dispatcher.kafkaAsyncProducer.Input() <- &kafkaProducerMessage
121-
return nil
121+
partition, offset, err := dispatcher.kafkaSyncProducer.SendMessage(&kafkaProducerMessage)
122+
123+
if err == nil {
124+
dispatcher.logger.Debugw("message sent", zap.Int32("partition", partition), zap.Int64("offset", offset))
125+
} else {
126+
dispatcher.logger.Warnw("message not sent", zap.Error(err))
127+
}
128+
129+
return err
122130
},
123131
args.Logger.Desugar(),
124132
eventingchannels.ResolveMessageChannelFromHostHeader(dispatcher.getChannelReferenceFromHost))
@@ -299,23 +307,6 @@ func (d *KafkaDispatcher) Start(ctx context.Context) error {
299307
return fmt.Errorf("message receiver is not set")
300308
}
301309

302-
if d.kafkaAsyncProducer == nil {
303-
return fmt.Errorf("kafkaAsyncProducer is not set")
304-
}
305-
306-
go func() {
307-
for {
308-
select {
309-
case e := <-d.kafkaAsyncProducer.Errors():
310-
d.logger.Warn("Got", zap.Error(e))
311-
case s := <-d.kafkaAsyncProducer.Successes():
312-
d.logger.Info("Sent", zap.Any("success", s))
313-
case <-ctx.Done():
314-
return
315-
}
316-
}
317-
}()
318-
319310
return d.receiver.Start(ctx)
320311
}
321312

kafka/channel/pkg/dispatcher/dispatcher_test.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@ package dispatcher
1919
import (
2020
"context"
2121
"errors"
22-
"net/http"
2322
"net/url"
2423
"testing"
2524

2625
"knative.dev/eventing/pkg/channel/fanout"
2726

2827
"github.com/Shopify/sarama"
29-
"github.com/cloudevents/sdk-go/v2/binding"
3028
"github.com/google/go-cmp/cmp"
3129
"github.com/google/go-cmp/cmp/cmpopts"
3230
"go.uber.org/zap"
@@ -425,26 +423,10 @@ func TestUnsubscribeUnknownSub(t *testing.T) {
425423

426424
func TestKafkaDispatcher_Start(t *testing.T) {
427425
d := &KafkaDispatcher{}
428-
429426
err := d.Start(context.TODO())
430427
if err == nil {
431428
t.Errorf("Expected error want %s, got %s", "message receiver is not set", err)
432429
}
433-
434-
receiver, err := eventingchannels.NewMessageReceiver(
435-
func(ctx context.Context, channel eventingchannels.ChannelReference, message binding.Message, _ []binding.Transformer, _ http.Header) error {
436-
return nil
437-
},
438-
zap.NewNop(),
439-
eventingchannels.ResolveMessageChannelFromHostHeader(d.getChannelReferenceFromHost))
440-
if err != nil {
441-
t.Fatalf("Error creating new message receiver. Error:%s", err)
442-
}
443-
d.receiver = receiver
444-
err = d.Start(context.TODO())
445-
if err == nil {
446-
t.Errorf("Expected error want %s, got %s", "kafkaAsyncProducer is not set", err)
447-
}
448430
}
449431

450432
func TestNewDispatcher(t *testing.T) {

0 commit comments

Comments
 (0)