事件服务
Noba 的事件服务目前还比较简单,只有一些简单的事件订阅和发布功能。一次完整的事件驱动分为这三步:首先需要创建事件;然后订阅该事件;在事件发生时通知订阅者。
创建事件
要创建事件需要先通过 ioc 创建事件服务,然后通过该服务创建包含事件的 Hub
- 创建事件服务:
# main.py from noba import core if __name__ == '__main__': event = core.make('event')
- 创建事件:
事件被包裹在 Hub 中的,一个 Hub 可以有多个事件。该 Hub 可以是一个命名 Hub,命名的目的是方便管理 Hub,但这并不是强制的。创建命名 Hub 的方法有两个(见代码中方法一和方法二)# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') # 创建一个命名为 'cross over' 的 Hub 方法一。该 hub 包含两个事件:'cross close price', 'cross open price' cross_over_hub = event_service.hub(['cross close price', 'cross open price'], "cross over") # 创建一个命名为 'cross over' 的 Hub 方法二。该 hub 包含两个事件:'cross close price', 'cross open price' cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over")
- 关于 Hub 的一些操作:
-
通过事件服务获取所有 Hub
# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") all_hub = event_service.get_all_hub()
-
事件服务通过名字获取某个 Hub
# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") hub = event_service.get_hub('cross over') print(cross_over_hub == hub) # True
-
获取 Hub 的所有事件
# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") cross_over_hub_event = cross_over_hub.get_events() print(cross_over_hub_event) # ['cross close price', 'cross open price']
-
获取 Hub 名字
# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") hub_name = cross_over_hub.get_name() print(hub_name) # cross over
-
从事件服务中删除 Hub 有两种方式。在 Hub 调用
drop_me
方法;或则调用事件服务的drop
方法# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") # 方法一 cross_over_hub.drop_me() # 方法二 event_service.drop('cross over')
-
通过 Hub 获取事件服务
# main.py from noba import core if __name__ == '__main__': event_service = core.make('event') cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over") service_obj = cross_over_hub.manager print(service_obj == event_service) # True
-
订阅事件
通过 watch
方法可以订阅在 Hub 中定义的事件。watch
接受 3 个参数:事件名 、 回调函数,回调函数可以接受事件通知时传递的数据。第 3 个参数是个布尔值 ,决定该订阅是否可以多次监听。默认为 False
,只监听一次。
# main.py
from noba import core
if __name__ == '__main__':
event_service = core.make('event')
cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over")
cross_over_hub.watch('cross close price', lambda data:print(data), True) # True 表示该订阅可以多次监听。False 是只监听一次
上面是面向过程的事件订阅,还可以面向对象方式来订阅事件(订阅者模式)
from noba import core
event_service = core.make('event')
class Purchase(event_service):
def subscribe(self, event):
cross_over_hub = self.get_hub('cross over')
# 订阅事件
cross_over_hub.watch(event, lambda data:print(f"moving average price is {data['moving_average_price']}, close price is {data['close_price']}。cross over!"), True)
if __name__ == '__main__':
# 创建一个命名为 cross over 的hub,该 hub 包含两个事件:'cross close price', 'cross open price'
cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over")
Purchase().subscribe('cross close price')
事件通知
通过 fire
方法可以触发定义在 Hub 中的事件。fire
传入两个参数:事件名 和 数据。数据会传递给订阅者的回调函数中。如下代码会打印出:"moving average price is 12, close price is 10。cross over!"
# main.py
from noba import core
if __name__ == '__main__':
event_service = core.make('event')
cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over")
cross_over_hub.watch('cross close price', lambda data:print(f"moving average price is {data['moving_average_price']}, close price is {data['close_price']}。cross over!"), True)
cross_over_hub.fire('cross close price', {"moving_average_price":12, "close_price":10})
订阅者模式下的事件通知:
# main.py
from noba import core
event_service = core.make('event')
class Purchase(event_service):
def subscribe(self, event):
cross_over_hub = self.get_hub('cross over')
# 订阅事件
cross_over_hub.watch(event, lambda data:print(f"moving average price is {data['moving_average_price']}, close price is {data['close_price']}。cross over!"), True)
if __name__ == '__main__':
# 创建一个命名为 cross over 的hub,该 hub 包含两个事件:'cross close price', 'cross open price'
cross_over_hub = event_service.hub(['cross close price', 'cross open price']).name("cross over")
Purchase().subscribe('cross close price')
cross_over_hub.fire('cross close price', {"moving_average_price":12, "close_price":10})
* 当然通知也可以用面向对象来改写,只需要继承事件服务就可以,代码略