package databroker import ( "context" "github.com/pomerium/pomerium/internal/log" ) // fastForwardHandler will skip type fastForwardHandler struct { handler SyncerHandler in chan *ffCmd exec chan *ffCmd } type ffCmd struct { clearRecords bool serverVersion uint64 records []*Record } func newFastForwardHandler(ctx context.Context, handler SyncerHandler) SyncerHandler { ff := &fastForwardHandler{ handler: handler, in: make(chan *ffCmd, 20), exec: make(chan *ffCmd), } go ff.runSelect(ctx) go ff.runExec(ctx) return ff } func (ff *fastForwardHandler) update(ctx context.Context, c *ffCmd) { ff.handler.UpdateRecords(ctx, c.serverVersion, c.records) } func (ff *fastForwardHandler) runSelect(ctx context.Context) { var update *ffCmd for { if update == nil { select { case <-ctx.Done(): return case update = <-ff.in: } } else { select { case <-ctx.Done(): return case update = <-ff.in: case ff.exec <- update: update = nil } } } } func (ff *fastForwardHandler) runExec(ctx context.Context) { for { select { case <-ctx.Done(): return case update := <-ff.exec: if update.clearRecords { ff.handler.ClearRecords(ctx) continue } ff.update(ctx, update) } } } func (ff *fastForwardHandler) GetDataBrokerServiceClient() DataBrokerServiceClient { return ff.handler.GetDataBrokerServiceClient() } func (ff *fastForwardHandler) ClearRecords(ctx context.Context) { select { case <-ctx.Done(): log.Error(ctx). Msg("ff_handler: ClearRecords: context canceled") case ff.exec <- &ffCmd{clearRecords: true}: } } func (ff *fastForwardHandler) UpdateRecords(ctx context.Context, serverVersion uint64, records []*Record) { select { case <-ctx.Done(): log.Error(ctx). Msg("ff_handler: UpdateRecords: context canceled") case ff.in <- &ffCmd{serverVersion: serverVersion, records: records}: } }