मॉड्यूल पाठ (5/5)
`context.Context`: रद्दीकरण और समय सीमा
context पैकेज प्रचार के लिए वास्तविक मानक है
कॉल श्रृंखला के साथ रद्दीकरण, समय सीमा और दायरे से बंधे मूल्य,
एकाधिक गोरआउट्स में। सभी मानक "नेटवर्किंग" पैकेज
(net/http, database/sql, os/exec) context.Context को इस रूप में स्वीकार करें
उनका पहला पैरामीटर.
अंतरपटल
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key any) any
}Done(): चैनल जो संदर्भ रद्द होने पर बंद हो जाता है।Err(): रद्दीकरण का कारण (context.Canceledयाcontext.DeadlineExceeded)।Deadline(): वैकल्पिक समय सीमा।Value(): स्कोप-बाउंड मानों की खोज (संयम से उपयोग करें)।
चार बुनियादी कार्य
ctx := context.Background() // radice: usalo in main, init, test
ctx := context.TODO() // "non so ancora": stub esplicito
ctx, cancel := context.WithCancel(parent) // cancel manuale
ctx, cancel := context.WithTimeout(parent, d) // scadenza relativa
ctx, cancel := context.WithDeadline(parent, t) // scadenza assoluta
ctx := context.WithValue(parent, key, value) // valore scope-boundसभी व्युत्पन्न फॉर्म एक cancel फ़ंक्शन लौटाते हैं: इसे हमेशा कॉल करें
(आदर्श रूप से defer के साथ) आंतरिक संसाधनों को जारी करने के लिए, भले ही
संदर्भ पहले ही समाप्त हो चुका है.
टाइमआउट पैटर्न
func fetchUser(id string) (*User, error) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
return queryUser(ctx, id) // queryUser deve rispettare ctx
}यदि queryUser को 2 सेकंड से अधिक समय लगता है, तो ctx.Done() बंद हो जाता है और
फ़ंक्शन को ऑपरेशन निरस्त करना होगा.
संदर्भ का सम्मान करते हुए: Done() पर चयन करें
func slowWork(ctx context.Context) error {
for {
select {
case <-ctx.Done():
return ctx.Err() // canceled o deadline exceeded
case <-time.After(100 * time.Millisecond):
// un tick di lavoro
}
}
}नियम: कहीं भी आपका फ़ंक्शन लंबे समय तक अवरुद्ध हो सकता है ctx.Done() को संभालना होगा। अन्यथा संदर्भ "चालू" है कुछ नहीं.
प्रथम-पैरामीटर सम्मेलन
func Fetch(ctx context.Context, url string) ([]byte, error) { ... }
// ^^^^^^^^^^^^^^^^^^^
// SEMPRE primo, mai dentro a una struct, mai opzionalectxहमेशा पहले पैरामीटर के रूप में, जिसका नामctxहै।- कभी नहीं
Contextको किसी संरचना के क्षेत्र के रूप में रखें (बहुत दुर्लभ अपवाद)। - कभी नहीं
nilको पास करें:context.TODO()को स्टब के रूप में उपयोग करें।
context.WithValue: संयम से
type userKey struct{}
ctx := context.WithValue(ctx, userKey{}, currentUser)
// più sotto:
if u, ok := ctx.Value(userKey{}).(*User); ok { ... }दिशानिर्देश:
- केवल अनुरोध-दायरे डेटा (अनुरोध आईडी, ट्रेस आईडी, उपयोगकर्ता पहचान) के लिए।
- फ़ंक्शन पैरामीटर के लिए कभी नहीं: उन्हें सामान्य रूप से पास करें।
- टकराव से बचने के लिए कस्टम गैर-निर्यातित प्रकार की कुंजियाँ।
श्रृंखला के साथ प्रसार
func handleHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() // context legato al ciclo di vita della richiesta
user, err := fetchUser(ctx, r.URL.Query().Get("id"))
if err != nil { ... }
// ...
}net/http जब क्लाइंट
डिस्कनेक्ट हो जाता है या जब हैंडलर वापस आता है। इसे सभी तक प्रचारित करके
डाउनस्ट्रीम कॉल में, संचालन का पूरा वृक्ष रद्द कर दिया जाता है
कैस्केड: डिस्कनेक्ट के बाद कोई बर्बाद काम नहीं।
इसे अजमाएं
context.Background() से प्राप्त 1-सेकंड टाइमआउट के साथ एक संदर्भ बनाएं और defer के साथ cancel कॉल करना याद रखें।
संकेत दिखाएँ
`context.WithTimeout(parent, d)` रिटर्न `(ctx, cancel)`; हमेशा कॉल रद्द करें.
3 प्रयासों के बाद समाधान उपलब्ध है
संदर्भ रद्द होने की प्रतीक्षा करने के लिए चयन में <-ctx.Done() का उपयोग करें।
संकेत दिखाएँ
`ctx.Done()` एक चैनल है जो संदर्भ रद्द होने पर बंद हो जाता है।
3 प्रयासों के बाद समाधान उपलब्ध है
परंपरा के अनुसार, फ़ंक्शन हस्ताक्षर में ctx पैरामीटर कहाँ जाता है?
func Fetch(???, url string) ([]byte, error)संक्षिप्त
context.Contextरद्दीकरण, समय सीमा और दायरे से बंधे मूल्यों का प्रचार करता है।Background()/TODO()मूल के रूप में;WithCancel/WithTimeout/WithDeadlineप्राप्त करना।- संसाधन जारी करने के लिए हमेशा
defer cancel()। - "लंबे" फ़ंक्शन को
ctx.Done()परselectया मानक पैकेज में ctx पास करना होगा। - कन्वेंशन:
ctxपहले पैरामीटर के रूप में, किसी संरचना के अंदर कभी नहीं। WithValueकेवल अनुरोध-दायरे वाले डेटा (अनुरोध आईडी, ट्रेस आईडी) के लिए।net/httpमें,r.Context()क्लाइंट डिस्कनेक्ट होने पर रद्द कर दिया जाता है।