آشنایی کامل با استفاده از Context در Go

Context یکی از ابزارهای قدرتمند زبان برنامه‌نویسی Go است که برای مدیریت درخواست‌ها، لغو عملیات، تنظیم زمان اجرا و انتقال داده بین بخش‌های مختلف یک برنامه استفاده می‌شود. این قابلیت به ویژه در ساخت برنامه‌های شبکه‌ای و سرویس‌های مبتنی بر HTTP بسیار کاربردی است.

چرا Context مهم است؟

وقتی با برنامه‌هایی که نیازمند مدیریت همزمانی (Concurrency) هستند کار می‌کنید، معمولاً نیاز دارید کنترل بیشتری روی زمان اجرای درخواست‌ها یا لغو عملیات داشته باشید. Context این امکان را فراهم می‌کند که:

  • لغو درخواست‌ها: زمانی که یک عملیات طولانی مدت دیگر نیازی به اجرا ندارد.
  • تنظیم محدودیت زمانی: برای جلوگیری از اجرای طولانی مدت یک فرآیند.
  • انتقال داده: بین بخش‌های مختلف کد بدون نیاز به پارامترهای اضافی.

ایجاد Context اولیه

برای شروع، کتابخانه context را وارد کنید و یک Context پایه بسازید:

package main
import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx := context.Background() // ایجاد یک Context پایه
    fmt.Println("Context ایجاد شد:", ctx)
}

انواع Context اولیه

  1. Background: برای موارد عمومی و پیش‌فرض.
  2. TODO: زمانی که هنوز مشخص نیست چه نوع Contextی مورد نیاز است.

اضافه کردن محدودیت زمانی به Context

محدودیت زمانی یکی از ویژگی‌های کاربردی Context است. می‌توانید با استفاده از context.WithTimeout یا context.WithDeadline محدودیت زمانی ایجاد کنید:

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel() // آزاد کردن منابع پس از پایان کار

    select {
    case <-time.After(3 * time.Second):
        fmt.Println("عملیات کامل شد")
    case <-ctx.Done():
        fmt.Println("لغو شد:", ctx.Err())
    }
}

در مثال بالا، اگر عملیات بیش از دو ثانیه طول بکشد، Context آن را لغو می‌کند.

انتقال داده با Value در Context

گاهی نیاز دارید اطلاعات خاصی را بین بخش‌های مختلف کد منتقل کنید. برای این کار می‌توانید از context.WithValue استفاده کنید:

func main() {
    ctx := context.WithValue(context.Background(), "key", "value")
    process(ctx)
}

func process(ctx context.Context) {
    value := ctx.Value("key")
    fmt.Println("مقدار منتقل شده: ", value)
}

در اینجا مقدار «value» با کلید «key» ذخیره و سپس در تابع دیگر خوانده شده است.

نکات مهم هنگام استفاده از Context

  1. همیشه پس از ساخت یک Context مشتق‌شده مانند WithTimeout یا WithCancel، تابع cancel را فراخوانی کنید تا منابع آزاد شوند.
  2. از انتقال داده‌های بزرگ یا حساس در context.Value خودداری کنید؛ بهتر است داده‌ها مستقیماً منتقل شوند.
  3. توجه داشته باشید که Context برای ارتباط بین توابع است و نباید به عنوان پایگاه داده کوچک استفاده شود.

نتیجه‌گیری

Context یکی از ابزارهای کلیدی زبان Go است که به شما امکان مدیریت بهتر زمان اجرا، لغو عملیات و انتقال داده بین توابع مختلف را می‌دهد. با یادگیری نحوه استفاده صحیح از این قابلیت، می‌توانید برنامه‌هایی قابل اعتمادتر و منعطف‌تر بسازید.