మాడ్యూల్ పాఠాలు (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() మూసివేయబడుతుంది మరియు
ఫంక్షన్ తప్పనిసరిగా ఆపరేషన్ను నిలిపివేయాలి.
సందర్భాన్ని గౌరవిస్తూ: పూర్తయింది()ని ఎంచుకోండి
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ని నిర్వహించాలి. పూర్తయింది()**. లేకపోతే, సందర్భం "పవర్ ఆన్ చేయబడింది" ఏమీ లేదు.
మొదటి పారామితి సమావేశం
func Fetch(ctx context.Context, url string) ([]byte, error) { ... }
// ^^^^^^^^^^^^^^^^^^^
// SEMPRE primo, mai dentro a una struct, mai opzionalectxఎల్లప్పుడూ మొదటి పారామీటర్గా,ctxఅని పేరు పెట్టబడింది.- ఎప్పుడూ
Contextని స్ట్రక్ట్ ఫీల్డ్గా పెట్టండి (చాలా అరుదైన మినహాయింపులు). - ఎప్పటికీ పాస్
nil:context.TODO()ని స్టబ్గా ఉపయోగించండి.
సందర్భం.విలువతో: పొదుపుగా
type userKey struct{}
ctx := context.WithValue(ctx, userKey{}, currentUser)
// più sotto:
if u, ok := ctx.Value(userKey{}).(*User); ok { ... }మార్గదర్శకాలు:
- అభ్యర్థన-స్కోప్డ్ డేటా (అభ్యర్థన ID, ట్రేస్ ID, వినియోగదారు గుర్తింపు) కోసం మాత్రమే.
- ఫంక్షన్ పారామీటర్ల కోసం ఎప్పుడూ చేయవద్దు: వాటిని సాధారణంగా పాస్ చేయండి.
- ఘర్షణలను నివారించడానికి కస్టమ్ నాన్-ఎగుమతి రకం కీలు.
గొలుసు వెంట ప్రచారం
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()ని రద్దు చేస్తుంది
డిస్కనెక్ట్ అవుతుంది లేదా హ్యాండ్లర్ తిరిగి వచ్చినప్పుడు. దాన్ని అందరికీ ప్రచారం చేయడం ద్వారా
దిగువ కాల్లు, మొత్తం ట్రీ ఆఫ్ ఆపరేషన్లు రద్దు చేయబడ్డాయి
క్యాస్కేడ్: డిస్కనెక్ట్ తర్వాత వృధా పని లేదు.
దీనిని ప్రయత్నించండి
సందర్భం నుండి 1-సెకన్ సమయం ముగియడంతో సందర్భాన్ని సృష్టించండి. నేపథ్యం() మరియు వాయిదాతో రద్దు చేయడానికి కాల్ చేయాలని గుర్తుంచుకోండి.
సూచనను చూపించు
`context.WithTimeout(తల్లిదండ్రులు, d)` తిరిగి `(ctx, రద్దు)`; ఎల్లప్పుడూ కాల్ రద్దు చేయండి.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
సందర్భం రద్దు చేయబడే వరకు వేచి ఉండటానికి ఎంపికలో <-ctx.Done()ని ఉపయోగించండి.
సూచనను చూపించు
`ctx.Done()` అనేది సందర్భం రద్దు చేయబడినప్పుడు మూసివేయబడే ఛానెల్.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
సంప్రదాయం ప్రకారం, ఫంక్షన్ సిగ్నేచర్లో ctx పరామితి ఎక్కడికి వెళుతుంది?
func Fetch(???, url string) ([]byte, error)రీక్యాప్
context.Contextరద్దు, గడువు మరియు స్కోప్-బౌండ్ విలువలను ప్రచారం చేస్తుంది.Background()/TODO()రూట్గా;WithCancel/WithTimeout/WithDeadlineఉత్పన్నం చేయడానికి.- వనరులను విడుదల చేయడానికి ఎల్లప్పుడూ
defer cancel(). - "లాంగ్" ఫంక్షన్లు తప్పనిసరిగా
selectలోctx.Done()లేదా ctxని ప్రామాణిక ప్యాకేజీలకు పాస్ చేయాలి. - కన్వెన్షన్:
ctxFIRST పరామితి వలె, ఎప్పుడూ నిర్మాణంలో ఉండదు. WithValueఅభ్యర్థన-స్కోప్డ్ డేటా కోసం మాత్రమే (అభ్యర్థన ID, ట్రేస్ ID).net/httpలో, క్లయింట్ డిస్కనెక్ట్ అయినప్పుడుr.Context()రద్దు చేయబడింది.