मुख्य सामग्री पर जाएं
मॉड्यूल 7 · पाठ 5 का 5पाठ्यक्रम में 35/50~14 min
मॉड्यूल पाठ (5/5)

`context.Context`: रद्दीकरण और समय सीमा

context पैकेज प्रचार के लिए वास्तविक मानक है कॉल श्रृंखला के साथ रद्दीकरण, समय सीमा और दायरे से बंधे मूल्य, एकाधिक गोरआउट्स में। सभी मानक "नेटवर्किंग" पैकेज (net/http, database/sql, os/exec) context.Context को इस रूप में स्वीकार करें उनका पहला पैरामीटर.

अंतरपटल

Go
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(): स्कोप-बाउंड मानों की खोज (संयम से उपयोग करें)।

चार बुनियादी कार्य

Go
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 के साथ) आंतरिक संसाधनों को जारी करने के लिए, भले ही संदर्भ पहले ही समाप्त हो चुका है.

टाइमआउट पैटर्न

Go
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() पर चयन करें

Go
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() को संभालना होगा। अन्यथा संदर्भ "चालू" है कुछ नहीं.

प्रथम-पैरामीटर सम्मेलन

Go
func Fetch(ctx context.Context, url string) ([]byte, error) { ... }
//        ^^^^^^^^^^^^^^^^^^^
// SEMPRE primo, mai dentro a una struct, mai opzionale
  • ctx हमेशा पहले पैरामीटर के रूप में, जिसका नाम ctx है।
  • कभी नहीं Context को किसी संरचना के क्षेत्र के रूप में रखें (बहुत दुर्लभ अपवाद)।
  • कभी नहीं nil को पास करें: context.TODO() को स्टब के रूप में उपयोग करें।

context.WithValue: संयम से

Go
type userKey struct{}

ctx := context.WithValue(ctx, userKey{}, currentUser)
// più sotto:
if u, ok := ctx.Value(userKey{}).(*User); ok { ... }

दिशानिर्देश:

  • केवल अनुरोध-दायरे डेटा (अनुरोध आईडी, ट्रेस आईडी, उपयोगकर्ता पहचान) के लिए।
  • फ़ंक्शन पैरामीटर के लिए कभी नहीं: उन्हें सामान्य रूप से पास करें।
  • टकराव से बचने के लिए कस्टम गैर-निर्यातित प्रकार की कुंजियाँ।

श्रृंखला के साथ प्रसार

Go
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 जब क्लाइंट डिस्कनेक्ट हो जाता है या जब हैंडलर वापस आता है। इसे सभी तक प्रचारित करके डाउनस्ट्रीम कॉल में, संचालन का पूरा वृक्ष रद्द कर दिया जाता है कैस्केड: डिस्कनेक्ट के बाद कोई बर्बाद काम नहीं।

इसे अजमाएं

व्यायाम#go.m7.l5.e1
प्रयास: 0लोड हो रहा है...

context.Background() से प्राप्त 1-सेकंड टाइमआउट के साथ एक संदर्भ बनाएं और defer के साथ cancel कॉल करना याद रखें।

संपादक लोड हो रहा है...
संकेत दिखाएँ

`context.WithTimeout(parent, d)` रिटर्न `(ctx, cancel)`; हमेशा कॉल रद्द करें.

3 प्रयासों के बाद समाधान उपलब्ध है

व्यायाम#go.m7.l5.e2
प्रयास: 0लोड हो रहा है...

संदर्भ रद्द होने की प्रतीक्षा करने के लिए चयन में <-ctx.Done() का उपयोग करें।

संपादक लोड हो रहा है...
संकेत दिखाएँ

`ctx.Done()` एक चैनल है जो संदर्भ रद्द होने पर बंद हो जाता है।

3 प्रयासों के बाद समाधान उपलब्ध है

Quiz#go.m7.l5.e3
तैयार

परंपरा के अनुसार, फ़ंक्शन हस्ताक्षर में ctx पैरामीटर कहाँ जाता है?

Go
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() क्लाइंट डिस्कनेक्ट होने पर रद्द कर दिया जाता है।