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
def book_trip(attrs) do | |
with {:ok, exchange_rates} <- BillingAPI.fetch_currency_exchange_rates(attrs), | |
{:ok, card_authorization} <- BillingAPI.authorize_card(exchange_rates, attrs), | |
{:ok, hotel_booking} <- HotelBookingAPI.book_hotel(attrs), | |
:ok <- Mailer.send_email_confirmation(card_authorization, hotel_booking, attrs), | |
{:ok, charge} <- BillingAPI.charge_card(card_authorization) do | |
{:ok, %{charge: charge, bookings: [hotel_booking]}} | |
end | |
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.Booker do | |
alias BookingApp.{Billing, Users, Hotels, Cars, Flights, Repo} | |
def create_booking(attrs) do | |
Sage.new() | |
|> Billing.authorize_card(attrs) | |
|> Hotels.maybe_book_hotel(attrs) | |
|> Cars.maybe_book_car(attrs) | |
|> Flights.maybe_book_flight(attrs) | |
|> Users.sign_up() |
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 MyApp.Domain.User.SignUp do | |
def create_and_subscribe_user(attrs) do | |
Repo.transaction(fn -> | |
with {:ok, user} <- create_user(attrs), | |
{:ok, plans} <- fetch_subscription_plans(attrs), | |
{:ok, charge} <- charge_card(user, subscription), | |
{:ok, subscription} <- create_subscription(user, plan, attrs), | |
{:ok, _delivery} <- schedule_delivery(user, subscription, attrs), | |
{:ok, _receipt} <- send_email_receipt(user, subscription, attrs), | |
{:ok, user} <- update_user(user, %{subscription: subscription}) do |
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 MyApp.Domain.User.SignUp do | |
def create_and_subscribe_user(attrs) do | |
Repo.transaction(fn -> | |
with {:ok, user} <- create_user(attrs), | |
{:ok, plans} <- fetch_subscription_plans(attrs), | |
{:ok, charge} <- charge_card(user, subscription), | |
{:ok, subscription} <- create_subscription(user, plan, attrs), | |
{:ok, _delivery} <- schedule_delivery(user, subscription, attrs), | |
{:ok, _receipt} <- send_email_receipt(user, subscription, attrs), | |
{:ok, user} <- update_user(user, %{subscription: subscription}) do |
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 | |
@spec book_trip(attrs :: map()) :: {:ok, last_effect :: any(), all_effects :: map()} | {:error, reason :: any()} | |
def book_trip(attrs) do | |
new() | |
|> run(:exchange_rate, &Billing.fetch_currency_exchange_rates/2, &Billing.currency_exchange_rates_circuit_breaker/4) | |
|> run(:authorization, &Billing.authorize_card/2, &Billing.cancel_card_authorization/4) | |
|> run_async(:book_hotel, &HotelsBooking.book/2, &HotelsBooking.cancel_booking/4) | |
|> run_async(:book_car, &CarsBooking.book/2, &CarsBooking.cancel_booking/4) |
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
def currency_exchange_rates_circuit_breaker(_effect_to_compensate, _effects_so_far, %{"base_currency" => base_currency}) do | |
with {:ok, exchange_rates} <- BookingApp.Cache.fetch(:eur_exchange_rates, base_currency) do | |
{:continue, exchange_rates} | |
else | |
_ -> :ok | |
end | |
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.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 |
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
@callback transaction(attrs :: map()) :: | |
{:ok, last_effect :: any(), all_effects :: map()} | {:error, reason :: any()} | |
@callback compensation(effect_to_compensate :: any(), effects_so_far :: map(), attrs :: any()) :: | |
:ok | |
| :abort | |
| {:retry, | |
[ | |
{:retry_limit, pos_integer()}, | |
{:base_backoff, pos_integer() | nil}, |
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
def delete_subscription(_effect_to_compensate, %{user: user}, _name_and_reason, _attrs) do | |
:ok = SageExample.Billing.APIClient.delete_all_subscriptions_for_user(user) | |
# We want to apply forward recovery from :subscription stage for 5 times | |
{:retry, retry_limit: 5, base_backoff: 10, max_backoff: 30_000, enable_jitter: true} | |
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 Mix.Tasks.Xref2 do | |
use Mix.Task | |
import Mix.Compilers.Elixir, | |
only: [read_manifest: 2, source: 0, source: 1, source: 2, module: 1] | |
@shortdoc "Performs cross reference checks" | |
@recursive true | |
@manifest "compile.elixir" |