slogan3

Ontwikkel een Go-applicatie met contextbeheer voor geavanceerde controle

description

Met deze prompt leer je hoe je contextbeheer in Go kunt toepassen voor betere controle over gelijktijdige processen, waardoor je applicaties robuuster en responsiever worden. Het helpt problemen met onbeheerde goroutines en resource leaks te voorkomen, wat beter is dan eenvoudige foutafhandeling of basisconcurrentie.

prompt

Help me een Go-applicatie te ontwikkelen die gebruikmaakt van contextbeheer voor het afhandelen van deadlines, annuleringen en time-outs in concurrente processen. Leg uit h ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een stapsgewijze uitleg over het gebruik van contexten in Go, inclusief een voorbeeld voor jouw webcrawler scenario: 1. Context maken: Gebruik `context.Background()` of `context.WithTimeout()` om een context te creëren. Voor jouw scenario, waarin de crawler binnen 10 seconden moet stoppen als de server niet reageert, is `context.WithTimeout()` geschikt. 2. Context doorgeven: Geef de context door aan functies die mogelijk lang duren of die je wilt kunnen annuleren, zoals HTTP-verzoeken of andere bewerkingen. 3. Context afhandelen: Controleer de context op annulering of deadline door `ctx.Done()` te lezen, of door `ctx.Err()` te gebruiken. Hier is een voorbeeldcode voor jouw webcrawler: ```go package main import ( "context" "fmt" "net/http" "time" ) func main() { // Maak een context met een timeout van 10 seconden ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Zorg dat resources vrijgegeven worden url := "http://voorbeeld.com" // Vervang door de echte URL // Start de crawl met de context err := crawl(ctx, url) if err != nil { fmt.Println("Crawling gestopt:", err) } else { fmt.Println("Crawling voltooid") } } // crawl voert een HTTP GET uit en stopt als de context geannuleerd wordt func crawl(ctx context.Context, url string) error { // Maak een HTTP request met de context req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return err } client := &http.Client{} // Voer het verzoek uit resp, err := client.Do(req) if err != nil { return err } defer resp.Body.Close() // Hier zou je de inhoud verwerken // Bijvoorbeeld: lees de body // _, err = io.Copy(os.Stdout, resp.Body) // if err != nil { // return err // } // Voor dit voorbeeld simuleren we een bewerking die mogelijk lang duurt select { case <-time.After(5 * time.Second): // Simulatie van verwerkingstijd return nil case <-ctx.Done(): // Context is geannuleerd of deadline bereikt return ctx.Err() } } ``` **Samenvatting:** - Maak een context met `context.WithTimeout()` voor de maximale tijd. - Geef de context door aan alle bewerkingen die je wilt kunnen annuleren. - Controleer `ctx.Done()` of gebruik `http.NewRequestWithContext()` om automatisch te stoppen bij annulering of timeout. - Zorg dat je `defer cancel()` gebruikt om resources vrij te geven. Op deze manier beheer je efficiënt deadlines en annuleringen in je Go-webcrawler!
provider: deepseek
model: deepseek-chat
Zeker, ik help je graag met het ontwikkelen van een Go-webcrawler met contextbeheer. Hier is een complete uitleg en implementatie: ## Contextbeheer in Go ### 1. Context aanmaken ```go package main import ( "context" "fmt" "net/http" "time" "sync" ) func main() { // Context met 10 seconden timeout ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Zorgt voor proper cleanup startCrawler(ctx) } ``` ### 2. Webcrawler met context doorgeven ```go func startCrawler(ctx context.Context) { urls := []string{ "https://example.com", "https://example.org", "https://example.net", } var wg sync.WaitGroup results := make(chan string, len(urls)) for _, url := range urls { wg.Add(1) go crawlURL(ctx, &wg, url, results) } // Wacht op alle goroutines of context cancellation go func() { wg.Wait() close(results) }() // Verzamel resultaten for result := range results { fmt.Println(result) } } ``` ### 3. Crawl-functie met context handling ```go func crawlURL(ctx context.Context, wg *sync.WaitGroup, url string, results chan<- string) { defer wg.Done() // Maak HTTP request met context req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { results <- fmt.Sprintf("Fout bij aanvraag %s: %v", url, err) return } client := &http.Client{ Timeout: 5 * time.Second, // Individuele request timeout } // Voer request uit resp, err := client.Do(req) // Controleer of context geannuleerd is select { case <-ctx.Done(): results <- fmt.Sprintf("Geannuleerd: %s - %v", url, ctx.Err()) return default: // Doorgaan als context niet geannuleerd is } if err != nil { results <- fmt.Sprintf("Fout: %s - %v", url, err) return } defer resp.Body.Close() results <- fmt.Sprintf("Success: %s - Status: %d", url, resp.StatusCode) } ``` ### 4. Verbeterde versie met error handling ```go func advancedCrawler(ctx context.Context) { ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() urls := []string{"https://example.com", "https://example.org"} for _, url := range urls { select { case <-ctx.Done(): fmt.Println("Crawler gestopt:", ctx.Err()) return default: result := fetchWithRetry(ctx, url, 3) fmt.Println(result) } } } func fetchWithRetry(ctx context.Context, url string, maxRetries int) string { for attempt := 1; attempt <= maxRetries; attempt++ { select { case <-ctx.Done(): return fmt.Sprintf("Geannuleerd: %s", url) default: result, err := fetchURL(ctx, url) if err == nil { return result } if attempt < maxRetries { time.Sleep(time.Duration(attempt) * time.Second) } } } return fmt.Sprintf("Mislukt na %d pogingen: %s", maxRetries, url) } func fetchURL(ctx context.Context, url string) (string, error) { req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return "", err } client := http.Client{Timeout: 3 * time.Second} resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() return fmt.Sprintf("Success: %s (%d)", url, resp.StatusCode), nil } ``` ## Belangrijke concepten: ### Context types: - `context.Background()` - Basis context - `context.WithTimeout()` - Timeout na bepaalde tijd - `context.WithCancel()` - Handmatige annulering - `context.WithDeadline()` - Specifieke eindtijd ### Best practices: 1. **Always pass context as first parameter** 2. **Check `ctx.Done()` in lange operaties** 3. **Use `defer cancel()` voor proper cleanup** 4. **Propageer context naar downstream calls** ### Context monitoring: ```go func monitorContext(ctx context.Context) { go func() { <-ctx.Done() fmt.Println("Context geannuleerd:", ctx.Err()) }() } ``` Deze implementatie zorgt ervoor dat je webcrawler: - Stopt na 10 seconden totaal - Individuele requests timeouten na 5 seconden - Proper afhandelt bij annuleringen - Resources goed opruimt Run met: `go run crawler.go`