<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
記錄一下自己在go開發和學習上的一些筆記
最近在看一些rpc框架的使用原理和原始碼的時候,對中介軟體的實現非常感興趣,然後也看了一下grpc的中介軟體的用法,也看了別的框架的中介軟體的設計,感覺grpc的還算是比較容易弄懂,於是記錄一下這個常用中介軟體的實現的一個原理的demo(吐槽一下其他的rpc框架分為inbound和outbound的middleware感覺好像有點複雜化了,所以我也不知道哪種設計會比較好,樓主是java出身,所以對反射走aop的那種模式比較熟悉,對鏈式呼叫的middleware有點不太熟悉,當然現在已經熟悉了)
所以接下來我們就來看看demo吧 首先先定義好中介軟體的型別,這裡我就簡單定義為以下的格式
type middleware func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error)
handler: endpoint型別,真正用來發起請求的一個處理方法或者是經過N層中介軟體包裝的後的發起請求的處理方法
type endpoint func(ctx context.Context, req interface{}) (resp interface{}, err error) //ctx: 協程間通訊帶著 //req: 請求的格式,這裡圖簡便,直接interface{}型別 //resp: 同req //err: error
然後既然我們要將上方的endpoint
進行包裝然後產生一個新的endpoint
那麼也就是需要一個函數去做一步的事情,input是endpoint
,ouput也是endpoint
type warp func(endpoint) endpoint //就是這個warp函數
然後我們通過每次呼叫這個warp的定義去生成一個新的endpoint
就可以產生一個類似於dfs鏈式呼叫的一箇中介軟體的過程,因為將會一層套一層的endpoint
下去,然後當最後一層有返回了以後就可以接著返回了,然後不斷的彈棧回去最開始的地方,因為我們中介軟體的實現必然是要呼叫handler的
func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1n") resp, err = handler(ctx, req) fmt.Printf("end1n") return }
// handler0 var handler endpoint = func(ctx context.Context, req interface{}) (resp interface{}, err error) { fmt.Printf("make msgn") return nil, nil } // middleware var md Middleware = func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1n") resp, err = handler(ctx, req) fmt.Printf("end1n") return } // warp ->> handler1 handler = warp(func(e endpoint) endpoint { return func(ctx context.Context, req interface{}) (resp interface{}, err error) { return md(ctx, req, e) } })(handler)
package main import ( "context" "fmt" ) type endpoint func(ctx context.Context, req interface{}) (resp interface{}, err error) type middleware func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) type warp func(endpoint) endpoint func main() { mds := []middleware{} mds = append(mds, func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before1n") resp, err = handler(ctx, req) fmt.Printf("end1n") return }) mds = append(mds, func(ctx context.Context, req interface{}, handler endpoint) (resp interface{}, err error) { fmt.Printf("before2n") resp, err = handler(ctx, req) fmt.Printf("end2n") return }) var handler endpoint = func(ctx context.Context, req interface{}) (resp interface{}, err error) { fmt.Printf("make msgn") return nil, nil } for i := len(mds) - 1; i >= 0; i-- { handler = warp(func(e endpoint) endpoint { // 由於go的機制問題如果不用tmp去存下當前的i,那麼mds[i]就會取最終的那一個,就會溢位,所以在return前先儲存一下i的量,然後每一個stack去存的變數就是對的 cur := i return func(ctx context.Context, req interface{}) (resp interface{}, err error) { return mds[cur](ctx, req, e) } })(handler) } resp, err := handler(context.Background(), "ster") if resp != nil && err != nil { return } }
結果是
before1
before2
make msg
end2
end1
結論:感覺有函數指標的語言都可以用這一套去實現一箇中介軟體
以上就是一文詳解Golang的中介軟體設計模式的詳細內容,更多關於Golang中介軟體設計模式的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45