horoscopes_r_us
A tiny demo for using Journey to power an application that computes horoscopes
Wire Journey
in as a dependency:
Mix.install([
{:journey, "~> 0.0.3"}
])
Define the process for your the Horoscopes application
defmodule Example.Process do
@doc """
Defines the steps in your application's process.
"""
def process() do
%Journey.Process{
name: "horoscopes-r-us",
version: "0.0.1",
steps: [
%Journey.Step{name: :first_name},
%Journey.Step{name: :birth_month},
%Journey.Step{name: :birth_day},
%Journey.Step{
name: :astrological_sign,
# This step defers to a function for computing the astrological sign (defined elsewhere).
func: &Example.Process.compute_sign/1,
# The execution of this task is dependenit on birth month and day being provided.
blocked_by: [
birth_month: :provided,
birth_day: :provided
]
},
%Journey.Step{
name: :horoscope,
# This step defers to a function for computing the horoscope.
func: &Example.Process.compute_horoscope/1,
# The execution of this task is dependenit on first name being and astrological_sign being available.
blocked_by: [
first_name: :provided,
astrological_sign: :provided
]
}
]
}
end
@doc """
Computes astrological sign.
"""
def compute_sign(values) do
# For demo purposes, pretend that this is a slow, expensive task. ; )
:timer.sleep(1000)
month = values[:birth_month].value
day = values[:birth_day].value
birthday = epoch(month, day)
sign =
cond do
birthday < epoch(1, 20) -> :capricorn
birthday < epoch(2, 19) -> :aquarius
birthday < epoch(3, 20) -> :pisces
birthday < epoch(4, 20) -> :aries
birthday < epoch(5, 20) -> :taurus
birthday < epoch(6, 21) -> :gemini
birthday < epoch(7, 21) -> :cancer
birthday < epoch(8, 23) -> :leo
birthday < epoch(9, 23) -> :virgo
birthday < epoch(10, 23) -> :libra
birthday < epoch(11, 23) -> :scorpio
birthday < epoch(12, 22) -> :saggitarius
true -> :capricorn
end
{:ok, sign}
end
@doc """
Computes horoscope.
"""
def compute_horoscope(values) do
# For demo purposes, pretend that this is a slow, expensive task. ; )
:timer.sleep(1500)
{
:ok,
"#{values[:first_name].value}! You are a righteous #{Atom.to_string(values[:astrological_sign].value)}! Now is the perfect time to smash the racist patriarchy."
}
end
defp epoch(month, day) do
DateTime.new!(%Date{year: 2000, month: month, day: day}, Time.new!(0, 0, 0))
|> DateTime.to_unix()
end
end
Load the process we have defined above
process = Example.Process.process()
A customer arrived, and wants a horscope! Kick off an execution of the process defined above:
execution = Journey.Process.execute(process)
Look at the state of the execution. Note the steps you defined in theplan, none computed:
execution |> Journey.Execution.get_summary() |> IO.puts()
The customer provided their birth date. Record their answer:
{:ok, execution} = Journey.Execution.update_value(execution.execution_id, :birth_day, 29)
Note that changes in the execution.
birth_day
in the execution has the data, and astrological_sign
is now only waiting for birth_month
:
execution |> Journey.Execution.get_summary() |> IO.puts()
The customer provided their birth_month
. Record this data.
{:ok, execution} = Journey.Execution.update_value(execution.execution_id, :birth_month, 4)
:timer.sleep(2000)
Note the execution has been updated with birth_month
, and astrological_sign
has been computed. horoscope
is now only waiting forfirst_name
:
execution = Journey.Execution.load!(execution.execution_id)
execution |> Journey.Execution.get_summary() |> IO.puts()
The customer provide first_name
, the only remaining piece required for computing horoscope
. Record this last piece of data.
{:ok, execution} =
Journey.Execution.update_value(execution.execution_id, :first_name, "Pickles The Cat")
:timer.sleep(2000)
Note that the execution has been updated with first_name
, and horoscope
computed:
execution = Journey.Execution.load!(execution.execution_id)
execution |> Journey.Execution.get_summary() |> IO.puts()
The customer has their horscope!
{:computed, result} = execution |> Journey.Execution.read_value(:horoscope)
result