github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/event/filter/eth_filter.go (about) 1 package filter 2 3 // TODO make use of the generic filtering system 4 5 import ( 6 "sync" 7 8 "github.com/jonasnick/go-ethereum/core" 9 "github.com/jonasnick/go-ethereum/event" 10 "github.com/jonasnick/go-ethereum/state" 11 ) 12 13 type FilterManager struct { 14 eventMux *event.TypeMux 15 16 filterMu sync.RWMutex 17 filterId int 18 filters map[int]*core.Filter 19 20 quit chan struct{} 21 } 22 23 func NewFilterManager(mux *event.TypeMux) *FilterManager { 24 return &FilterManager{ 25 eventMux: mux, 26 filters: make(map[int]*core.Filter), 27 } 28 } 29 30 func (self *FilterManager) Start() { 31 go self.filterLoop() 32 } 33 34 func (self *FilterManager) Stop() { 35 close(self.quit) 36 } 37 38 func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) { 39 self.filterMu.Lock() 40 id = self.filterId 41 self.filters[id] = filter 42 self.filterId++ 43 self.filterMu.Unlock() 44 return id 45 } 46 47 func (self *FilterManager) UninstallFilter(id int) { 48 self.filterMu.Lock() 49 delete(self.filters, id) 50 self.filterMu.Unlock() 51 } 52 53 // GetFilter retrieves a filter installed using InstallFilter. 54 // The filter may not be modified. 55 func (self *FilterManager) GetFilter(id int) *core.Filter { 56 self.filterMu.RLock() 57 defer self.filterMu.RUnlock() 58 return self.filters[id] 59 } 60 61 func (self *FilterManager) filterLoop() { 62 // Subscribe to events 63 events := self.eventMux.Subscribe(core.PendingBlockEvent{}, core.NewBlockEvent{}, state.Logs(nil)) 64 65 out: 66 for { 67 select { 68 case <-self.quit: 69 break out 70 case event := <-events.Chan(): 71 switch event := event.(type) { 72 case core.NewBlockEvent: 73 self.filterMu.RLock() 74 for _, filter := range self.filters { 75 if filter.BlockCallback != nil { 76 filter.BlockCallback(event.Block) 77 } 78 } 79 self.filterMu.RUnlock() 80 81 case core.PendingBlockEvent: 82 self.filterMu.RLock() 83 for _, filter := range self.filters { 84 if filter.PendingCallback != nil { 85 filter.PendingCallback(event.Block) 86 } 87 } 88 self.filterMu.RUnlock() 89 90 case state.Logs: 91 self.filterMu.RLock() 92 for _, filter := range self.filters { 93 if filter.LogsCallback != nil { 94 msgs := filter.FilterLogs(event) 95 if len(msgs) > 0 { 96 filter.LogsCallback(msgs) 97 } 98 } 99 } 100 self.filterMu.RUnlock() 101 } 102 } 103 } 104 }