Context in Go
Go में context
एक built-in package है जिसका उपयोग concurrent programs में cancellation, deadlines, और request-scoped values को manage करने के लिए किया जाता है। context
का उपयोग खासकर तब किया जाता है जब multiple goroutines एक साथ काम कर रही होती हैं और आपको उनमें से कुछ को terminate करना हो, या उन्हें एक निश्चित समय सीमा के अंदर काम पूरा करने के लिए कहना हो।
Why Use Context?
- Cancellation:
Context
का उपयोग एक long-running process या goroutine को बीच में रोकने के लिए किया जाता है। - Timeouts and Deadlines:
Context
का उपयोग यह specify करने के लिए किया जाता है कि एक process कितनी देर तक चलेगा और उसके बाद उसे cancel कर दिया जाएगा। - Passing Values:
Context
का उपयोग values को एक goroutine से दूसरी goroutine में pass करने के लिए किया जाता है।
Types of Contexts
context.Background()
: यह एक empty context होता है, जिसे आप base context के रूप में उपयोग करते हैं। इसे अक्सर root context कहा जाता है।context.TODO()
: यह भी एक empty context है, लेकिन इसका उपयोग तब किया जाता है जब आप context का उपयोग करना चाहते हैं लेकिन अभी तक sure नहीं हैं कि कौन-सा context उपयोग किया जाए।context.WithCancel(parentContext)
: यह एक derived context बनाता है, जिसे cancel किया जा सकता है। जब आप cancel function call करेंगे, तो यह context और उससे derived सभी contexts को cancel कर देगा।context.WithTimeout(parentContext, timeout)
: यह एक derived context बनाता है जो specified timeout के बाद automatically cancel हो जाएगा।context.WithDeadline(parentContext, deadline)
: यह context को एक fixed time पर cancel कर देता है, जिसे deadline कहा जाता है।context.WithValue(parentContext, key, value)
: यह context के साथ एक value जोड़ता है, जिसे बाद में retrieve किया जा सकता है।
Simple Real-Life Example: Web Request Handling
मान लीजिए कि आपके पास एक web server है जो कुछ external APIs को call करता है और उन calls को process करने के बाद client को response भेजता है। लेकिन अगर किसी वजह से API call बहुत ज्यादा समय ले लेता है, तो आप चाहते हैं कि वह call cancel हो जाए और user को timeout का response भेजा जाए। यहाँ पर context आपकी मदद कर सकता है।
Example: Using Context in a Web Server
package main
import (
"context"
"fmt"
"net/http"
"time"
)
// A fake external API call
func fetchData(ctx context.Context) (string, error) {
select {
case <-time.After(5 * time.Second):
return "Fetched Data", nil
case <-ctx.Done():
return "", ctx.Err()
}
}
func handler(w http.ResponseWriter, r *http.Request) {
// Creating a context with a 2-second timeout
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel() // Ensure that the cancel function is called
data, err := fetchData(ctx)
if err != nil {
fmt.Fprintf(w, "Error: %v\n", err)
return
}
fmt.Fprintf(w, "Success: %s\n", data)
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Server is listening on :8080")
http.ListenAndServe(":8080", nil)
}
Explanation:
context.WithTimeout(r.Context(), 2*time.Second)
: इस statement में हम एक context create कर रहे हैं जो कि 2-second timeout के साथ है। अगर 2 seconds के अंदर task complete नहीं होता है, तो context cancel हो जाएगा।fetchData(ctx context.Context)
: यह एक fake API call है जो 5 seconds का समय लेता है। अगर context cancel होता है (यानि 2 seconds बाद), तो यह function "context deadline exceeded" error return करेगा।select
statement: यह concurrent operations को manage करने के लिए उपयोग किया जाता है। यहाँ, अगर API call 2 seconds से अधिक समय लेता है, तो context cancellation case trigger होगा और API call को cancel कर देगा।
Basic Example of Using Context
1. Simple Context with Cancellation
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Create a context with cancellation
ctx, cancel := context.WithCancel(context.Background())
// Start a goroutine that does some work
go func() {
for {
select {
case <-ctx.Done():
fmt.Println("Goroutine stopped")
return
default:
fmt.Println("Working...")
time.Sleep(500 * time.Millisecond)
}
}
}()
// Simulate some work in main goroutine
time.Sleep(2 * time.Second)
// Cancel the context, which stops the goroutine
cancel()
// Wait to see the goroutine stop
time.Sleep(1 * time.Second)
}
Explanation:
context.WithCancel(context.Background())
: यह एक context और cancel function create करता है। जबcancel()
function call किया जाता है, तो context से जुड़ी सभी goroutines को stop कर दिया जाता है।ctx.Done()
: यह channel context के cancel होने का signal देता है। जब यह signal मिलता है, तो goroutine stop हो जाती है।- Output: यह हर 500 milliseconds पर "Working..." print करेगा और 2 सेकंड बाद "Goroutine stopped"।
2. Context with Timeout
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Create a context with a timeout of 2 seconds
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
select {
case <-time.After(3 * time.Second):
fmt.Println("Task completed")
case <-ctx.Done():
fmt.Println("Context timed out:", ctx.Err())
}
}
Explanation:
context.WithTimeout(context.Background(), 2*time.Second)
: यह context 2 seconds बाद automatically cancel हो जाएगा।ctx.Done()
: अगर timeout पूरा हो जाता है और task complete नहीं होता है, तोctx.Done()
trigger हो जाता है और "Context timed out" print होता है।- Output: चूंकि task 3 seconds का है और context 2 seconds में timeout हो रहा है, इसलिए output "Context timed out" होगा।
3. Passing Values with Context
package main
import (
"context"
"fmt"
)
func main() {
ctx := context.WithValue(context.Background(), "userID", 12345)
processRequest(ctx)
}
func processRequest(ctx context.Context) {
userID := ctx.Value("userID").(int)
fmt.Println("Processing request for user ID:", userID)
}
Explanation:
context.WithValue(context.Background(), "userID", 12345)
: यह context में "userID" key के साथ 12345 value को store करता है।ctx.Value("userID")
: यह value को retrieve करता है और "Processing request for user ID: 12345" print करता है।- Output: "Processing request for user ID: 12345"।
Common Use Cases for Context
- Web Servers: Web requests को handle करते समय, हर request के लिए एक context create किया जाता है, जिससे आप request को cancel कर सकते हैं अगर user ने page छोड़ दिया हो या timeout हो गया हो।
- Database Queries: Database में long-running queries को cancel करने के लिए context का उपयोग किया जा सकता है, ताकि system resources free हो सकें।
- Goroutine Management: अगर आप एक task को multiple goroutines में divide करते हैं और किसी वजह से उस task को cancel करना पड़ता है, तो context का उपयोग करके सभी goroutines को एक साथ cancel किया जा सकता है।
Summary
- Context: Go में concurrency को manage करने के लिए powerful tool है, जिससे आप cancellation, timeouts, और request-specific values को handle कर सकते हैं।
- Cancellation: Context का उपयोग किसी भी task को बीच में रोकने के लिए किया जा सकता है।
- Timeouts and Deadlines: Context का उपयोग time-bound tasks के लिए किया जा सकता है, ताकि वे एक fixed समय सीमा के अंदर complete हो जाएं या cancel हो जाएं।
- Values: Context का उपयोग request-scoped data को pass करने के लिए किया जा सकता है, जो multiple goroutines के बीच में share किया जा सकता है।
Context का सही उपयोग Go में concurrent programming को manage और simplify करने के लिए बहुत जरूरी है। अगर आपको context के बारे में और जानकारी चाहिए या कोई specific सवाल है, तो बताइए!
No comments:
Post a Comment