github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/event/filter/eth_filter.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package filter 18 19 // TODO make use of the generic filtering system 20 21 import ( 22 "sync" 23 24 "github.com/ethereum/go-ethereum/core" 25 "github.com/ethereum/go-ethereum/core/state" 26 "github.com/ethereum/go-ethereum/event" 27 ) 28 29 type FilterManager struct { 30 eventMux *event.TypeMux 31 32 filterMu sync.RWMutex 33 filterId int 34 filters map[int]*core.Filter 35 36 quit chan struct{} 37 } 38 39 func NewFilterManager(mux *event.TypeMux) *FilterManager { 40 return &FilterManager{ 41 eventMux: mux, 42 filters: make(map[int]*core.Filter), 43 } 44 } 45 46 func (self *FilterManager) Start() { 47 go self.filterLoop() 48 } 49 50 func (self *FilterManager) Stop() { 51 close(self.quit) 52 } 53 54 func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) { 55 self.filterMu.Lock() 56 defer self.filterMu.Unlock() 57 id = self.filterId 58 self.filters[id] = filter 59 self.filterId++ 60 61 return id 62 } 63 64 func (self *FilterManager) UninstallFilter(id int) { 65 self.filterMu.Lock() 66 defer self.filterMu.Unlock() 67 if _, ok := self.filters[id]; ok { 68 delete(self.filters, id) 69 } 70 } 71 72 // GetFilter retrieves a filter installed using InstallFilter. 73 // The filter may not be modified. 74 func (self *FilterManager) GetFilter(id int) *core.Filter { 75 self.filterMu.RLock() 76 defer self.filterMu.RUnlock() 77 return self.filters[id] 78 } 79 80 func (self *FilterManager) filterLoop() { 81 // Subscribe to events 82 events := self.eventMux.Subscribe( 83 //core.PendingBlockEvent{}, 84 core.ChainEvent{}, 85 core.TxPreEvent{}, 86 state.Logs(nil)) 87 88 out: 89 for { 90 select { 91 case <-self.quit: 92 break out 93 case event := <-events.Chan(): 94 switch event := event.(type) { 95 case core.ChainEvent: 96 self.filterMu.RLock() 97 for _, filter := range self.filters { 98 if filter.BlockCallback != nil { 99 filter.BlockCallback(event.Block, event.Logs) 100 } 101 } 102 self.filterMu.RUnlock() 103 104 case core.TxPreEvent: 105 self.filterMu.RLock() 106 for _, filter := range self.filters { 107 if filter.TransactionCallback != nil { 108 filter.TransactionCallback(event.Tx) 109 } 110 } 111 self.filterMu.RUnlock() 112 113 case state.Logs: 114 self.filterMu.RLock() 115 for _, filter := range self.filters { 116 if filter.LogsCallback != nil { 117 msgs := filter.FilterLogs(event) 118 if len(msgs) > 0 { 119 filter.LogsCallback(msgs) 120 } 121 } 122 } 123 self.filterMu.RUnlock() 124 } 125 } 126 } 127 }