github.com/project-88388/tendermint-v0.34.14-terra.2@v1.0.0/types/event_bus.go (about) 1 package types 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/tendermint/tendermint/abci/types" 8 "github.com/tendermint/tendermint/libs/log" 9 tmpubsub "github.com/tendermint/tendermint/libs/pubsub" 10 "github.com/tendermint/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 if err := b.pubsub.Stop(); err != nil { 63 b.pubsub.Logger.Error("error trying to stop eventBus", "error", err) 64 } 65 } 66 67 func (b *EventBus) NumClients() int { 68 return b.pubsub.NumClients() 69 } 70 71 func (b *EventBus) NumClientSubscriptions(clientID string) int { 72 return b.pubsub.NumClientSubscriptions(clientID) 73 } 74 75 func (b *EventBus) Subscribe( 76 ctx context.Context, 77 subscriber string, 78 query tmpubsub.Query, 79 outCapacity ...int, 80 ) (Subscription, error) { 81 return b.pubsub.Subscribe(ctx, subscriber, query, outCapacity...) 82 } 83 84 // This method can be used for a local consensus explorer and synchronous 85 // testing. Do not use for for public facing / untrusted subscriptions! 86 func (b *EventBus) SubscribeUnbuffered( 87 ctx context.Context, 88 subscriber string, 89 query tmpubsub.Query, 90 ) (Subscription, error) { 91 return b.pubsub.SubscribeUnbuffered(ctx, subscriber, query) 92 } 93 94 func (b *EventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error { 95 return b.pubsub.Unsubscribe(ctx, subscriber, query) 96 } 97 98 func (b *EventBus) UnsubscribeAll(ctx context.Context, subscriber string) error { 99 return b.pubsub.UnsubscribeAll(ctx, subscriber) 100 } 101 102 func (b *EventBus) Publish(eventType string, eventData TMEventData) error { 103 // no explicit deadline for publishing events 104 ctx := context.Background() 105 return b.pubsub.PublishWithEvents(ctx, eventData, map[string][]string{EventTypeKey: {eventType}}) 106 } 107 108 // validateAndStringifyEvents takes a slice of event objects and creates a 109 // map of stringified events where each key is composed of the event 110 // type and each of the event's attributes keys in the form of 111 // "{event.Type}.{attribute.Key}" and the value is each attribute's value. 112 func (b *EventBus) validateAndStringifyEvents(events []types.Event, logger log.Logger) map[string][]string { 113 result := make(map[string][]string) 114 for _, event := range events { 115 if len(event.Type) == 0 { 116 logger.Debug("Got an event with an empty type (skipping)", "event", event) 117 continue 118 } 119 120 for _, attr := range event.Attributes { 121 if len(attr.Key) == 0 { 122 logger.Debug("Got an event attribute with an empty key(skipping)", "event", event) 123 continue 124 } 125 126 compositeTag := fmt.Sprintf("%s.%s", event.Type, string(attr.Key)) 127 result[compositeTag] = append(result[compositeTag], string(attr.Value)) 128 } 129 } 130 131 return result 132 } 133 134 func (b *EventBus) PublishEventNewBlock(data EventDataNewBlock) error { 135 // no explicit deadline for publishing events 136 ctx := context.Background() 137 138 resultEvents := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...) 139 events := b.validateAndStringifyEvents(resultEvents, b.Logger.With("block", data.Block.StringShort())) 140 141 // add predefined new block event 142 events[EventTypeKey] = append(events[EventTypeKey], EventNewBlock) 143 144 return b.pubsub.PublishWithEvents(ctx, data, events) 145 } 146 147 func (b *EventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error { 148 // no explicit deadline for publishing events 149 ctx := context.Background() 150 151 resultTags := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...) 152 // TODO: Create StringShort method for Header and use it in logger. 153 events := b.validateAndStringifyEvents(resultTags, b.Logger.With("header", data.Header)) 154 155 // add predefined new block header event 156 events[EventTypeKey] = append(events[EventTypeKey], EventNewBlockHeader) 157 158 return b.pubsub.PublishWithEvents(ctx, data, events) 159 } 160 161 func (b *EventBus) PublishEventNewEvidence(evidence EventDataNewEvidence) error { 162 return b.Publish(EventNewEvidence, evidence) 163 } 164 165 func (b *EventBus) PublishEventVote(data EventDataVote) error { 166 return b.Publish(EventVote, data) 167 } 168 169 func (b *EventBus) PublishEventValidBlock(data EventDataRoundState) error { 170 return b.Publish(EventValidBlock, data) 171 } 172 173 // PublishEventTx publishes tx event with events from Result. Note it will add 174 // predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys 175 // will be overwritten. 176 func (b *EventBus) PublishEventTx(data EventDataTx) error { 177 // no explicit deadline for publishing events 178 ctx := context.Background() 179 180 events := b.validateAndStringifyEvents(data.Result.Events, b.Logger.With("tx", data.Tx)) 181 182 // add predefined compositeKeys 183 events[EventTypeKey] = append(events[EventTypeKey], EventTx) 184 events[TxHashKey] = append(events[TxHashKey], fmt.Sprintf("%X", Tx(data.Tx).Hash())) 185 events[TxHeightKey] = append(events[TxHeightKey], fmt.Sprintf("%d", data.Height)) 186 187 return b.pubsub.PublishWithEvents(ctx, data, events) 188 } 189 190 func (b *EventBus) PublishEventNewRoundStep(data EventDataRoundState) error { 191 return b.Publish(EventNewRoundStep, data) 192 } 193 194 func (b *EventBus) PublishEventTimeoutPropose(data EventDataRoundState) error { 195 return b.Publish(EventTimeoutPropose, data) 196 } 197 198 func (b *EventBus) PublishEventTimeoutWait(data EventDataRoundState) error { 199 return b.Publish(EventTimeoutWait, data) 200 } 201 202 func (b *EventBus) PublishEventNewRound(data EventDataNewRound) error { 203 return b.Publish(EventNewRound, data) 204 } 205 206 func (b *EventBus) PublishEventCompleteProposal(data EventDataCompleteProposal) error { 207 return b.Publish(EventCompleteProposal, data) 208 } 209 210 func (b *EventBus) PublishEventPolka(data EventDataRoundState) error { 211 return b.Publish(EventPolka, data) 212 } 213 214 func (b *EventBus) PublishEventUnlock(data EventDataRoundState) error { 215 return b.Publish(EventUnlock, data) 216 } 217 218 func (b *EventBus) PublishEventRelock(data EventDataRoundState) error { 219 return b.Publish(EventRelock, data) 220 } 221 222 func (b *EventBus) PublishEventLock(data EventDataRoundState) error { 223 return b.Publish(EventLock, data) 224 } 225 226 func (b *EventBus) PublishEventValidatorSetUpdates(data EventDataValidatorSetUpdates) error { 227 return b.Publish(EventValidatorSetUpdates, data) 228 } 229 230 //----------------------------------------------------------------------------- 231 type NopEventBus struct{} 232 233 func (NopEventBus) Subscribe( 234 ctx context.Context, 235 subscriber string, 236 query tmpubsub.Query, 237 out chan<- interface{}, 238 ) error { 239 return nil 240 } 241 242 func (NopEventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error { 243 return nil 244 } 245 246 func (NopEventBus) UnsubscribeAll(ctx context.Context, subscriber string) error { 247 return nil 248 } 249 250 func (NopEventBus) PublishEventNewBlock(data EventDataNewBlock) error { 251 return nil 252 } 253 254 func (NopEventBus) PublishEventNewBlockHeader(data EventDataNewBlockHeader) error { 255 return nil 256 } 257 258 func (NopEventBus) PublishEventNewEvidence(evidence EventDataNewEvidence) error { 259 return nil 260 } 261 262 func (NopEventBus) PublishEventVote(data EventDataVote) error { 263 return nil 264 } 265 266 func (NopEventBus) PublishEventTx(data EventDataTx) error { 267 return nil 268 } 269 270 func (NopEventBus) PublishEventNewRoundStep(data EventDataRoundState) error { 271 return nil 272 } 273 274 func (NopEventBus) PublishEventTimeoutPropose(data EventDataRoundState) error { 275 return nil 276 } 277 278 func (NopEventBus) PublishEventTimeoutWait(data EventDataRoundState) error { 279 return nil 280 } 281 282 func (NopEventBus) PublishEventNewRound(data EventDataRoundState) error { 283 return nil 284 } 285 286 func (NopEventBus) PublishEventCompleteProposal(data EventDataRoundState) error { 287 return nil 288 } 289 290 func (NopEventBus) PublishEventPolka(data EventDataRoundState) error { 291 return nil 292 } 293 294 func (NopEventBus) PublishEventUnlock(data EventDataRoundState) error { 295 return nil 296 } 297 298 func (NopEventBus) PublishEventRelock(data EventDataRoundState) error { 299 return nil 300 } 301 302 func (NopEventBus) PublishEventLock(data EventDataRoundState) error { 303 return nil 304 } 305 306 func (NopEventBus) PublishEventValidatorSetUpdates(data EventDataValidatorSetUpdates) error { 307 return nil 308 }