ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 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() మూసివేయబడుతుంది మరియు ఫంక్షన్ తప్పనిసరిగా ఆపరేషన్‌ను నిలిపివేయాలి.

సందర్భాన్ని గౌరవిస్తూ: పూర్తయింది()ని ఎంచుకోండి

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ని నిర్వహించాలి. పూర్తయింది()**. లేకపోతే, సందర్భం "పవర్ ఆన్ చేయబడింది" ఏమీ లేదు.

మొదటి పారామితి సమావేశం

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()ని స్టబ్‌గా ఉపయోగించండి.

సందర్భం.విలువతో: పొదుపుగా

Go
type userKey struct{}

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

మార్గదర్శకాలు:

  • అభ్యర్థన-స్కోప్డ్ డేటా (అభ్యర్థన ID, ట్రేస్ ID, వినియోగదారు గుర్తింపు) కోసం మాత్రమే.
  • ఫంక్షన్ పారామీటర్‌ల కోసం ఎప్పుడూ చేయవద్దు: వాటిని సాధారణంగా పాస్ చేయండి.
  • ఘర్షణలను నివారించడానికి కస్టమ్ నాన్-ఎగుమతి రకం కీలు.

గొలుసు వెంట ప్రచారం

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 స్వయంచాలకంగా r.Context()ని రద్దు చేస్తుంది డిస్‌కనెక్ట్ అవుతుంది లేదా హ్యాండ్లర్ తిరిగి వచ్చినప్పుడు. దాన్ని అందరికీ ప్రచారం చేయడం ద్వారా దిగువ కాల్‌లు, మొత్తం ట్రీ ఆఫ్ ఆపరేషన్లు రద్దు చేయబడ్డాయి క్యాస్కేడ్: డిస్‌కనెక్ట్ తర్వాత వృధా పని లేదు.

దీనిని ప్రయత్నించండి

వ్యాయామం#go.m7.l5.e1
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

సందర్భం నుండి 1-సెకన్ సమయం ముగియడంతో సందర్భాన్ని సృష్టించండి. నేపథ్యం() మరియు వాయిదాతో రద్దు చేయడానికి కాల్ చేయాలని గుర్తుంచుకోండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

`context.WithTimeout(తల్లిదండ్రులు, d)` తిరిగి `(ctx, రద్దు)`; ఎల్లప్పుడూ కాల్ రద్దు చేయండి.

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().
  • "లాంగ్" ఫంక్షన్‌లు తప్పనిసరిగా selectలో ctx.Done() లేదా ctxని ప్రామాణిక ప్యాకేజీలకు పాస్ చేయాలి.
  • కన్వెన్షన్: ctx FIRST పరామితి వలె, ఎప్పుడూ నిర్మాణంలో ఉండదు.
  • WithValue అభ్యర్థన-స్కోప్డ్ డేటా కోసం మాత్రమే (అభ్యర్థన ID, ట్రేస్ ID).
  • net/httpలో, క్లయింట్ డిస్‌కనెక్ట్ అయినప్పుడు r.Context() రద్దు చేయబడింది.