github.com/okex/exchain@v1.8.0/libs/tendermint/types/event_bus.go (about)

     1  package types
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/okex/exchain/libs/tendermint/abci/types"
     8  	"github.com/okex/exchain/libs/tendermint/libs/log"
     9  	tmpubsub "github.com/okex/exchain/libs/tendermint/libs/pubsub"
    10  	"github.com/okex/exchain/libs/tendermint/libs/service"
    11  )
    12  
    13  const defaultCapacity = 0
    14  
    15  type EventBusSubscriber interface {
    16  	Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, outCapacity ...int) (Subscription, error)
    17  	Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error
    18  	UnsubscribeAll(ctx context.Context, subscriber string) error
    19  
    20  	NumClients() int
    21  	NumClientSubscriptions(clientID string) int
    22  }
    23  
    24  type Subscription interface {
    25  	Out() <-chan tmpubsub.Message
    26  	Cancelled() <-chan struct{}
    27  	Err() error
    28  }
    29  
    30  // EventBus is a common bus for all events going through the system. All calls
    31  // are proxied to underlying pubsub server. All events must be published using
    32  // EventBus to ensure correct data types.
    33  type EventBus struct {
    34  	service.BaseService
    35  	pubsub *tmpubsub.Server
    36  }
    37  
    38  // NewEventBus returns a new event bus.
    39  func NewEventBus() *EventBus {
    40  	return NewEventBusWithBufferCapacity(defaultCapacity)
    41  }
    42  
    43  // NewEventBusWithBufferCapacity returns a new event bus with the given buffer capacity.
    44  func NewEventBusWithBufferCapacity(cap int) *EventBus {
    45  	// capacity could be exposed later if needed
    46  	pubsub := tmpubsub.NewServer(tmpubsub.BufferCapacity(cap))
    47  	b := &EventBus{pubsub: pubsub}
    48  	b.BaseService = *service.NewBaseService(nil, "EventBus", b)
    49  	return b
    50  }
    51  
    52  func (b *EventBus) SetLogger(l log.Logger) {
    53  	b.BaseService.SetLogger(l)
    54  	b.pubsub.SetLogger(l.With("module", "pubsub"))
    55  }
    56  
    57  func (b *EventBus) OnStart() error {
    58  	return b.pubsub.Start()
    59  }
    60  
    61  func (b *EventBus) OnStop() {
    62  	b.pubsub.Stop()
    63  }
    64  
    65  func (b *EventBus) NumClients() int {
    66  	return b.pubsub.NumClients()
    67  }
    68  
    69  func (b *EventBus) NumClientSubscriptions(clientID string) int {
    70  	return b.pubsub.NumClientSubscriptions(clientID)
    71  }
    72  
    73  func (b *EventBus) Subscribe(
    74  	ctx context.Context,
    75  	subscriber string,
    76  	query tmpubsub.Query,
    77  	outCapacity ...int,
    78  ) (Subscription, error) {
    79  	return b.pubsub.Subscribe(ctx, subscriber, query, outCapacity...)
    80  }
    81  
    82  // This method can be used for a local consensus explorer and synchronous
    83  // testing. Do not use for for public facing / untrusted subscriptions!
    84  func (b *EventBus) SubscribeUnbuffered(
    85  	ctx context.Context,
    86  	subscriber string,
    87  	query tmpubsub.Query,
    88  ) (Subscription, error) {
    89  	return b.pubsub.SubscribeUnbuffered(ctx, subscriber, query)
    90  }
    91  
    92  func (b *EventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error {
    93  	return b.pubsub.Unsubscribe(ctx, subscriber, query)
    94  }
    95  
    96  func (b *EventBus) UnsubscribeAll(ctx context.Context, subscriber string) error {
    97  	return b.pubsub.UnsubscribeAll(ctx, subscriber)
    98  }
    99  
   100  func (b *EventBus) Publish(eventType string, eventData TMEventData) error {
   101  	// no explicit deadline for publishing events
   102  	ctx := context.Background()
   103  	return b.pubsub.PublishWithEvents(ctx, eventData, map[string][]string{EventTypeKey: {eventType}})
   104  }
   105  
   106  // validateAndStringifyEvents takes a slice of event objects and creates a
   107  // map of stringified events where each key is composed of the event
   108  // type and each of the event's attributes keys in the form of
   109  // "{event.Type}.{attribute.Key}" and the value is each attribute's value.
   110  func (b *EventBus) validateAndStringifyEvents(events []types.Event, logger log.Logger) map[string][]string {
   111  	result := make(map[string][]string)
   112  	for _, event := range events {
   113  		if len(event.Type) == 0 {
   114  			logger.Debug("Got an event with an empty type (skipping)", "event", event)
   115  			continue
   116  		}
   117  
   118  		for _, attr := range event.Attributes {
   119  			if len(attr.Key) == 0 {
   120  				logger.Debug("Got an event attribute with an empty key(skipping)", "event", event)
   121  				continue
   122  			}
   123  
   124  			compositeTag := fmt.Sprintf("%s.%s", event.Type, string(attr.Key))
   125  			result[compositeTag] = append(result[compositeTag], string(attr.Value))
   126  		}
   127  	}
   128  
   129  	return result
   130  }
   131  
   132  func (b *EventBus) PublishEventNewBlock(data EventDataNewBlock) error {
   133  	// no explicit deadline for publishing events
   134  	ctx := context.Background()
   135  
   136  	resultEvents := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...)
   137  	events := b.validateAndStringifyEvents(resultEvents, b.Logger.With("block", data.Block.StringShort()))
   138  
   139  	// add predefined new block event
   140  	events[EventTypeKey] = append(events[EventTypeKey], EventNewBlock)
   141  
   142  	return b.pubsub.PublishWithEvents(ctx, data, events)
   143  }
   144  
   145  func (b *EventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error {
   146  	// no explicit deadline for publishing events
   147  	ctx := context.Background()
   148  
   149  	resultTags := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...)
   150  	// TODO: Create StringShort method for Header and use it in logger.
   151  	events := b.validateAndStringifyEvents(resultTags, b.Logger.With("header", data.Header))
   152  
   153  	// add predefined new block header event
   154  	events[EventTypeKey] = append(events[EventTypeKey], EventNewBlockHeader)
   155  
   156  	return b.pubsub.PublishWithEvents(ctx, data, events)
   157  }
   158  
   159  func (b *EventBus) PublishEventVote(data EventDataVote) error {
   160  	return b.Publish(EventVote, data)
   161  }
   162  
   163  func (b *EventBus) PublishEventValidBlock(data EventDataRoundState) error {
   164  	return b.Publish(EventValidBlock, data)
   165  }
   166  
   167  // PublishEventTx publishes tx event with events from Result. Note it will add
   168  // predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys
   169  // will be overwritten.
   170  func (b *EventBus) PublishEventTx(data EventDataTx) error {
   171  	// no explicit deadline for publishing events
   172  	ctx := context.Background()
   173  
   174  	events := b.validateAndStringifyEvents(data.Result.Events, b.Logger.With("tx", data.Tx))
   175  
   176  	// add predefined compositeKeys
   177  	events[EventTypeKey] = append(events[EventTypeKey], EventTx)
   178  	events[TxHashKey] = append(events[TxHashKey], fmt.Sprintf("%X", data.Tx.Hash(data.Height)))
   179  	events[TxHeightKey] = append(events[TxHeightKey], fmt.Sprintf("%d", data.Height))
   180  
   181  	return b.pubsub.PublishWithEvents(ctx, data, events)
   182  }
   183  
   184  func (b *EventBus) PublishEventTxs(data EventDataTxs) error {
   185  	return b.Publish(EventTxs, data)
   186  }
   187  
   188  func (b *EventBus) PublishEventPendingTx(data EventDataTx) error {
   189  	ctx := context.Background()
   190  
   191  	events := make(map[string][]string)
   192  	// add predefined compositeKeys
   193  	events[EventTypeKey] = append(events[EventTypeKey], EventPendingTx)
   194  	return b.pubsub.PublishWithEvents(ctx, data, events)
   195  }
   196  
   197  func (b *EventBus) PublishEventRmPendingTx(data EventDataRmPendingTx) error {
   198  	ctx := context.Background()
   199  
   200  	events := make(map[string][]string)
   201  	events[EventTypeKey] = append(events[EventTypeKey], EventRmPendingTx)
   202  	return b.pubsub.PublishWithEvents(ctx, data, events)
   203  }
   204  
   205  func (b *EventBus) PublishEventLatestBlockTime(data EventDataBlockTime) error {
   206  	ctx := context.Background()
   207  	events := make(map[string][]string)
   208  	events[EventTypeKey] = append(events[EventTypeKey], EventBlockTime)
   209  	return b.pubsub.PublishWithEvents(ctx, data, events)
   210  }
   211  
   212  func (b *EventBus) PublishEventNewRoundStep(data EventDataRoundState) error {
   213  	return b.Publish(EventNewRoundStep, data)
   214  }
   215  
   216  func (b *EventBus) PublishEventTimeoutPropose(data EventDataRoundState) error {
   217  	return b.Publish(EventTimeoutPropose, data)
   218  }
   219  
   220  func (b *EventBus) PublishEventTimeoutWait(data EventDataRoundState) error {
   221  	return b.Publish(EventTimeoutWait, data)
   222  }
   223  
   224  func (b *EventBus) PublishEventNewRound(data EventDataNewRound) error {
   225  	return b.Publish(EventNewRound, data)
   226  }
   227  
   228  func (b *EventBus) PublishEventCompleteProposal(data EventDataCompleteProposal) error {
   229  	return b.Publish(EventCompleteProposal, data)
   230  }
   231  
   232  func (b *EventBus) PublishEventPolka(data EventDataRoundState) error {
   233  	return b.Publish(EventPolka, data)
   234  }
   235  
   236  func (b *EventBus) PublishEventUnlock(data EventDataRoundState) error {
   237  	return b.Publish(EventUnlock, data)
   238  }
   239  
   240  func (b *EventBus) PublishEventRelock(data EventDataRoundState) error {
   241  	return b.Publish(EventRelock, data)
   242  }
   243  
   244  func (b *EventBus) PublishEventLock(data EventDataRoundState) error {
   245  	return b.Publish(EventLock, data)
   246  }
   247  
   248  func (b *EventBus) PublishEventValidatorSetUpdates(data EventDataValidatorSetUpdates) error {
   249  	return b.Publish(EventValidatorSetUpdates, data)
   250  }
   251  
   252  //-----------------------------------------------------------------------------
   253  type NopEventBus struct{}
   254  
   255  func (NopEventBus) Subscribe(
   256  	ctx context.Context,
   257  	subscriber string,
   258  	query tmpubsub.Query,
   259  	out chan<- interface{},
   260  ) error {
   261  	return nil
   262  }
   263  
   264  func (NopEventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error {
   265  	return nil
   266  }
   267  
   268  func (NopEventBus) UnsubscribeAll(ctx context.Context, subscriber string) error {
   269  	return nil
   270  }
   271  
   272  func (NopEventBus) PublishEventNewBlock(data EventDataNewBlock) error {
   273  	return nil
   274  }
   275  
   276  func (NopEventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error {
   277  	return nil
   278  }
   279  
   280  func (NopEventBus) PublishEventVote(data EventDataVote) error {
   281  	return nil
   282  }
   283  
   284  func (NopEventBus) PublishEventTx(data EventDataTx) error {
   285  	return nil
   286  }
   287  
   288  func (NopEventBus) PublishEventTxs(data EventDataTxs) error {
   289  	return nil
   290  }
   291  
   292  func (NopEventBus) PublishEventPendingTx(data EventDataTx) error {
   293  	return nil
   294  }
   295  
   296  func (NopEventBus) PublishEventRmPendingTx(EventDataRmPendingTx) error {
   297  	return nil
   298  }
   299  
   300  func (NopEventBus) PublishEventNewRoundStep(data EventDataRoundState) error {
   301  	return nil
   302  }
   303  
   304  func (NopEventBus) PublishEventTimeoutPropose(data EventDataRoundState) error {
   305  	return nil
   306  }
   307  
   308  func (NopEventBus) PublishEventTimeoutWait(data EventDataRoundState) error {
   309  	return nil
   310  }
   311  
   312  func (NopEventBus) PublishEventNewRound(data EventDataRoundState) error {
   313  	return nil
   314  }
   315  
   316  func (NopEventBus) PublishEventCompleteProposal(data EventDataRoundState) error {
   317  	return nil
   318  }
   319  
   320  func (NopEventBus) PublishEventPolka(data EventDataRoundState) error {
   321  	return nil
   322  }
   323  
   324  func (NopEventBus) PublishEventUnlock(data EventDataRoundState) error {
   325  	return nil
   326  }
   327  
   328  func (NopEventBus) PublishEventRelock(data EventDataRoundState) error {
   329  	return nil
   330  }
   331  
   332  func (NopEventBus) PublishEventLock(data EventDataRoundState) error {
   333  	return nil
   334  }
   335  
   336  func (NopEventBus) PublishEventValidatorSetUpdates(data EventDataValidatorSetUpdates) error {
   337  	return nil
   338  }
   339  
   340  func (NopEventBus) PublishEventLatestBlockTime(data EventDataBlockTime) error {
   341  	return nil
   342  }