@@ -87,7 +87,10 @@ type LogAggregator struct {
87
87
streamRequests chan streamRequest
88
88
89
89
// sink is a sink to send aggregated flows to.
90
- sink Sink
90
+ sink bucketing.Sink
91
+
92
+ // sinkChan allows setting the sink asynchronously.
93
+ sinkChan chan bucketing.Sink
91
94
92
95
// recvChan is the channel to receive flow updates on.
93
96
recvChan chan * proto.FlowUpdate
@@ -124,6 +127,7 @@ func NewLogAggregator(opts ...Option) *LogAggregator {
124
127
listRequests : make (chan listRequest ),
125
128
streamRequests : make (chan streamRequest ),
126
129
recvChan : make (chan * proto.FlowUpdate , channelDepth ),
130
+ sinkChan : make (chan bucketing.Sink , 10 ),
127
131
rolloverFunc : time .After ,
128
132
bucketsToAggregate : 20 ,
129
133
pushIndex : 30 ,
@@ -195,7 +199,7 @@ func (a *LogAggregator) Run(startTime int64) {
195
199
a .handleFlowUpdate (upd )
196
200
case <- rolloverCh :
197
201
rolloverCh = a .rolloverFunc (a .rollover ())
198
- a .maybeEmitFlows ( )
202
+ a .buckets . EmitFlowCollections ( a . sink )
199
203
case req := <- a .listRequests :
200
204
req .respCh <- a .queryFlows (req .req )
201
205
case req := <- a .streamRequests :
@@ -204,13 +208,21 @@ func (a *LogAggregator) Run(startTime int64) {
204
208
a .backfill (stream , req .req )
205
209
case id := <- a .streams .closedStreams ():
206
210
a .streams .close (id )
211
+ case sink := <- a .sinkChan :
212
+ logrus .WithField ("sink" , sink ).Info ("Setting aggregator sink" )
213
+ a .sink = sink
214
+ a .buckets .EmitFlowCollections (a .sink )
207
215
case <- a .done :
208
216
logrus .Warn ("Aggregator shutting down" )
209
217
return
210
218
}
211
219
}
212
220
}
213
221
222
+ func (a * LogAggregator ) SetSink (s bucketing.Sink ) {
223
+ a .sinkChan <- s
224
+ }
225
+
214
226
// Receive is used to send a flow update to the aggregator.
215
227
func (a * LogAggregator ) Receive (f * proto.FlowUpdate ) {
216
228
timeout := time .After (5 * time .Second )
@@ -222,25 +234,6 @@ func (a *LogAggregator) Receive(f *proto.FlowUpdate) {
222
234
}
223
235
}
224
236
225
- func (a * LogAggregator ) maybeEmitFlows () {
226
- if a .sink == nil {
227
- logrus .Debug ("No sink configured, skip flow emission" )
228
- return
229
- }
230
-
231
- flows := a .buckets .FlowCollection ()
232
- if flows == nil {
233
- // We've already pushed this bucket, so we can skip it. We'll emit the next flow once
234
- // bucketsToAggregate buckets have been rolled over.
235
- logrus .Debug ("Delaying flow emission, no new flows to emit" )
236
- return
237
- }
238
-
239
- if len (flows .Flows ) > 0 {
240
- a .sink .Receive (flows )
241
- }
242
- }
243
-
244
237
// Stream returns a new Stream from the aggregator. It uses a channel to synchronously request the stream
245
238
// from the aggregator.
246
239
func (a * LogAggregator ) Stream (req * proto.FlowStreamRequest ) (* Stream , error ) {
0 commit comments