ماڈیول اسباق (5/5)
'context.Context': منسوخی اور آخری تاریخ
context پیکیج پروپیگنڈہ کرنے کے لیے اصل معیار ہے
کال چین کے ساتھ منسوخی، ڈیڈ لائنز اور دائرہ کار کی پابند اقدار،
متعدد goroutines بھر میں. تمام معیاری "نیٹ ورکنگ" پیکجز
(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 opzionalectxALWAYS پہلے پیرامیٹر کے طور پر، جس کا نام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 { ... }رہنما خطوط:
- صرف درخواست کے دائرہ کار ڈیٹا کے لیے (درخواست 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() جب کلائنٹ
منقطع ہوجاتا ہے یا جب ہینڈلر واپس آتا ہے۔ اسے سب تک پہنچا کر
ڈاؤن اسٹریم کالز، آپریشن کا پورا درخت میں منسوخ کر دیا گیا ہے۔
جھرن: منقطع ہونے کے بعد کوئی ضائع شدہ کام نہیں۔
اسے آزمائیں
context.Background() سے اخذ کردہ 1 سیکنڈ کے ٹائم آؤٹ کے ساتھ ایک سیاق و سباق بنائیں اور ڈیفر کے ساتھ کال کینسل کرنا یاد رکھیں۔
اشارہ دکھائیں۔
`context.WithTimeout(parent, d)` ریٹرن `(ctx, cancel)`; ہمیشہ کال منسوخ کریں.
3 کوششوں کے بعد حل دستیاب ہے۔
سیاق و سباق کے منسوخ ہونے کا انتظار کرنے کے لیے انتخاب میں <-ctx.Done() استعمال کریں۔
اشارہ دکھائیں۔
`ctx.Done()` ایک ایسا چینل ہے جو سیاق و سباق کے منسوخ ہونے پر بند ہو جاتا ہے۔
3 کوششوں کے بعد حل دستیاب ہے۔
کنونشن کے مطابق، فنکشن کے دستخط میں ctx پیرامیٹر کہاں جاتا ہے؟
func Fetch(???, url string) ([]byte, error)Recap
context.Contextمنسوخی، ڈیڈ لائن اور دائرہ کار کی قدروں کا پرچار کرتا ہے۔Background()/TODO()بطور جڑ؛WithCancel/WithTimeout/WithDeadlineحاصل کرنا۔- وسائل جاری کرنے کے لیے ہمیشہ
defer cancel()۔ - "طویل" فنکشنز کو
selectپرctx.Done()یا معیاری پیکجوں میں ctx پاس کرنا چاہئے۔ - کنونشن:
ctxبطور FIRST پیرامیٹر، کبھی بھی ساخت کے اندر نہیں۔ WithValueصرف درخواست کے دائرہ کار والے ڈیٹا کے لیے (درخواست ID، ٹریس ID)۔net/httpمیں،r.Context()کلائنٹ کے منقطع ہونے پر منسوخ ہو گیا ہے۔