go-ethereum事件机制设计与实现

总体介绍

以太坊内部有大量协程,协程间的调度驱动通过事件机制来完成;具体实现使用
golang的chan机制。主要方案有以下两种。

1.使用观察者模式实现“事件”转发

Feed 类为 observer
  • Subscribe()方法, 客户端调用
    开始订阅‘事件’,把客户端的 接收channel 添加到 Feed;同时返回feedSub对象

  • feedSub.Unsubscribe()方法 ,客户端调用
    客户端通过调用此方法取消订阅

  • Send(value interface{})方法, Feed(observer) 拥有者调用
    通过此方法向所有订阅者发布‘事件’

使用go的chan机制实现通信
  • 订阅者把自己的 接收 chan 添加到 Feed(observer)
  • Send发布消息时的输入参数也是一个 chan
具体使用示例
1)BlockChain类作为 Feed(observer) 拥有者
  • 拥有下面几个 Feed成员
    rmLogsFeed event.Feed
    chainFeed event.Feed
    chainSideFeed event.Feed
    chainHeadFeed event.Feed
    logsFeed event.Feed
  • 封装了下面几个订阅函数
    SubscribeRemovedLogsEvent
    SubscribeChainEvent
    SubscribeChainHeadEvent
    ...
  • 发布消息时调用 bc.xxxxFeed.Send(ev)
2) TestTransactionGapFilling 作为客户端
  • 下行代码定义了事件接收 chan
    events := make(chan TxPreEvent, testTxPoolConfig.AccountQueue+5)
  • 下行代码订阅了tx_pool的事件
    sub := pool.txFeed.Subscribe(events)
  • 通过上面的events接收处理事件

2.全局双工事件通道,根据事件类型订阅和转发

TypeMux 类为observer
  • Subscribe()方法, 注册者调用
    参数为要接收的‘事件类型’, 返回TypeMuxSubscription对象
  • Post()方法, 注册者调用
    发送消息,具体实现调用TypeMuxSubscription.deliver()
  • TypeMuxSubscription. Unsubscribe()方法, 注册者调用
    取消订阅
  • TypeMuxSubscription.deliver()方法 ,无外部调用
    注册者发送消息的具体实现,
  • TypeMuxSubscription.Chan()方法, 注册者调用
    接收事件
以太坊具体使用
  • Ethereum中创建一次,其他地方多次使用 ,全局只有一个对象。

  • Subscribe()和Post()方法在代码中有多次调用,执行对象都来自Ethereum.eventMux指向的对象

你可能感兴趣的:(go-ethereum事件机制设计与实现)