Hone logo
Hone
Problems

Context Propagation in Go: A Distributed Task Manager

Context propagation is a crucial pattern in distributed systems and concurrent Go programs. This challenge asks you to implement a simplified context propagation mechanism to track request IDs across multiple functions, simulating a distributed task manager where each function represents a microservice or a stage in a processing pipeline. This allows for easier debugging and tracing of requests as they flow through the system.

Problem Description

You are tasked with creating a ContextPropagator that allows you to associate a request ID with a context.Context and propagate that ID to subsequent functions. The ContextPropagator should provide the following functionalities:

  1. WithRequestID(ctx context.Context, requestID string) context.Context: This function takes an existing context.Context and a requestID (a string) and returns a new context.Context with the requestID associated with it. The requestID should be stored in a key named "request-id" within the context.

  2. GetRequestID(ctx context.Context) (string, bool): This function takes a context.Context and attempts to retrieve the requestID associated with it. It should return the requestID as a string and a boolean indicating whether the requestID was found in the context. If the requestID is not present, it should return an empty string and false.

You will also need to implement two example functions, processStage1 and processStage2, that demonstrate the propagation of the request ID using your ContextPropagator. processStage1 should take a context and a request ID, add the request ID to the context, and then call processStage2 with the modified context. processStage2 should retrieve the request ID from the context and print it.

Examples

Example 1:

Input:
  - Initial context: context.Background()
  - requestID: "12345"

Output:
  - processStage2 output: "Request ID: 12345"
Explanation:
  - processStage1 receives the initial context and "12345".
  - processStage1 creates a new context with the request ID "12345" associated with the "request-id" key.
  - processStage1 calls processStage2 with the new context.
  - processStage2 retrieves the request ID "12345" from the context and prints it.

Example 2:

Input:
  - Initial context: context.Background()
  - requestID: "" (empty string)

Output:
  - processStage2 output: "Request ID: " (empty string)
Explanation:
  - processStage1 receives the initial context and an empty string.
  - processStage1 creates a new context with an empty string associated with the "request-id" key.
  - processStage1 calls processStage2 with the new context.
  - processStage2 retrieves the empty string from the context and prints it.

Example 3: (Edge Case - No Request ID)

Input:
  - Initial context: context.Background()

Output:
  - processStage2 output: "Request ID: " (empty string)
Explanation:
  - processStage1 receives the initial context and no request ID.
  - processStage1 creates a new context with no request ID associated with the "request-id" key.
  - processStage1 calls processStage2 with the new context.
  - processStage2 attempts to retrieve the request ID from the context, finds nothing, and returns an empty string.

Constraints

  • The requestID will be a string.
  • The context key for the request ID must be "request-id".
  • The solution must be implemented in Go.
  • The solution should be efficient and avoid unnecessary memory allocations.

Notes

  • Consider using context.WithValue to associate the request ID with the context.
  • Remember to handle the case where the request ID is not present in the context gracefully.
  • The focus is on the context propagation mechanism itself, not on the actual processing logic within processStage1 and processStage2. They are simply placeholders to demonstrate the propagation.
  • Error handling is not required for this challenge. The focus is on the context propagation logic.
  • The context.Context is immutable. You must create a new context when adding a value.
Loading editor...
go