for _, document := range this.pending { go this.persist(document) } this.waiter.Wait() } func (this *Handler) persist(document projector.Document) { started := clock.UTCNow() this.writer.Write(document) metrics.Measure(DocumentWriteLatency, milliseconds(time.Since(started))) this.waiter.Done() } func milliseconds(duration time.Duration) int64 { return microseconds(duration) / 1000 } func microseconds(duration time.Duration) int64 { return int64(duration.Nanoseconds() / 1000) } func (this *Handler) sendLatestAcknowledgement(receipt interface{}) { this.output <- receipt } func (this *Handler) prepareForNextBatch() { this.pending = make(map[string]projector.Document) } var ( DepthPersistQueue = metrics.AddGauge("pipeline:persist-phase-backlog-depth", time.Second*300) DocumentsToSave = metrics.AddGauge("pipeline:documents-to-save", time.Second*300) DocumentWriteLatency = metrics.AddGauge("pipeline:document-write-latency-milliseconds", time.Second*300) )
input <-chan messaging.Delivery output chan<- projector.DocumentMessage transformer Transformer clock *clock.Clock } func NewHandler(input <-chan messaging.Delivery, output chan<- projector.DocumentMessage, transformer Transformer) *Handler { return &Handler{input: input, output: output, transformer: transformer} } func (this *Handler) Listen() { for message := range this.input { now := this.clock.UTCNow() metrics.Measure(transformQueueDepth, int64(len(this.input))) this.transformer.TransformAllDocuments(message.Message, now) if len(this.input) == 0 { this.output <- projector.DocumentMessage{ Receipt: message.Receipt, Documents: this.transformer.Collect(), } } } close(this.output) } var transformQueueDepth = metrics.AddGauge("pipeline:transform-phase-backlog-depth", time.Second*30)