Reconnecting...
Reconnecting...
# Resilient, Scalable Applications, Built Simply
Journey lets you define your business logic as a computation graph. It runs executions of your graph, with built-in persistence, fault tolerance, and horizontal scalability.
An Elixir package, Journey simply scales with your Elixir application. No additional infrastructure to deploy, no additional cloud service runtime dependencies to take on.
# Examples
Here are a couple of examples of building applications with Journey: a basic two-node Useless Machine, and a more functionality-rich Credit Card Application Service.
Note: this example is included in
Journey's codebase
(opens in a new window)
.
A
useless machine
(opens in a new window)
is a device whose only function is to turn itself off.
Here is a Journey graph implementing a useless machine with two nodes (:switch and :paw). The definition of :paw
includes a function (&lol_no/1) that defines what
:paw
does when :switch
changes:
Below is an example of using this useless machine.
The code creates an "execution" of the graph, and then flips its :switch
to "on", and watches the :paw
node wake up and flip the :switch
back to "off" (some of IEX output omitted for brevity):
We could keep flipping the switch on, and then watching paw turn it off until the end of time, or until the server crashes.
As long as you took a note of the ID of the execution, you can always load the execution when the application is back up, and continue where you left off, as if nothing happened.
Journey gives your application resiliency.
The Credit Card Application service is a more complex application, which includes multiple nodes holding data provided by the customer (name, ssn#), or computed by the graph itself (e.g. credit score) when the node's upstream data becomes available, or actions scheduled for later (e.g. sending a reminder to a pre-approved customer if they didn't request a credit card within a week), etc.
The essence of the application boils down to
1. the rules of the business captured in its Journey graph, and
2. the functions that perform various actions in self-computing nodes (e.g.
send_preapproval_reminder()
function, which sends the customer a reminder email).
This example (the journey graph, placeholder business logic, doctests) can be found in
Journey's codebase
(opens in a new window)
.
## Useless Machine
defmodule UselessMachine do
import Journey.Node
def graph() do
Journey.new_graph(
"useless machine example graph",
"v1.0.0",
[
input(:switch),
mutate(:paw, [:switch], &lol_no/1, mutates: :switch)
]
)
end
def lol_no(%{switch: switch}) do
IO.puts("paw says: '#{switch}? lol no'")
{:ok, "off"}
end
end
~/src/new_journey $ iex -S mix
iex(1)> graph = UselessMachine.graph()
iex(2)> execution = Journey.start_execution(graph)
iex(3)> Journey.get_value(execution, :switch)
{:error, :not_set}
iex(4)> Journey.get_value(execution, :paw)
{:error, :not_set}
iex(5)> Journey.set(execution, :switch, "on")
paw says: 'on? lol no'
iex(6)> Journey.get_value(execution, :paw)
{:ok, "updated :switch (at 1752361554)"}
iex(7)> Journey.get_value(execution, :switch)
{:ok, "off"}
iex(8)> Journey.set(execution, :switch, "on")
paw says: 'on? lol no'
iex(9)> Journey.get_value(execution, :paw)
{:ok, "updated :switch (at 1752361589)"}
iex(10)> Journey.get_value(execution, :switch)
{:ok, "off"}
iex(11)> execution.id
"EXECLA7DTA19GX626M866MR3"
~/src/new_journey $ iex -S mix
iex(1)> _graph = UselessMachine.graph()
iex(2)> execution = Journey.load("EXECLA7DTA19GX626M866MR3")
iex(3)> Journey.set(execution, :switch, "on")
paw says: 'on? lol no'
iex(4)> Journey.get_value(execution, :paw)
{:ok, "updated :switch (at 1752435125)"}
## Credit Card Application Service