github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/events/collector.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package events 16 17 import ( 18 "sync" 19 "sync/atomic" 20 21 "github.com/denisbrodbeck/machineid" 22 23 eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1" 24 ) 25 26 var machineID = "invalid" 27 var machineIDOnce = &sync.Once{} 28 29 // getMachineID returns a unique machine identifier hash specific to dolt 30 func getMachineID() string { 31 machineIDOnce.Do(func() { 32 id, err := machineid.ProtectedID("dolt") 33 34 if err == nil { 35 machineID = id 36 } 37 }) 38 39 return machineID 40 } 41 42 // GlobalCollector is an instance of a collector where all events should be sent via the CloseEventAndAdd function 43 var GlobalCollector = NewCollector() 44 45 const collChanBufferSize = 32 46 47 // Collector collects and stores Events later to be sent to an Emitter. 48 type Collector struct { 49 val *atomic.Value 50 wg *sync.WaitGroup 51 evtCh chan *eventsapi.ClientEvent 52 } 53 54 // NewCollector creates a new instance of a collector 55 func NewCollector() *Collector { 56 wg := &sync.WaitGroup{} 57 evtCh := make(chan *eventsapi.ClientEvent, collChanBufferSize) 58 59 c := &Collector{&atomic.Value{}, wg, evtCh} 60 61 wg.Add(1) 62 go func() { 63 defer wg.Done() 64 65 var events []*eventsapi.ClientEvent 66 for evt := range evtCh { 67 events = append(events, evt) 68 } 69 70 c.val.Store(events) 71 }() 72 73 return c 74 } 75 76 // CloseEventAndAdd closes the supplied event and adds it to the collection of events. This method is thread safe. 77 func (c *Collector) CloseEventAndAdd(evt *Event) { 78 c.evtCh <- evt.close() 79 } 80 81 // Close waits for any remaining events to finish collection and then returns a slice of ClientEvents to be passed to an 82 // emitter. 83 func (c *Collector) Close() []*eventsapi.ClientEvent { 84 close(c.evtCh) 85 86 c.wg.Wait() 87 88 interf := c.val.Load() 89 90 return interf.([]*eventsapi.ClientEvent) 91 }