Sobes.tech
Middle

Разкажи ми за случаите на използване на контекста в Go.

sobes.tech AI

Отговор от AI

Контекстът в Go се използва за управление на жизнения цикъл на заявките и контрол на изпълнението на горутините. Основните случаи на употреба:

  • Отмяна: Позволява да се отменя веригата от горутини, свързана с определена заявка. Например при затваряне на връзката или при изтичане на таймаут.
  • Таймаут: Настройва крайния срок за изпълнение на операцията. Ако операцията не завърши навреме, контекстът се отменя. Това предотвратява безкрайно чакане.
  • Предаване на специфични за заявката данни: Позволява да се предават данни, свързани с конкретна заявка (например ID на потребител, идентификатор на трасировка), чрез веригата от функции без промяна на техните сигнатури.

Примери за употреба:

  1. Отмяна по сигнал:

    пакет main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    функция worker(ctx context.Context, id int) {
    	за {
    		избор {
    		случай <-ctx.Done():
    			fmt.Printf("Работник %d прекъснат\n", id)
    			връщане
    		default:
    			fmt.Printf("Работник %d работи...\n", id)
    			time.Sleep(500 * time.Millisecond)
    		}
    	}
    }
    
    функция main() {
    	ctx, cancel := context.WithCancel(context.Background())
    	defer cancel() // Гарантираме отмяна
    
    	go worker(ctx, 1)
    	go worker(ctx, 2)
    
    	time.Sleep(2 * time.Second)
    	cancel() // Отменяме контекста
    
    	time.Sleep(500 * time.Millisecond) // Даваме време на горутините да приключат
    }
    
  2. Таймаут:

    пакет main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    функция longOperation(ctx context.Context) error {
    	избор {
    	случай <-time.After(3 * time.Second): // Имитация на дълга работа
    		fmt.Println("Операцията успешно завърши")
    		връщане nil
    	случай <-ctx.Done():
    		fmt.Println("Операцията е отменена от контекста:", ctx.Err())
    		връщане ctx.Err()
    	}
    }
    
    функция main() {
    	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    	defer cancel()
    
    	err := longOperation(ctx)
    	ако ако err != nil {
    		fmt.Println("Грешка:", err)
    	}
    }
    
  3. Предаване на данни:

    пакет main
    
    import (
    	"context"
    	"fmt"
    )
    
    type UserKey string
    
    const userIDKey UserKey = "userID"
    
    func processRequest(ctx context.Context) {
    	userID := ctx.Value(userIDKey).(int)
    	fmt.Printf("Обработка на заявка за потребителско ID: %d\n", userID)
    	// Дальнейша обработка на заявката с използване на userID
    }
    
    func main() {
    	ctx := context.WithValue(context.Background(), userIDKey, 123)
    	processRequest(ctx)
    }