View Source RabbitMQStream.Producer behaviour (rabbitmq_stream v0.4.0)
RabbitMQStream.Producer
allows you to define modules or processes that publish messages to a single stream.
Defining a producer Module
A standalone producer module can be defined with:
defmodule MyApp.MyProducer do
use RabbitMQStream.Producer,
stream_name: "my-stream",
connection: MyApp.MyConnection
end
After adding it to your supervision tree, you can publish messages with:
MyApp.MyProducer.publish("Hello, world!")
You can add the producer to your supervision tree as follows this:
def start(_, _) do
children = [
# ...
MyApp.MyProducer
]
opts = # ...
Supervisor.start_link(children, opts)
end
The standalone producer starts its own RabbitMQStream.Connection
, declaring itself and fetching its most recent publishing_id
, and declaring the stream, if it does not exist.
Configuration
The RabbitMQStream.Producer accepts the following options:
:stream_name
- The name of the stream to publish to. Required.:reference_name
- The string which is used by the server to prevent Duplicate Message. Defaults to__MODULE__.Producer
.:connection
- The identifier for aRabbitMQStream.Connection
.:serializer
- The module to use to decode the message. Defaults tonil
, which means no encoding is done.
You can also declare the configuration in your config.exs
:
config :rabbitmq_stream, MyApp.MyProducer,
stream_name: "my-stream",
connection: MyApp.MyConnection
Setting up
You can optionally define a before_start/2
callback to perform setup logic, such as creating the stream, if it doesn't yet exists.
defmodule MyApp.MyProducer do
use RabbitMQStream.Producer,
stream_name: "my-stream",
connection: MyApp.MyConnection
@impl true
def before_start(_opts, state) do
# Create the stream
RabbitMQStream.Connection.create_stream(state.connection, state.stream_name)
state
end
end
Configuration
You can configure each Producer with:
config :rabbitmq_stream, MyApp.MyProducer,
stream_name: "my-stream",
connection: MyApp.MyConnection
And also you can override the defaults of all producers with:
config :rabbitmq_stream, :defaults,
producer: [
connection: MyApp.MyConnection,
# ...
]
serializer: Jason
Globally configuring all producers ignores the following options:
:stream_name
:reference_name
Encoding
You can declare a function for encoding each message by declaring a encode!/1
callback as follows:alarm_handler
defmodule MyApp.MyProducer do
use RabbitMQStream.Producer,
stream_name: "my-stream",
connection: MyApp.MyConnection
@impl true
def encode!(message) do
Jason.encode!(message)
end
end
Or by passing a :serializer
option to the use
macro:
defmodule MyApp.MyProducer do
use RabbitMQStream.Producer,
stream_name: "my-stream",
connection: MyApp.MyConnection,
serializer: Jason
end
The default value for the :serializer
is the module itself, unless a default is defined at a higher level of the
configuration. If there is a encode!/1
callback defined, it is always used
Summary
Callbacks
Optional callback that is called after the process has started, but before the
producer has declared itself and fetched its most recent publishing_id
.
Callback responsible for encoding a message into binary format.
Callback responsible for generating the 'filter_value' for a message. The value is used by the Server for filtering the chunks sent to consumer that have defined a 'filter' parameter.
Publishes a single message to the stream.
Types
@type option() :: {:stream_name, String.t()} | {:reference_name, String.t()} | {:connection, GenServer.server()}
@type options() :: [option()]
@type t() :: %RabbitMQStream.Producer{ connection: GenServer.server(), id: String.t() | nil, producer_module: module(), publishing_id: String.t(), reference_name: String.t(), sequence: non_neg_integer() | nil, stream_name: String.t() }
Callbacks
Optional callback that is called after the process has started, but before the
producer has declared itself and fetched its most recent publishing_id
.
This is usefull for setup logic, such as creating the Stream if it doesn't yet exists.
Callback responsible for encoding a message into binary format.
It can be used in many ways, such as to 'Jason.encode!/1' a Map, or to Gzip Compact a message before it is appended to the Stream.
Callback responsible for generating the 'filter_value' for a message. The value is used by the Server for filtering the chunks sent to consumer that have defined a 'filter' parameter.
The callback is invoked before the message is encoded, by the serializer options.
Example defintion:
@impl true
def filter_value(message) do
message["key"]
end
The default implementation defines nil
as the filter_value
for all messages.
@callback publish(message :: term()) :: :ok
Publishes a single message to the stream.
The message first passes through the 'encode!/1' callback, before being sent to the RabbitMQStream.Producer process responsible for sending the binary message to the Connection.
As of RabbitMQ 3.13.x, the mesagge's 'filter_value' is generated by passing it through the 'filter_value/1' callback.
The callback always returns ':ok', as the server only send a response for a publish in case of an error, in which case the error code is logged.