Hone logo
Hone
Problems

Go Context Management: Handling Request-Scoped Data and Cancellation

This challenge focuses on implementing and utilizing Go's context package, a crucial tool for managing request-scoped data, timeouts, and cancellations across API boundaries and between goroutines. You will build a system that simulates handling incoming requests, passing context through various stages, and reacting to cancellation signals.

Problem Description

You are tasked with creating a simplified service that processes incoming requests. Each request needs to carry a unique identifier and potentially some request-specific data. Crucially, the processing of a request might take a variable amount of time, and we need to be able to cancel it if it exceeds a certain duration or if an external signal is received.

Your goal is to:

  1. Create a context for each incoming request, including a unique request ID.
  2. Pass this context down through multiple stages of processing, simulating functions that might perform database lookups, external API calls, or other operations.
  3. Implement a timeout mechanism for the overall request processing.
  4. Demonstrate how to check for cancellation within the processing stages.
  5. Simulate an external cancellation signal that can interrupt a long-running request.

The expected behavior is that if a request times out or is externally cancelled, the processing should stop gracefully, and no further work should be done for that request.

Key Requirements

  • Context Creation: For each simulated incoming request, create a context.Context that carries a request ID.
  • Context Propagation: Pass the created context to all subsequent processing functions.
  • Timeout: Implement a mechanism to cancel the context after a specified duration (e.g., 5 seconds).
  • Cancellation Check: Within processing functions, periodically check if the context has been cancelled. If it has, stop processing and return an error.
  • External Cancellation: Allow for a separate signal (e.g., an interrupt signal from the OS) to trigger context cancellation.
  • Graceful Shutdown: Ensure that cancelled or timed-out requests do not continue to perform work.

Expected Behavior

  • Requests that complete within the timeout and without external cancellation should report success.
  • Requests that exceed the timeout should be cancelled, and the processing should stop.
  • Requests that are cancelled by an external signal should stop processing immediately.

Edge Cases to Consider

  • Requests that complete very quickly should not be affected by the timeout.
  • Multiple requests should be handled concurrently without interfering with each other's contexts.
  • Ensure proper error handling when cancellation occurs.

Examples

Example 1: Successful Request

Input: No external cancellation signal, request processing takes 2 seconds, timeout is 5 seconds.
Output:
Processing Request ID: req-123 - Stage 1 started
Processing Request ID: req-123 - Stage 1 completed
Processing Request ID: req-123 - Stage 2 started
Processing Request ID: req-123 - Stage 2 completed
Processing Request ID: req-123 - Request finished successfully

Explanation: The request completes within the 5-second timeout, and all stages of processing execute without interruption.

Example 2: Timeout Cancellation

Input: No external cancellation signal, request processing takes 7 seconds, timeout is 5 seconds.
Output:
Processing Request ID: req-456 - Stage 1 started
Processing Request ID: req-456 - Stage 1 completed
Processing Request ID: req-456 - Stage 2 started
(After 5 seconds)
Processing Request ID: req-456 - Request cancelled due to timeout.

Explanation: The request processing exceeds the 5-second timeout. The context.Done() channel will be closed after 5 seconds, signaling cancellation to the processing stages. Stage 2 (or any ongoing operation) should detect this and stop.

Example 3: External Cancellation

Input: An external OS interrupt signal (e.g., Ctrl+C) is received during request processing, request processing would take 10 seconds, timeout is 15 seconds.
Output:
Processing Request ID: req-789 - Stage 1 started
Processing Request ID: req-789 - Stage 1 completed
Processing Request ID: req-789 - Stage 2 started
(External interrupt signal received)
Processing Request ID: req-789 - Request cancelled by external signal.

Explanation: An external signal is caught and used to cancel the context for all active requests. The processing of req-789 should halt as soon as it detects the cancellation.

Constraints

  • The maximum number of concurrent requests to simulate is 10.
  • The request ID will be a string (e.g., "req-123").
  • Processing stages should simulate work using time.Sleep().
  • The timeout duration for requests will be a fixed 5 seconds.
  • The simulation should run for a maximum of 30 seconds before exiting gracefully.

Notes

  • Consider using context.WithTimeout for the timeout mechanism.
  • For external cancellation, context.WithCancel combined with listening to OS signals (os/signal) is a common pattern.
  • Within your processing functions, use a select statement to check ctx.Done() and perform the actual work concurrently. This is key to non-blocking cancellation checks.
  • Think about how to pass request-specific data along with the context using context.WithValue.
  • A good implementation will clearly show how the context.Context is passed and how ctx.Done() is used to control the flow of execution.
Loading editor...
go