NewBatcher creates a new Batcher and starts it. Here ctx controls the lifetime of the batcher, canceling it will result in the Batcher exiting it's processing routine (run).
(ctx context.Context, reg prometheus.Registerer, store database.Store, ps pubsub.Pubsub, opts ...Option)
| 132 | // NewBatcher creates a new Batcher and starts it. Here ctx controls the lifetime of the batcher, canceling it will |
| 133 | // result in the Batcher exiting it's processing routine (run). |
| 134 | func NewBatcher(ctx context.Context, reg prometheus.Registerer, store database.Store, ps pubsub.Pubsub, opts ...Option) (*Batcher, error) { |
| 135 | b := &Batcher{ |
| 136 | store: store, |
| 137 | ps: ps, |
| 138 | Metrics: NewMetrics(), |
| 139 | done: make(chan struct{}), |
| 140 | log: slog.Logger{}, |
| 141 | clock: quartz.NewReal(), |
| 142 | } |
| 143 | |
| 144 | for _, opt := range opts { |
| 145 | opt(b) |
| 146 | } |
| 147 | |
| 148 | b.Metrics.register(reg) |
| 149 | |
| 150 | if b.interval == 0 { |
| 151 | b.interval = defaultMetadataFlushInterval |
| 152 | } |
| 153 | |
| 154 | if b.maxBatchSize == 0 { |
| 155 | b.maxBatchSize = defaultMetadataBatchSize |
| 156 | } |
| 157 | |
| 158 | // Create warn ticker after options are applied so it uses the correct clock. |
| 159 | b.warnTicker = b.clock.NewTicker(10 * time.Second) |
| 160 | |
| 161 | if b.timer == nil { |
| 162 | b.timer = b.clock.NewTimer(b.interval) |
| 163 | } |
| 164 | |
| 165 | // Create buffered channel with 5x batch size capacity |
| 166 | channelSize := b.maxBatchSize * defaultChannelBufferMultiplier |
| 167 | b.updateCh = make(chan update, channelSize) |
| 168 | |
| 169 | // Initialize batch map |
| 170 | b.batch = make(map[compositeKey]value) |
| 171 | |
| 172 | b.ctx, b.cancel = context.WithCancel(ctx) |
| 173 | go func() { |
| 174 | b.run(b.ctx) |
| 175 | close(b.done) |
| 176 | }() |
| 177 | |
| 178 | return b, nil |
| 179 | } |
| 180 | |
| 181 | func (b *Batcher) Close() { |
| 182 | b.cancel() |