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  }