Skip to content

Latest commit

 

History

History

01_context

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

🌐 context in Go

💡 What is context?

context is a mechanism in Go that helps transmit cancellation signals, deadlines, and other request-scoped values across goroutines. It is especially useful in concurrent programming, where you need to manage the lifecycle of goroutines, handle timeouts, and propagate cancellation signals.

  • Purpose: Manage and control the lifecycle of goroutines.
  • How it works: context helps propagate cancellation, timeouts, and values between goroutines, without relying on global variables.

📝 How to Use context

  1. Creating a Context:

    • Use functions from the context package like context.Background(), context.TODO(), and context.WithCancel() to create a new context.
  2. Canceling a Context:

    • Use context.WithCancel() to create a context that can be canceled when certain actions are completed.
  3. Timeout and Deadline:

    • Use context.WithTimeout() and context.WithDeadline() to set a timeout for operations.
  4. Passing Values in Context:

    • You can use context.WithValue() to pass global values between goroutines.

💡 Example: Using Context for Cancellation

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// Create context with cancellation
	ctx, cancel := context.WithCancel(context.Background())

	// Goroutine performing work
	go func() {
		for {
			select {
			case <-ctx.Done():
				// If context is canceled
				fmt.Println("Operation canceled!")
				return
			default:
				// Normal work
				fmt.Println("Working...")
				time.Sleep(1 * time.Second)
			}
		}
	}()

	// Cancel the context after 3 seconds
	time.Sleep(3 * time.Second)
	cancel()

	// Wait for goroutine to finish
	time.Sleep(1 * time.Second)
}

💡 Example: Using Context with Timeout

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	// Create context with a 2-second timeout
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	// Goroutine waits until timeout or completes work
	go func() {
		select {
		case <-ctx.Done():
			// Context expired
			fmt.Println("Timed out!")
		case <-time.After(3 * time.Second):
			// Simulate work that takes 3 seconds
			fmt.Println("Work completed")
		}
	}()

	// Wait for goroutine to finish or timeout
	time.Sleep(4 * time.Second)
}

💡 Example: Passing Values in Context

package main

import (
	"context"
	"fmt"
)

func main() {
	// Create context with value
	ctx := context.WithValue(context.Background(), "userID", 12345)

	// Goroutine reads value from context
	go func(ctx context.Context) {
		userID := ctx.Value("userID").(int)
		fmt.Printf("User ID from context: %d\n", userID)
	}(ctx)

	// Wait for goroutine to finish
	time.Sleep(1 * time.Second)
}

🛠 Key Concepts in context

  • Cancellation: Allows you to cancel ongoing tasks in goroutines when no longer needed.
  • Timeouts and Deadlines: Controls the maximum duration for tasks and goroutines. If the task doesn’t complete within the allowed time, the context expires, signaling cancellation.
  • Context Propagation: Transmits cancellation signals and values across API boundaries between goroutines.

💡 Real-World Use Cases for context

  1. Web Servers and HTTP Requests

    • Scenario: Web applications handle multiple HTTP requests, each requiring a clear lifecycle with timeouts and cancellation if necessary.
    • Solution: Use context to cancel HTTP requests if they exceed the timeout or if the client cancels the request.
  2. Distributed Systems and API Calls

    • Scenario: In distributed systems, API calls between services need to be managed with timeouts and cancellation.
    • Solution: Use context to manage request lifetimes and propagate cancellation signals between services.
  3. Parallel Operations

    • Scenario: When executing multiple tasks concurrently, you may need to cancel tasks if one of them fails or exceeds its allocated time.
    • Solution: Use context to cancel other goroutines when one task fails or exceeds the timeout.

⚠️ Best Practices for context

  • Use Context to Manage Timeouts and Cancellation: Always use context to manage timeouts and cancellations, especially when dealing with external APIs or services.
  • Avoid Using Context for Global State: Context is not meant for passing global state. Use it to propagate cancellation, deadlines, or request-scoped values.
  • Propagate Context Across API Boundaries: Always pass the context across API boundaries, especially when calling functions from other goroutines.

🚀 Summary

  • context is a powerful tool for managing the lifecycle of goroutines, particularly when handling timeouts, cancellations, or propagating global values.
  • Understanding and using context correctly can help you avoid performance problems and resource management issues in concurrent or distributed applications.