# Lix [![CircleCI](https://circleci.com/gh/rfunix/lix/tree/master.svg?style=svg)](https://circleci.com/gh/rfunix/lix/tree/master)
# Lix is a generic worker handler for SQS messages.
## Installation
1. Add Lix to your dependencies in the `mix.exs` file:
```elixir
def deps do
[
{:lix, git: "https://github.com/rfunix/lix/", tag: "0.2.0"},
]
end
```
2. Run `$ mix deps.get` to update your dependencies.
3. Add `:lix` to your extra applications list:
```elixir
def application do
[extra_applications: [:lix]]
end
```
## Configuration
Lix uses [ex_aws_sqs](https://github.com/ex-aws/ex_aws_sqs) to handle SQS messages and [ex_aws_sns](https://github.com/ex-aws/ex_aws_sns) to publish messages.
For this to work, we need to add a few AWS settings in our file `config.exs`. For example:
```elixir
config :ex_aws, :sqs,
access_key_id: "",
secret_access_key: "",
scheme: "http://",
host: "localhost",
port: 4100,
region: "local-01"
config :ex_aws, :sns,
access_key_id: "",
secret_access_key: "",
scheme: "http://",
host: "localhost",
port: 4100,
region: "local-01"
```
You can also define some Lix specific settings. For example:
```elixir
config :lix,
max_number_of_messages: 10,
visibility_timeout: 0.30,
handler_backoff: 500
```
## Examples
### Basic Worker
```elixir
defmodule Basic.Handler.Example do
use GenServer
@name :handler_example
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: @name)
end
@impl true
def init(args) do
Lix.Handler.Manager.register(%{
handler_example: [queue: "queue/handler_queue", callback: "process_item"]
})
schedule_poller()
{:ok, args}
end
defp schedule_poller() do
send(self(), :poll)
end
@impl true
def handle_info(:poll, state) do
Lix.Handler.run(@name)
schedule_poller()
{:noreply, state}
end
@impl true
def handle_cast({:process_item, messages}, state) do
# Do things
Enum.map(messages, fn message ->
Lix.Handler.confirm_processed_callback(@name, message)
end)
{:noreply, state}
end
end
```
### Basic Worker that publishes SNS messages
```elixir
defmodule Basic.Handler.Example do
use GenServer
@name :handler_example
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: @name)
end
@impl true
def init(args) do
Lix.Handler.Manager.register(%{
handler_example: [queue: "queue/handler_queue", callback: "process_item", topic_arn: "my-topic"]
})
schedule_poller()
{:ok, args}
end
defp schedule_poller() do
send(self(), :poll)
end
@impl true
def handle_info(:poll, state) do
Lix.Handler.run(@name)
schedule_poller()
{:noreply, state}
end
@impl true
def handle_cast({:process_item, messages}, state) do
# Do things
Enum.map(messages, fn message ->
Lix.Handler.confirm_processed_callback(@name, message, "PUBLISH THIS MESSAGE")
end)
{:noreply, state}
end
end
```
### Workers
```elixir
defmodule Example.Handler.Supervisor do
use Supervisor
@number_of_workers 1..5
def start_link(arg) do
Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
end
@impl true
def init(_arg) do
children = Enum.map(@number_of_workers, fn worker_number ->
name = String.to_atom("handler#{worker_number}")
Supervisor.child_spec({Example.Handler, %{name: name, queue: "test_item"}}, id: name)
end)
Supervisor.init(children, strategy: :one_for_one)
end
end
defmodule Example.Handler do
use GenServer
require Logger
def start_link(%{name: name} = args) do
GenServer.start_link(__MODULE__, args, name: name)
end
@impl true
def init(args) do
generate_handler_info(args)
|> Lix.Handler.Manager.register()
schedule_poller()
{:ok, args}
end
defp generate_handler_info(%{name: name, queue: queue}) do
AtomicMap.convert(%{name => [queue: "queue/#{queue}", callback: "process_item"]})
end
defp schedule_poller() do
send(self(), :poll)
end
@impl true
def handle_info(:poll, %{name: name} = state) do
Lix.Handler.run(name)
schedule_poller()
{:noreply, state}
end
@impl true
def handle_cast({:process_item, messages}, %{name: name} = state) do
# Do things
Enum.map(messages, fn message ->
Lix.Handler.confirm_processed_callback(name, message)
end)
{:noreply, state}
end
end
Example.Handler.Supervisor.start_link([])
```
The documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/lix](https://hexdocs.pm/lix).