久久国产乱子伦精品免费M,亚洲一区二区三区91,欧美国产在线视频,国产精品视频久久

Golang事件系統Event Bus

本文介紹了事件總線實現。

最近在學習開源項目Grafana的代碼,發現作者實現了一個事件總線的機制,在項目里面大量應用,效果也非常好,代碼也比較簡單,介紹給大家看看。

源碼文件地址:grafana/bus.go at main · grafana/grafana · GitHub

1.注冊和調用

在這個項目里面隨處可見這種寫法:

Golang事件系統Event Bus

關鍵是bus.Dispatch(&query)這段代碼,它的參數是一個結構體GetAlertByIdQuery,內容如下:

Golang事件系統Event Bus

根據名字可以看出這個方法就是通過Id去查詢Alert,其中Alert結構體就是結果對象,這里就不貼出來了。

通過查看源碼可以得知,Dispatch背后是調用了GetAlertById這個方法,然后把結果賦值到query參數的Result中返回。

Golang事件系統Event Bus

問題來了,這是怎么實現的呢?Dispatch到底做了哪些操作?這樣做有什么好處?

下面我來一一解答:

首先,在Dispatch之前,你需要先注冊這個方法,也就是調用AddHandler,在這個項目里面可以看到init函數里面有大量這樣的代碼:

Golang事件系統Event Bus

其實這個方法的邏輯也很簡單,所謂注冊也就是把通過一個map把函數名和對應的函數做一個映射關系保存起來,當我們Dispatch的時候其實就是通過參數名查找之前注冊過的函數,然后通過反射調用該函數。

Bus結構體里面有幾個map成員,在這個項目里面作者定義了3種不同類型的handler,一種是普通的handler,也就是剛才展示的那種,第二種是帶上下文的handler,還有一種則是事件訂閱用到的handler,我們給一個事件注冊多個監聽者,當事件觸發的時候會依次調用多個監聽函數,其實就是一個觀察者模式。

Golang事件系統Event Bus

下面就看看具體的源碼,AddHandler方法內容如下:

Golang事件系統Event Bus

Dispatch方法的源碼如下:

Golang事件系統Event Bus

對于AddHandlerCtxDispatchCtx這個2個方法基本上是一樣的,只不過多了一個上下文參數,可以拿來做超時控制或者其它用途。

2.訂閱和發布

除此之外,還有2個方法AddEventListenerPublish,即事件的訂閱和發布。

Golang事件系統Event Bus

查看源碼可以得知,可以給一個事件注冊多個handler函數,而Publish的時候則是依次調用注冊的函數,邏輯也不復雜。

Golang事件系統Event Bus

這里面有一點不好,所有訂閱函數的調用是順序的,并沒有使用協程,所以如果注冊了很多個函數,這樣效率也不高啊。

3.好處

可能有人會好奇,為什么明明可以直接調用函數就行,為啥非得繞個彎子,整這么復雜?

況且,每次調用都得使用反射機制,性能也不行。

我覺得主要有以下幾點:

1.這種寫法邏輯清晰,解耦

2.方便單元測試

3.性能不是最大考量,雖然說反射會降低性能

轉自:wangbjun.site/2021/coding/golang/event-bus.html

 

相關新聞

歷經多年發展,已成為國內好評如潮的Linux云計算運維、SRE、Devops、網絡安全、云原生、Go、Python開發專業人才培訓機構!

    1. 主站蜘蛛池模板: 公安县| 东明县| 那曲县| 和平县| 东方市| 博乐市| 慈溪市| 清苑县| 龙门县| 宜昌市| 阿拉善盟| 双辽市| 扎囊县| 邹城市| 平潭县| 迭部县| 眉山市| 盱眙县| 荣昌县| 阜城县| 营山县| 贵阳市| 阿拉尔市| 肥乡县| 海兴县| 银川市| 韶关市| 南丰县| 张北县| 从江县| 江西省| 昌平区| 冷水江市| 辽中县| 合川市| 隆子县| 汉中市| 梅河口市| 微山县| 郎溪县| 界首市|