defmodule HareMq do @moduledoc """ To use HareMq in your Elixir project, follow these steps: Install the required dependencies by adding them to your `mix.exs` file: ```elixir defp deps do [ {:hare_mq, "~> 1.3.0"} ] end ``` ### Publisher The `MyApp.MessageProducer` module is responsible for publishing messages to a message queue using the `HareMq.Publisher` behavior. This module provides an interface for sending messages with specified routing and exchange settings. It also supports deduplication based on specific keys. The `MyApp.MessageProducer` module is configured with the following options: - **`routing_key`**: Specifies the routing key used to route messages to the appropriate queue. In this example, the routing key is set to `"routing_key"`. - **`exchange`**: Defines the exchange to which messages will be published. In this example, the exchange is set to `"exchange"`. - **`unique`**: This configuration option sets up deduplication rules: - **`period`**: Defines the time period for deduplication in ms. In this example, it is set to `:infinity`, meaning that messages are considered unique indefinitely based on the specified keys. - **`keys`**: A list of keys used to determine message uniqueness. If the message is a string, deduplication is managed by default behavior and you do not need to specify `keys`. If provided, deduplication is based on the specified keys. In the example, deduplication is based on the `:project_id` key. ```elixir defmodule MyApp.MessageProducer do use HareMq.Publisher, routing_key: "routing_key", exchange: "exchange" # Function to send a message to the message queue. def send_message(message) do # Publish the message using the HareMq.Publisher behavior. publish_message(message) end end ``` ```elixir defmodule MyApp.MessageProducer do use HareMq.Publisher, routing_key: "routing_key", exchange: "exchange", unique: [ period: :infinity, keys: [:project_id] ] # Function to send a message to the message queue. def send_message(message) do # Publish the message using the HareMq.Publisher behavior. publish_message(message) end end ``` ### Consumer The `MyApp.MessageConsumer` module is designed to consume messages from a message queue using the `HareMq.Consumer` behavior. This module provides the functionality to receive and process messages with specific routing and exchange settings. The `MyApp.MessageConsumer` module is configured with the following options: - **`queue_name`**: Specifies the name of the queue from which messages will be consumed. In this example, the queue name is set to `"queue_name"`. - **`routing_key`**: Defines the routing key used to filter messages. In this example, the routing key is set to `"routing_key"`. - **`exchange`**: Defines the exchange from which messages will be consumed. In this example, the exchange is set to `"exchange"`. ```elixir defmodule MyApp.MessageConsumer do use HareMq.Consumer, queue_name: "queue_name", routing_key: "routing_key", exchange: "exchange" # Function to process a received message. def consume(message) do # Log the beginning of the message processing. IO.puts("Processing message: \#{inspect(message)}") end end ``` ### Dynamic Consumer The `MyApp.MessageConsumer` module is designed to consume messages from a message queue using the `HareMq.DynamicConsumer` behavior. This module provides the functionality to receive and process messages with dynamic scaling based on the specified number of worker processes. The `MyApp.MessageConsumer` module is configured with the following options: - **`queue_name`**: Specifies the name of the queue from which messages will be consumed. In this example, the queue name is set to `"queue_name"`. - **`routing_key`**: Defines the routing key used to filter messages. In this example, the routing key is set to `"routing_key"`. - **`exchange`**: Defines the exchange from which messages will be consumed. In this example, the exchange is set to `"exchange"`. - **`consumer_count`**: Indicates the number of worker processes that should be used to handle incoming messages. In this example, `consumer_count` is set to `10`, which means that 10 worker processes will be run to consume and process messages concurrently. - **`auto_scaling`**: Allows configuration for dynamic scaling of consumers: - **`min_consumers`**: The minimum number of consumers to maintain. - **`max_consumers`**: The maximum number of consumers to maintain. - **`messages_per_consumer`**: The number of messages each consumer should handle before scaling adjustments are considered. - **`check_interval`**: The interval (in milliseconds) at which to check the queue length and adjust the number of consumers accordingly. ```elixir defmodule MyApp.MessageConsumer do use HareMq.DynamicConsumer, queue_name: "queue_name", routing_key: "routing_key", exchange: "exchange", consumer_count: 10 # Function to process a received message. def consume(message) do # Log the beginning of the message processing. IO.puts("Processing message: \#{inspect(message)}") end end ``` ### MessageConsumer with auto scaling ```elixir defmodule MyApp.MessageConsumer do use HareMq.DynamicConsumer, queue_name: "queue_name", routing_key: "routing_key", exchange: "exchange", consumer_count: 10, auto_scaling: [ min_consumers: 1, max_consumers: 20, messages_per_consumer: 100, check_interval: 5_000 ] # Function to process a received message. def consume(message) do # Log the beginning of the message processing. IO.puts("Processing message: \#{inspect(message)}") end end ``` ### Usage in Application: MyApp.Application ```elixir defmodule MyApp.Application do use Application def start(_type, _args) do children = [ # Start the message consumer. MyApp.MessageConsumer, # Start the message producer. MyApp.MessageProducer, ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end ``` ## Configuration ```elixir config :hare_mq, :amqp, host: "localhost", url: "amqp://guest:guest@myhost:12345", user: "guest", password: "guest" config :hare_mq, :configuration, delay_in_ms: 10_000, retry_limit: 15, message_ttl: 31_449_600 ``` ## Rate Us: If you enjoy using HareMq, please consider giving us a star on GitHub! Your feedback and support are highly appreciated. [GitHub](https://github.com/Dimakoua/hare_mq) """ use Application require Logger def start(_type, _args) do children = [ HareMq.Connection, HareMq.DedupCache ] opts = [strategy: :one_for_one, name: HareMq.Supervisor] Supervisor.start_link(children, opts) end end