تخطَّ إلى المحتوى

context.WithTimeout

مهلة زمنية لعملية context.WithTimeout

context.WithTimeout تشتق من context أب مهلةً زمنية نسبية — تُلغى القناة Done تلقائيًا عند انقضاء المدة أو عند استدعاء cancel يدويًا، أيّهما أسبق.

WithTimeout اختصار لـ WithDeadline بوقت نسبي بدل وقت مطلق: تحسب الموعد النهائي داخليًا بجمع الوقت الحالي مع المدة الممرَّرة. تعيد context مشتقًّا ودالة cancel يجب استدعاؤها دائمًا (غالبًا بـ defer) حتى لو انتهى العمل قبل انقضاء المهلة — لتحرير الموارد المرتبطة بالـ context فورًا بدل انتظار انتهاء المهلة تلقائيًا.

عند انقضاء المهلة، تُغلَق قناة Done() ويصبح Err() يساوي context.DeadlineExceeded، فيمكن لأي كود يستمع لها عبر select أن يتوقف فورًا.

الصياغة

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

📄 مثال

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

select {
case <-ctx.Done():
  fmt.Println("انتهت المهلة:", ctx.Err())
case result := <-doWork(ctx):
  fmt.Println(result)
}

أهم النقاط

العنصرالوظيفة
timeoutمدة زمنية نسبية (time.Duration) بدءًا من لحظة الاستدعاء
cancel()دالة يجب استدعاؤها دائمًا (عبر defer) لتحرير الموارد فور انتهاء الحاجة للـ context
ctx.Err()يساوي context.DeadlineExceeded بعد انقضاء المهلة

💡 نصائح عملية

  • استدعِ defer cancel() بالسطر التالي مباشرة بعد WithTimeout — عادة تُنسى إن أُجِّل كتابتها
  • مرّر context كأول معامل لأي دالة تنفّذ عملًا قد يطول (استعلام قاعدة بيانات، طلب شبكة) بدل تجاهله

⚠️ أخطاء شائعة

  • نسيان استدعاء cancel() حتى بعد نجاح العملية قبل انتهاء المهلة — يُبقي موارد داخلية محجوزة حتى انقضاء المهلة الأصلية فعليًا
  • تخزين context مشتقّ من WithTimeout بمتغيّر على مستوى الحزمة لإعادة استخدامه — المهلة تبدأ لحظة الإنشاء لا لحظة الاستخدام

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار GO الكامل بالعربي.