@@ -2,8 +2,8 @@ package conneventhub
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
- "strings"
7
7
"sync/atomic"
8
8
"time"
9
9
@@ -14,72 +14,70 @@ import (
14
14
15
15
// multimap from ScopedEventhub to *azeventhubs.EventDataBatch
16
16
type HubBatches struct {
17
- batches map [ScopedEventhub ][ ]* azeventhubs.EventDataBatch
17
+ batch map [ScopedEventhub ]* azeventhubs.EventDataBatch
18
18
manager * EventHubManager
19
19
}
20
20
21
21
func NewHubBatches (manager * EventHubManager ) * HubBatches {
22
22
return & HubBatches {
23
- batches : make (map [ScopedEventhub ][ ]* azeventhubs.EventDataBatch ),
23
+ batch : make (map [ScopedEventhub ]* azeventhubs.EventDataBatch ),
24
24
manager : manager ,
25
25
}
26
26
}
27
27
28
- func (h * HubBatches ) AddEvent (ctx context.Context , name ScopedEventhub , event string ) error {
29
- batches , ok := h .batches [name ]
30
- if ! ok {
31
- batches = []* azeventhubs.EventDataBatch {}
32
- }
33
-
34
- if len (batches ) == 0 {
28
+ func (h * HubBatches ) AddEvent (
29
+ ctx context.Context ,
30
+ name ScopedEventhub ,
31
+ event string ,
32
+ // this is true when we are retrying to send the event after the batch size exceeded
33
+ // this should initially be false, and then true when we are retrying.
34
+ retryForBatchSizeExceed bool ,
35
+ ) error {
36
+ batch , ok := h .batch [name ]
37
+ if ! ok || batch == nil {
35
38
newBatch , err := h .manager .CreateEventDataBatch (ctx , name )
36
39
if err != nil {
37
- return err
40
+ return fmt . Errorf ( "failed to create event data batch: %v" , err )
38
41
}
39
- batches = append (batches , newBatch )
42
+ batch = newBatch
43
+ h .batch [name ] = batch
40
44
}
41
45
42
- if err := tryAddEventToBatch (event , batches [len (batches )- 1 ]); err != nil {
43
- if strings .Contains (err .Error (), "too large for the batch" ) {
44
- overflowBatch , err := h .handleBatchOverflow (ctx , name , event )
45
- if err != nil {
46
- return fmt .Errorf ("failed to handle batch overflow: %v" , err )
47
- }
48
- batches = append (batches , overflowBatch )
49
- } else {
50
- return fmt .Errorf ("failed to add event data: %v" , err )
51
- }
46
+ err := tryAddEventToBatch (event , batch )
47
+ if err == nil {
48
+ // we successfully added the event to the batch, so we're done.
49
+ return nil
52
50
}
53
51
54
- h .batches [name ] = batches
55
- return nil
56
- }
52
+ if errors .Is (err , azeventhubs .ErrEventDataTooLarge ) {
53
+ if retryForBatchSizeExceed {
54
+ // if we are already retrying, then we should just return the error
55
+ // as we have already tried to send the event to the batch.
56
+ return fmt .Errorf ("[retry-failed] event too large to add to batch: %v" , err )
57
+ }
57
58
58
- func ( h * HubBatches ) handleBatchOverflow (
59
- ctx context. Context ,
60
- name ScopedEventhub ,
61
- event string ,
62
- ) ( * azeventhubs. EventDataBatch , error ) {
63
- newBatch , err := h . manager . CreateEventDataBatch ( ctx , name )
64
- if err != nil {
65
- return nil , err
66
- }
67
- if err := tryAddEventToBatch ( event , newBatch ); err != nil {
68
- return nil , fmt .Errorf ("failed to add event data to new batch: %v" , err )
59
+ // if the event is too large, send the current batch and
60
+ // delete it from the map, so that a new batch can be created
61
+ // for the event next time.
62
+ if err := h . sendBatch ( ctx , name , batch ); err != nil {
63
+ return fmt . Errorf ( "failed to send batch: %v" , err )
64
+ }
65
+ delete ( h . batch , name )
66
+
67
+ return h . AddEvent ( ctx , name , event , true )
68
+ } else {
69
+ return fmt .Errorf ("failed to add event to batch: %v" , err )
69
70
}
70
- return newBatch , nil
71
71
}
72
72
73
73
func (h * HubBatches ) Len () int {
74
- return len (h .batches )
74
+ return len (h .batch )
75
75
}
76
76
77
77
// ForEach calls the given function for each ScopedEventhub and batch pair
78
78
func (h * HubBatches ) ForEach (fn func (ScopedEventhub , * azeventhubs.EventDataBatch )) {
79
- for name , batches := range h .batches {
80
- for _ , batch := range batches {
81
- fn (name , batch )
82
- }
79
+ for name , batch := range h .batch {
80
+ fn (name , batch )
83
81
}
84
82
}
85
83
@@ -137,14 +135,19 @@ func (h *HubBatches) flushAllBatches(
137
135
})
138
136
})
139
137
140
- log .Infof ("[sendEventBatch] successfully sent %d events in total to event hub" ,
138
+ err := g .Wait ()
139
+ log .Infof ("[flush] successfully sent %d events in total to event hub" ,
141
140
numEventsPushed )
142
- return g .Wait ()
141
+
142
+ // clear the batches after flushing them.
143
+ h .Clear ()
144
+
145
+ return err
143
146
}
144
147
145
148
// Clear removes all batches from the HubBatches
146
149
func (h * HubBatches ) Clear () {
147
- h .batches = make (map [ScopedEventhub ][ ]* azeventhubs.EventDataBatch )
150
+ h .batch = make (map [ScopedEventhub ]* azeventhubs.EventDataBatch )
148
151
}
149
152
150
153
func tryAddEventToBatch (event string , batch * azeventhubs.EventDataBatch ) error {
0 commit comments