A durable event-driven workflow engine SDK for Elixir.
Read the documentation and get started in minutes.
Inngest Elixir SDK
Inngest's Elixir SDK allows you to create event-driven, durable workflows in your existing API — without new infrastructure.
It's useful if you want to build reliable software without worrying about queues, events, subscribers, workers, or other complex primitives such as concurrency, parallelism, event batching, or distributed debounce. These are all built in.
The Elixir SDK can be downloaded from Hex. Add it
to your list of dependencies in mix.exs
# mix.exs
def deps do
[
{:inngest, "~> 0.2"}
]
end
This is a basic example of what an Inngest function will look like.
A Module can be turned into an Inngest function easily by using the Inngest.Function
macro.
defmodule MyApp.AwesomeFunction do
use Inngest.Function
@func %FnOpts{id: "awesome-fn", name: "Awesome Function"} # The id and name of the function
@trigger %Trigger{event: "func/awesome"} # The event this function will react to
@impl true
def exec(_ctx, _input) do
IO.inspect("Do something")
{:ok, "hello world"}
end
end
And just like that, you have an Inngest function that will react to an event called func/awesome
.
Inngest.Function.exec/2
will then be called by the SDK to run and execute the logic.
The above example will be no different from other background processing libraries, so let's take a look at a more complicated version. Which should provide you an idea what is capable with Inngest.
defmodule MyApp.AwesomeFunction do
use Inngest.Function
@func %FnOpts{id: "awesome-fn", name: "Awesome Function"} # The id and name of the function
@trigger %Trigger{event: "func/awesome"} # The event this function will react to
@impl true
def exec(ctx, %{step: step} = input) do
IO.inspect("Starting function...")
%{greet: greet} =
# A return value wrapped in a `step` are memorized, meaning
# it's guaranteed to be idempotent.
# if it fails, it'll be retried.
step.run(ctx, "step1", fn ->
%{greet: "hello"}
end)
# Sleeping will pause the execution from running, and function
# will be reinvoked when time is up.
step.sleep(ctx, "wait-a-little", "10s")
%{name: name} =
step.run(ctx, "retrieve-user", fn ->
# retrieve user from here
%{name: user_name}
end)
# There are times you want to wait for something to happen before
# continue on the workflow. `wait_for_event` allows exactly that.
evt = step.wait_for_event("wait-for-registration-complete", %{
event: "user/register.completed",
timeout: "1h"
})
# You might want to trigger some other workflow, sending an event
# will trigger the functions that are registered against the `event`.
step.send_event("completed-work", %{
name: "func/awesome.completed",
data: %{name: name}
})
{:ok, %{greetings: "#{greet} #{name}", registered: is_nil(evt)}}
end
end
See the guides for more details regarding use cases and how each macros can be used.