@@ -18,7 +18,6 @@ import (
18
18
"context"
19
19
20
20
"github.com/Shopify/sarama"
21
- "github.com/google/uuid"
22
21
"google.golang.org/grpc/codes"
23
22
24
23
"go.opentelemetry.io/otel/api/kv"
@@ -104,16 +103,25 @@ func (p *asyncProducer) Errors() <-chan *sarama.ProducerError {
104
103
105
104
// AsyncClose async close producer.
106
105
func (p * asyncProducer ) AsyncClose () {
107
- p .close <- closeAsync
106
+ p .input <- & sarama.ProducerMessage {
107
+ Metadata : closeAsync ,
108
+ }
108
109
}
109
110
110
111
// Close shuts down the producer and waits for any buffered messages to be
111
112
// flushed.
112
113
func (p * asyncProducer ) Close () error {
113
- p .close <- closeSync
114
+ p .input <- & sarama.ProducerMessage {
115
+ Metadata : closeSync ,
116
+ }
114
117
return <- p .closeErr
115
118
}
116
119
120
+ type producerMessageContext struct {
121
+ span trace.Span
122
+ metadataBackup interface {}
123
+ }
124
+
117
125
// WrapAsyncProducer wraps a sarama.AsyncProducer so that all produced messages
118
126
// are traced. It requires the underlying sarama Config so we can know whether
119
127
// or not successes will be returned.
@@ -135,26 +143,42 @@ func WrapAsyncProducer(serviceName string, saramaConfig *sarama.Config, p sarama
135
143
closeErr : make (chan error ),
136
144
}
137
145
go func () {
138
- spans := make (map [interface {}]trace. Span )
146
+ producerMessageContexts := make (map [interface {}]producerMessageContext )
139
147
defer close (wrapped .successes )
140
148
defer close (wrapped .errors )
141
149
for {
142
150
select {
143
- case t := <- wrapped .close :
144
- switch t {
145
- case closeSync :
146
- go func () {
147
- wrapped .closeErr <- p .Close ()
148
- }()
149
- case closeAsync :
150
- p .AsyncClose ()
151
- }
152
151
case msg := <- wrapped .input :
153
- msg .Metadata = uuid .New ()
152
+ // Shut down if message metadata is a close type.
153
+ // Sarama will close after dispatching every message.
154
+ // So wrapper should follow this mechanism by adding a special message at
155
+ // the end of the input channel.
156
+ if ct , ok := msg .Metadata .(closeType ); ok {
157
+ switch ct {
158
+ case closeSync :
159
+ go func () {
160
+ wrapped .closeErr <- p .Close ()
161
+ }()
162
+ case closeAsync :
163
+ p .AsyncClose ()
164
+ }
165
+ continue
166
+ }
167
+
154
168
span := startProducerSpan (cfg , saramaConfig .Version , msg )
169
+
170
+ // Create message context, backend message metadata
171
+ mc := producerMessageContext {
172
+ metadataBackup : msg .Metadata ,
173
+ span : span ,
174
+ }
175
+
176
+ // Specific metadata with span id
177
+ msg .Metadata = span .SpanContext ().SpanID
178
+
155
179
p .Input () <- msg
156
180
if saramaConfig .Producer .Return .Successes {
157
- spans [msg .Metadata ] = span
181
+ producerMessageContexts [msg .Metadata ] = mc
158
182
} else {
159
183
// If returning successes isn't enabled, we just finish the
160
184
// span right away because there's no way to know when it will
@@ -167,9 +191,12 @@ func WrapAsyncProducer(serviceName string, saramaConfig *sarama.Config, p sarama
167
191
return
168
192
}
169
193
key := msg .Metadata
170
- if span , ok := spans [key ]; ok {
171
- delete (spans , key )
172
- finishProducerSpan (span , msg .Partition , msg .Offset , nil )
194
+ if mc , ok := producerMessageContexts [key ]; ok {
195
+ delete (producerMessageContexts , key )
196
+ finishProducerSpan (mc .span , msg .Partition , msg .Offset , nil )
197
+
198
+ // Restore message metadata
199
+ msg .Metadata = mc .metadataBackup
173
200
}
174
201
wrapped .successes <- msg
175
202
case err , ok := <- p .Errors ():
@@ -178,9 +205,9 @@ func WrapAsyncProducer(serviceName string, saramaConfig *sarama.Config, p sarama
178
205
return
179
206
}
180
207
key := err .Msg .Metadata
181
- if span , ok := spans [key ]; ok {
182
- delete (spans , key )
183
- finishProducerSpan (span , err .Msg .Partition , err .Msg .Offset , err .Err )
208
+ if mc , ok := producerMessageContexts [key ]; ok {
209
+ delete (producerMessageContexts , key )
210
+ finishProducerSpan (mc . span , err .Msg .Partition , err .Msg .Offset , err .Err )
184
211
}
185
212
wrapped .errors <- err
186
213
}
0 commit comments