# Use case

Message queues are a powerful tool for building scalable and reliable distributed systems. They help decouple components, manage load, and improve resilience. Here are some scenarios and features where using a message queue can be highly beneficial:

#### 1. **Asynchronous Processing**

**Use Case:** When a task can be performed asynchronously without requiring immediate feedback to the user.

**Example:** A web application that processes image uploads. Instead of processing the image (resizing, filtering, etc.) synchronously, which would make the user wait, the app can enqueue the task and immediately return a response. A background worker then processes the image.

#### 2. **Load Leveling**

**Use Case:** To handle sudden spikes in load by queuing requests and processing them at a manageable rate.

**Example:** An online store during a flash sale. Instead of overwhelming the payment processing system, orders can be queued and processed sequentially.

#### 3. **Decoupling Microservices**

**Use Case:** To enable communication between microservices without tightly coupling them.

**Example:** A microservice architecture where a user service needs to notify an email service when a new user registers. The user service can publish a message to a queue that the email service consumes.

#### 4. **Reliable Communication**

**Use Case:** To ensure that messages are not lost even if the system crashes or becomes unavailable.

**Example:** A financial application where transaction logs are written to a queue to ensure they are processed and stored reliably, even if parts of the system fail.

#### 5. **Task Scheduling**

**Use Case:** To schedule tasks to be executed at a later time.

**Example:** Sending reminder emails or notifications at a specific time or after a certain delay.

#### 6. **Event Sourcing**

**Use Case:** To capture a sequence of events and replay them if necessary.

**Example:** An e-commerce platform that logs every change in the state of an order (created, paid, shipped) to a message queue, enabling the reconstruction of the state by replaying events.

#### 7. **Rate Limiting**

**Use Case:** To control the rate at which requests are processed.

**Example:** An API that interacts with a third-party service with rate limits. Requests can be queued and processed at a rate that respects the third-party service's limitations.

#### Example Implementation: Using RabbitMQ with C\#

**Installing RabbitMQ Client**

First, install the RabbitMQ client library for .NET:

```shell
dotnet add package RabbitMQ.Client
```

**Producer (Publishing Messages)**

Here's an example of a producer that sends messages to a queue:

```csharp
using System;
using System.Text;
using RabbitMQ.Client;

public class Producer
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using var connection = factory.CreateConnection();
        using var channel = connection.CreateModel();
        
        channel.QueueDeclare(queue: "task_queue",
                             durable: true,
                             exclusive: false,
                             autoDelete: false,
                             arguments: null);

        string message = "Hello World!";
        var body = Encoding.UTF8.GetBytes(message);

        var properties = channel.CreateBasicProperties();
        properties.Persistent = true;

        channel.BasicPublish(exchange: "",
                             routingKey: "task_queue",
                             basicProperties: properties,
                             body: body);

        Console.WriteLine(" [x] Sent {0}", message);
    }
}
```

**Consumer (Consuming Messages)**

Here's an example of a consumer that reads messages from a queue:

```csharp
using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

public class Consumer
{
    public static void Main()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using var connection = factory.CreateConnection();
        using var channel = connection.CreateModel();

        channel.QueueDeclare(queue: "task_queue",
                             durable: true,
                             exclusive: false,
                             autoDelete: false,
                             arguments: null);

        var consumer = new EventingBasicConsumer(channel);
        consumer.Received += (model, ea) =>
        {
            var body = ea.Body.ToArray();
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);
        };

        channel.BasicConsume(queue: "task_queue",
                             autoAck: true,
                             consumer: consumer);

        Console.WriteLine(" Press [enter] to exit.");
        Console.ReadLine();
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huy312100.gitbook.io/software-development/message-broker/rabbitmq/use-case.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
