@@ -19,10 +19,28 @@ type MessageSender interface {
19
19
SendMessages (msgs []* sarama.ProducerMessage ) error
20
20
}
21
21
22
+ type AsyncMessageSender struct {
23
+ sarama.AsyncProducer
24
+ logger * fflog.FFLogger
25
+ }
26
+
27
+ func (a * AsyncMessageSender ) SendMessages (msgs []* sarama.ProducerMessage ) error {
28
+ for len (msgs ) > 0 {
29
+ select {
30
+ case err := <- a .AsyncProducer .Errors ():
31
+ a .logger .Warn ("Failed to produce message: %w" , err )
32
+ case a .AsyncProducer .Input () <- msgs [0 ]:
33
+ msgs = msgs [1 :]
34
+ }
35
+ }
36
+ return nil
37
+ }
38
+
22
39
// Settings contains Kafka-specific configurations needed for message creation
23
40
type Settings struct {
24
41
Topic string `json:"topic"`
25
42
Addresses []string `json:"addresses"`
43
+ Async bool `json:"async"`
26
44
* sarama.Config
27
45
}
28
46
@@ -41,18 +59,24 @@ type Exporter struct {
41
59
// dialer will create the producer. This field is added for dependency injection during testing as sarama
42
60
// has the annoying tendency to dial as soon as a producer is created.
43
61
dialer func (addrs []string , config * sarama.Config ) (MessageSender , error )
62
+
63
+ logger * fflog.FFLogger
44
64
}
45
65
46
66
// Export will produce a message to the Kafka topic. The message's value will contain the event encoded in the
47
67
// selected format. Messages are published synchronously and will error immediately on failure.
48
- func (e * Exporter ) Export (_ context.Context , _ * fflog.FFLogger , featureEvents []exporter.FeatureEvent ) error {
68
+ func (e * Exporter ) Export (_ context.Context , logger * fflog.FFLogger , featureEvents []exporter.FeatureEvent ) error {
49
69
if e .sender == nil {
50
70
err := e .initializeProducer ()
51
71
if err != nil {
52
72
return fmt .Errorf ("writer: %w" , err )
53
73
}
54
74
}
55
75
76
+ if e .logger == nil {
77
+ e .logger = logger
78
+ }
79
+
56
80
messages := make ([]* sarama.ProducerMessage , 0 , len (featureEvents ))
57
81
for _ , event := range featureEvents {
58
82
data , err := e .formatMessage (event )
@@ -90,6 +114,13 @@ func (e *Exporter) initializeProducer() error {
90
114
if e .dialer == nil {
91
115
e .dialer = func (addrs []string , config * sarama.Config ) (MessageSender , error ) {
92
116
// Adapter for the function to comply with the MessageSender interface return
117
+ if e .Settings .Async {
118
+ asyncProducer , err := sarama .NewAsyncProducer (addrs , config )
119
+ if err != nil {
120
+ return nil , err
121
+ }
122
+ return & AsyncMessageSender {AsyncProducer : asyncProducer , logger : e .logger }, nil //TODO Close should be called on shutdown
123
+ }
93
124
return sarama .NewSyncProducer (addrs , config )
94
125
}
95
126
}
0 commit comments