Created
May 13, 2018 16:37
-
-
Save AndrewDryga/88caac1a4d422e6c42fa0cf3b36fb931 to your computer and use it in GitHub Desktop.
Sage: Booking example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BookingApp.Billing do | |
def authorize_card(%{exchange_rate: exchange_rate}, %{"card_token" => card_token, "total" => total}) do | |
{:ok, authorization} = authorize(card_token, total * exchange_rate) | |
end | |
def cancel_card_authorization(_effect_to_compensate, effects_to_compensate, _name_and_reason, %{"card_token" => card_token}) do | |
with {:ok, authorization} <- Map.fetch(effects_to_compensate, :authorization) || fetch_authorization_for_card(card_token) do | |
:ok = cancel_authorization(authorization) | |
end | |
end | |
def charge_authorization(%{authorization: authorization}, _attrs) do | |
# ... | |
end | |
def refund_payment(_effect_to_compensate, effects_to_compensate, _name_and_reason, %{"card_token" => card_token}) do | |
# ... | |
end | |
defp authorize(_card_token, _total_eur), raise "Not Implemented" | |
defp cancel_authorization(_authorization), raise "Not Implemented" | |
defp fetch_authorization_for_card(_card_token), raise "Not Implemented" | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BookingApp.Cache do | |
# Not implemented | |
def persist(table, key, value), do: :ok | |
def fetch(table, key, value), do: {:ok, 1} | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BookingApp.CurrencyExchange do | |
def fetch_currency_exchange_rates(_effects_so_far, %{"base_currency" => base_currency}) do | |
with {:ok, exchange_rates} <- fetch_eur_exchange_rates_to(base_currency, ttl: 30_000) do | |
BookingApp.Cache.persist(:eur_exchange_rates, base_currency, exchange_rates) | |
{:ok, exchange_rates} | |
end | |
end | |
def currency_exchange_rates_circuit_breaker(_effect_to_compensate, _effects_so_far, name_and_reason, %{"base_currency" => base_currency}) do | |
# When error occured on current stage and there is a cache for exchange rates, | |
# it's safe to proceed with this cached value | |
with {:currency_exchange_rates, _reason} <- name_and_reason, | |
{:ok, exchange_rates} <- BookingApp.Cache.fetch(:eur_exchange_rates, base_currency) do | |
{:continue, exchange_rates} | |
else | |
_ -> :ok | |
end | |
end | |
defp fetch_eur_exchange_rates_to(_base_currency), do: 1 | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule BookingApp.Sage do | |
import Sage | |
alias BookingApp.{Billing, Hotels, Cars, Flights, Repo} | |
@spec create_and_subscribe_user(attrs :: map()) :: | |
{:ok, last_effect :: any(), all_effects :: map()} | {:error, reason :: any()} | |
def create_booking(attrs) do | |
new() | |
|> run(:currency_exchange_rates, &fetch_currency_exchange_rates/2, ¤cy_exchange_rates_circuit_breaker/4) | |
|> run(:authorize_card, &Billing.authorize_card/2, &Billing.cancel_card_authorization/4) | |
|> run_async(:book_hotel, &Hotels.book/2, &Hotels.cancel_booking/4) | |
|> run_async(:book_car, &Cars.book/2, &Cars.cancel_booking/4) | |
|> run_async(:book_flight, &Flights.book/2, &Flights.cancel_booking/4) | |
|> run(:email_confirmation, &send_email_confirmation/2) | |
|> run(:charge_card, &Billing.charge_card/2, &Billing.refund_payment/4) | |
|> transaction(Repo, attrs) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment