Async Systems
Request Tracking
System Completion Status
Technology
Programming

How to track requests and completion status in async systems?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Asynchronous systems are a mainstay in the world of distributed computing, particularly when it comes to handling I/O-bound or network-bound tasks. These systems allow tasks to be processed in a non-blocking manner, promoting better system throughput and responsiveness. However, managing and tracking requests in such an environment can be challenging due to the decoupled nature of service execution. In this article, we’ll explore several methods and tools that can be used to effectively track requests and monitor the completion status in asynchronous systems.

Understanding Asynchronous Operations

In asynchronous systems, operations are typically initiated without waiting for the results to be immediately available. This decoupling of request initiation and result handling enables a system to handle other tasks while waiting for resources or operations that take time to complete, such as database queries or calls to external services.

However, this model introduces complexities in monitoring which tasks have started, are in progress, or have completed, and how errors are handled.

Techniques for Tracking and Monitoring

1. Logging

The simplest method of tracking requests in an asynchronous system is through logging. Each request may generate logs at various stages of its handling:

  • Request Received: Log when a request is received.
  • Request Processing: Log when the request processing starts and ends.
  • Request Completion: Log the outcome of the request.

For example, consider a Node.js application using the winston logging library:

javascript
1const logger = require('winston');
2
3function handleRequest(req) {
4    logger.info(`Request received: ${req.id}`);
5    processRequest(req).then(result => {
6        logger.info(`Request processed: ${req.id}, Result: ${result}`);
7    }).catch(error => {
8        logger.error(`Request ${req.id} failed, Error: ${error.message}`);
9    });
10}

2. Correlation IDs

In complex systems where a request might span multiple services, generating a unique correlation ID for each request helps in tracing its path across services.

A typical approach is to generate a UUID for each incoming request at the gateway level and pass this ID through all services involved in handling the request.

python
1import uuid
2
3def handle_request(request):
4    correlation_id = str(uuid.uuid4())
5    logger.info(f"Handling request with correlation ID: {correlation_id}")
6    # Pass correlation_id to all services and datastores

3. Distributed Tracing

Distributed tracing extends the concept of correlation IDs by providing tools and services that specifically design visual trace routes through which a request travels. Tools like Jaeger, Zipkin, and AWS X-Ray can provide detailed visualizations of request flow and latency in a system.

Here’s how you might integrate such a tool in a service:

java
1import io.jaegertracing.Configuration;
2import io.jaegertracing.internal.JaegerTracer;
3
4public JaegerTracer initTracer(String service) {
5    return new Configuration(service)
6        .withSampler(new Configuration.SamplerConfiguration().withType("const").withParam(1))
7        .withReporter(new Configuration.ReporterConfiguration().withLogSpans(true))
8        .getTracer();
9}

4. Status Tracking via Databases or In-Memory Stores

For some use cases, especially in job processing systems, it might be necessary to track job status in a more persistent or queryable form:

  • Submitted: Job has been received.
  • In Progress: Job is currently being processed.
  • Completed: Job has completed with a result.
  • Failed: Job has failed with an error.

Storing this information in a database or an in-memory data store like Redis can facilitate easy querying of job statuses, as shown:

sql
1CREATE TABLE job_status (
2    job_id VARCHAR PRIMARY KEY,
3    status VARCHAR NOT NULL,
4    last_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
5);
6
7UPDATE job_status SET status = 'In Progress' WHERE job_id = '123';

Key Tools and Techniques Summary

Tool/TechniquePurpose
LoggingSimple debugging and tracking
Correlation IDsTrace requests across services
Distributed TracingDetailed, visual trace analysis
Database/In-MemoryPersistent job status tracking

Conclusion

Tracking request status and completion in asynchronous systems requires thought-out placement of log statements, usage of correlation IDs or more sophisticated tools like distributed tracing systems. Depending on the scale and need of your application, persistent storage tracking can also be utilized to monitor job statuses and facilitate system observability and debuggability. Combining these methods appropriately will give you a comprehensive view of the processes and improve the maintainability of asynchronous operations.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.