Sobes.tech
Middle

Pověz mi o případech použití kontextu v Go.

sobes.tech AI

Odpověď od AI

Kontext v Go se používá k řízení životního cyklu požadavků a kontrole provádění gorutin. Hlavní případy použití:

  • Zrušení: Umožňuje zrušit řetězec gorutin spojený s určitým požadavkem. Například při uzavření spojení nebo po časovém limitu.
  • Časový limit: Nastavuje konečný termín provedení operace. Pokud operace není dokončena včas, kontext je zrušen. To zabraňuje nekonečnému čekání.
  • Předávání specifických dat požadavku: Umožňuje předávat data související s konkrétním požadavkem (například ID uživatele, identifikátor trasování) přes řetězec volání funkcí bez změny jejich podpisů.

Příklady použití:

  1. Zrušení podle signálu:

    balíček main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    funkce worker(ctx context.Context, id int) {
    	pro {
    		výběr {
    		případ <-ctx.Done():
    			fmt.Printf("Pracovník %d přerušen\n", id)
    			return
    		default:
    			fmt.Printf("Pracovník %d pracuje...\n", id)
    			čas.Sleep(500 * time.Millisecond)
    		}
    	}
    }
    
    funkce main() {
    	ctx, cancel := context.WithCancel(context.Background())
    	defer cancel() // Zaručíme zrušení
    
    	go worker(ctx, 1)
    	go worker(ctx, 2)
    
    	time.Sleep(2 * time.Second)
    	cancel() // Zrušíme kontext
    
    	time.Sleep(500 * time.Millisecond) // Dáme čas gorutinám dokončit
    }
    
  2. Časový limit:

    balíček main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    funkce longOperation(ctx context.Context) error {
    	výběr {
    	případ <-time.After(3 * time.Second): // Simulace dlouhé práce
    		fmt.Println("Operace úspěšně dokončena")
    		return nil
    	případ <-ctx.Done():
    		fmt.Println("Operace zrušena kontextem:", ctx.Err())
    		return ctx.Err()
    	}
    }
    
    funkce main() {
    	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    	defer cancel()
    
    	err := longOperation(ctx)
    	if err != nil {
    		fmt.Println("Chyba:", err)
    	}
    }
    
  3. Předávání dat:

    balíček main
    
    import (
    	"context"
    	"fmt"
    )
    
    type UserKey string
    
    const userIDKey UserKey = "userID"
    
    func processRequest(ctx context.Context) {
    	userID := ctx.Value(userIDKey).(int)
    	fmt.Printf("Zpracování požadavku pro uživatelské ID: %d\n", userID)
    	// Další zpracování požadavku s použitím userID
    }
    
    func main() {
    	ctx := context.WithValue(context.Background(), userIDKey, 123)
    	processRequest(ctx)
    }