This file contains 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 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 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 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 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 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 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 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 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" |
This file contains 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
## You can use this set or rules to parse Elixir logs in DataDog Logger | |
# 16:01:37.511 request_id=2khj5fsrc3lpk86dh8000g5h [debug] Processing with TwilioProxy.RequestController.create | |
router %{date("HH:mm:ss.SSS"):date} (%{data::keyvalue("=", " ")} )?\[+%{word:level}\] Processing (with|by) +%{data:controller.callback} | |
# 16:04:07.995 request_id=u8m11nptsmsjc282k3l1133u6evmljer [info] Sent 200 in 16ms | |
# 16:04:07.995 request_id=u8m11nptsmsjc282k3l1133u6evmljer [info] Sent 200 in 16µs | |
# 00:05:30.048 request_id=sXax4ynq8i+zU90Emg84 [info] Sent 400 in 1ms |