第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我應(yīng)該在每個傳入請求中創(chuàng)建新的上下文嗎?

我應(yīng)該在每個傳入請求中創(chuàng)建新的上下文嗎?

Go
拉莫斯之舞 2023-08-14 14:39:41
在過去的幾天里,我一直在閱讀有關(guān) Go 的內(nèi)容,并且我不斷回顧的一個概念是上下文。我想我理解創(chuàng)建這樣一個結(jié)構(gòu)背后的動機。我不明白的是在傳入 HTTP 請求中使用上下文時的特定用例。假設(shè)我們有一個追隨者httpHandlerFunc。在該處理程序內(nèi)部,我們調(diào)用一個需要傳遞上下文的函數(shù)。我經(jīng)常看到這個解決方案func myHandler(w http.ResponseWriter, r *http.Request) {  ctx := context.WithValue(context.Background(), "request", r)  otherFunc(ctx)}我的問題是,為什么我們不直接從請求中傳遞上下文,就像這樣func myHandler(w http.ResponseWriter, r *http.Request) {  otherFunc(r.Context())}既然我們希望上下文流過我們的程序,那么傳遞請求的上下文不是更有意義嗎?我認為創(chuàng)建后臺上下文是我們只想在根父級中執(zhí)行的操作,就像init()函數(shù)一樣。
查看完整描述

2 回答

?
森林海

TA貢獻2011條經(jīng)驗 獲得超2個贊

您可能會錯過上下文的要點 - 據(jù)說是由于您正在處理的 HOWTO 很差。

在上下文中攜帶任意值的可能性實際上是這種類型的一個缺陷,其設(shè)計者對此感到遺憾,因為它創(chuàng)建了一種反模式(處理上下文作為某種狀態(tài)的正確方法是明確地擁有一組值)傳遍了)。

上下文存在的主要原因是它們提供了信號的樹狀傳播(在上下文的情況下是取消或“完成”)。所以上下文背后的原始想法如下:

  1. “根”上下文對象是為傳入請求創(chuàng)建的。

  2. 需要代表請求執(zhí)行的每個“任務(wù)”都與其自己的上下文相關(guān)聯(lián),該上下文源自請求的上下文。

  3. 這些任務(wù)可能會產(chǎn)生其他任務(wù)等等。

    正如您所看到的,形成了“工作單元”的層次結(jié)構(gòu),鏈接到對象,這是這些單元存在和執(zhí)行的原因。

  4. 當傳入請求被取消時(例如,客戶端的套接字斷開連接),與其關(guān)聯(lián)的上下文對象也會被取消,然后所有鏈接的任務(wù)都會收到它,因為它從生成的上下文樹的根向下傳播到其離開——確保請求執(zhí)行的所有任務(wù)(最終)被取消。

    當然,為了使其發(fā)揮作用,每個“任務(wù)”(通常是一個執(zhí)行某些操作的 goroutine)都需要從傳遞給它的上下文中“監(jiān)聽”該“完成”信號。

上下文還支持開箱即用的超時,因此您可以創(chuàng)建一個上下文,該上下文在經(jīng)過一些固定時間間隔后會自行取消。

那么,回到你問題中的例子。

第一個示例完全忽略請求的上下文,并從頭開始創(chuàng)建上下文,表面上唯一的原因是在其中攜帶內(nèi)容(不好)。

第二個示例可能將上下文用于其預(yù)期目的(但我們不知道,因為我們看不到otherFunc)。


1 實際上,如果要控制的任務(wù)沒有其他策略“添加”到現(xiàn)有的父上下文,則不需要創(chuàng)建新的上下文。派生的想法是實現(xiàn)額外的方法來取消此特定任務(wù)中的工作,并尊重父上下文的取消。?例如,為特定任務(wù)派生的上下文可以有自己的截止日期,或者有辦法僅取消該特定上下文。
當然,可以為任務(wù)導(dǎo)出復(fù)雜的嵌套上下文:例如,可以從父上下文導(dǎo)出具有截止日期的上下文,然后可以從前者導(dǎo)出可取消的上下文。結(jié)果將是一個上下文被代碼明確地取消,或者當截止日期到期或當父上下文發(fā)出取消信號時被取消。


查看完整回答
反對 回復(fù) 2023-08-14
?
慕萊塢森

TA貢獻1810條經(jīng)驗 獲得超4個贊

你的兩個例子做了完全不同的事情。


func myHandler(w http.ResponseWriter, r *http.Request) {

  ctx := context.WithValue(context.Background(), "request", r)

  otherFunc(ctx)

}

這將創(chuàng)建一個新的上下文,并將請求存儲為一個值。很少(如果有的話)有任何理由這樣做。一個更慣用的解決方案是將請求傳遞給otherFunc像這樣的:


func myHandler(w http.ResponseWriter, r *http.Request) {

  otherFunc(r)

}

如果您確實需要將請求作為上下文值傳遞,則可能應(yīng)該使用當前請求的上下文來執(zhí)行此操作,如下所示:


func myHandler(w http.ResponseWriter, r *http.Request) {

  ctx := context.WithValue(r.Context(), "request", r)

  otherFunc(ctx)

}


查看完整回答
反對 回復(fù) 2023-08-14
  • 2 回答
  • 0 關(guān)注
  • 206 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號