-
Notifications
You must be signed in to change notification settings - Fork 64
Adds Kaffe.MessageHandler behaviour #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,15 +39,7 @@ An opinionated, highly specific, Elixir wrapper around [Brod](https://github.com | |
| end | ||
| ``` | ||
|
|
||
| 2. Ensure `kaffe` is started with your application: | ||
|
|
||
| ```elixir | ||
| def application do | ||
| [applications: [:logger, :kaffe]] | ||
| end | ||
| ``` | ||
|
|
||
| 3. Configure a Kaffe Consumer and/or Producer | ||
| 2. Configure a Kaffe Consumer and/or Producer | ||
|
|
||
| ## Kaffe Consumer Usage | ||
|
|
||
|
|
@@ -61,14 +53,15 @@ There is also legacy support for single message consumers, which process one mes | |
|
|
||
| ### Kaffe GroupMember - Batch Message Consumer | ||
|
|
||
| 1. Define a `handle_messages/1` function in the provided module. | ||
|
|
||
| `handle_messages/1` This function (note the pluralization) will be called with a *list of messages*, with each message as a map. Each message map will include the topic and partition in addition to the normal Kafka message metadata. | ||
| 1. Define a `handle_messages/1` function in the provided module implementing the `Kaffe.MessageHandler` behaviour. | ||
|
|
||
| The module's `handle_messages/1` function _must_ return `:ok` or Kaffe will throw an error. The Kaffe consumer will block until your `handle_messages/1` function returns `:ok`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be helpful to have this kind of comment somewhere else?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the README is a good place for it, unless we want to make a separate
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the README is a fine place for it. A |
||
| `handle_messages/1` will be called with a *list of messages*, with each message as a map. Each message map will include the topic and partition in addition to the normal Kafka message metadata. | ||
|
|
||
| ```elixir | ||
| defmodule MessageProcessor do | ||
| @behaviour Kaffe.MessageHandler | ||
|
|
||
| @impl Kaffe.MessageHandler | ||
| def handle_messages(messages) do | ||
| for %{key: key, value: value} = message <- messages do | ||
| IO.inspect message | ||
|
|
@@ -154,6 +147,9 @@ Example: | |
|
|
||
| ```elixir | ||
| defmodule MessageProcessor do | ||
| @behaviour Kaffe.MessageHandler | ||
|
|
||
| @impl Kaffe.MessageHandler | ||
| def handle_messages(messages) do | ||
| for %{key: key, value: value} = message <- messages do | ||
| IO.inspect message | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| defmodule Kaffe.MessageHandler do | ||
| @moduledoc """ | ||
| The behaviour for a message handler. | ||
|
|
||
| The module implementing this behaviour needs to be configured for the consumer | ||
| under Kaffe config. | ||
|
|
||
| ``` | ||
| config :kaffe, | ||
| consumers: %{ | ||
| "subscriber_1" => [ | ||
| ... | ||
| message_handler: MyApp.MessageHandler | ||
| ] | ||
| } | ||
| ``` | ||
| """ | ||
| alias Kaffe.Consumer | ||
|
|
||
| @doc """ | ||
| The functionality responsible for handling the message set from Kaffe. | ||
|
|
||
| Each message will include the topic and partition in addition to the normal Kafka | ||
| message metadata. | ||
|
|
||
| The response from the message handler is what dictates how a | ||
| subscriber should deal with the message offset. Depending on the situation, | ||
| a message processor may not want to have its most recent offsets committed. | ||
|
|
||
| In some cases you may not want to commit back the most recent offset after | ||
| processing a list of messages. For example, if you're batching messages to be | ||
| sent elsewhere and want to ensure that a batch can be rebuilt should there be | ||
| an error further downstream. In that example you might want to keep the offset | ||
| of the first message in your batch so your consumer can restart back at that point | ||
| to reprocess and rebatch the messages. | ||
|
|
||
| The following returns are supported: | ||
| - `:ok` - commit back the most recent offset and request more messages | ||
| - `{:ok, :no_commit}` - do _not_ commit back the most recent offset and | ||
| request more messages from the offset of the last message | ||
| - `{:ok, offset}` - commit back at the offset specified and request | ||
| messages from that point forward | ||
|
|
||
| Because the return types are only success based, the message handler needs | ||
| to handle errors. | ||
| """ | ||
| @callback handle_messages(messages :: list(Consumer.message())) :: | ||
| :ok | {:ok, :no_commit} | {:ok, offset :: :brod.offset()} | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a dumb question, but is this no longer needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is super outdated.
Elixir as 1.4 infers which applications to include based on your
deps. See https://elixir-lang.org/blog/2017/01/05/elixir-v1-4-0-released/There's now the
extra_applicationstag, which is only needed when you use something that is not in the deps list (typically things from erlang, like :ssl or :logger).