Skip to content

Instantly share code, notes, and snippets.

View AndrewDryga's full-sized avatar

Andrew Dryga AndrewDryga

View GitHub Profile
#!/usr/bin/env bash
set -xe
# Create a release tarball
mix release --verbose
# Find tarball location
APP_NAME="myapp"
APP_TARBALL=$(find _build/${MIX_ENV}/rel/${APP_NAME}/releases -maxdepth 2 -name ${APP_NAME}.tar.gz)
{
"name": "myappapi",
"description": "MyApp Backend Application",
"scripts": {
"postdeploy": "/app/bin/myapp seed"
},
"env": {
"MY_ENV_VARIABLE": {
"required": true
}
FROM nebo15/alpine-elixir:1.5.1 as builder
MAINTAINER Nebo#15 [email protected]
# Always build with production environment
ENV MIX_ENV=prod
# `/opt` is a common place for third-party provided packages that are not part of the OS itself
WORKDIR /opt/app
# Required in elixir_make
@AndrewDryga
AndrewDryga / mix_test_watch.sh
Last active November 4, 2020 17:27
Watch for file changes and run tests for stale modules
#!/bin/bash
command -v fswatch >/dev/null 2>&1 || { echo >&2 "fswatch is not installed. To install it use 'brew install fswatch'. Aborting."; exit 1; }
command -v mix >/dev/null 2>&1 || { echo >&2 "mix is not installed. Aborting."; exit 1; }
PROJECT_PATH=$(git rev-parse --show-toplevel)
[[ "$?" != "0" ]] && echo "Stale test watch works only within git project." && exit 1;
declare -a IGNORED_PATHS
declare -i throttle_by=2
@AndrewDryga
AndrewDryga / application.ex
Last active February 20, 2018 22:58
Adding runtime config via Application.put_env/2 in Application start/2 callback
defmodule Sample.Application do
use Application
# ...
def start(_type, _args) do
import Supervisor.Spec
# ...
# Update application environment from system environment variable when application starts
Application.put_env(:sample_app, :configurable_env_var, System.get_env("CONFIGURABLE_ENV_VAR"))
defmodule SageExample do
import Sage
require Logger
# It is better to build Saga struct in a module attribute,
# we don't need to spend resources each time we want to execute it
@create_and_subscribe_user_sage
new()
|> run(:user, &create_user/2)
|> run(:plans, &fetch_subscription_plans/2)
@AndrewDryga
AndrewDryga / rules.txt
Created April 9, 2018 13:45
Grok parser for Elixir logs
## 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
@AndrewDryga
AndrewDryga / xref.ex
Created May 7, 2018 14:38
Find unused code
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"
@AndrewDryga
AndrewDryga / compensation_with_retry.ex
Last active May 28, 2018 15:51
Sage: Stage with Retry in Compensation
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
@AndrewDryga
AndrewDryga / callbacks.ex
Last active June 4, 2018 12:36
Sage: Callbacks
@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},