View on_conflict.ex
defmodule Upa.VideoWatchProgress do
def save(attrs) do
struct(Upa.VideoWatchProgress, attrs)
|> changeset
|> Upa.Repo.insert(on_conflict: insert_conflict_strategy(attrs))
|> case do
{:error, _} = error -> raise Upa.DatabaseCommandError
{:ok, changeset} -> :ok
end
end
View event_consumer.ex
defmodule UpaEventSourcing.VideoWatchProgress.EventAggregator do
def start_link(event) do
Task.start_link(fn ->
Upa.VideoWatchProgress.save(event) #Saves to the database
end)
end
end
defmodule UpaEventSourcing.VideoWatchProgress.EventConsumer do
use ConsumerSupervisor
View application.ex
children = [
worker(UpaEventSourcing.VideoWatchProgress.EventStore, []),
worker(UpaEventSourcing.VideoWatchProgress.EventConsumer, [
%{producer: UpaEventSourcing.VideoWatchProgress.EventStore,
processor: UpaEventSourcing.VideoWatchProgress.EventAggregator}
])
]
View config.exs
config :upa, video_watch_progress_min_demand: 1
config :upa, video_watch_progress_max_demand: 192
config :upa, Upa.Repo,
adapter: Ecto.Adapters.MySQL,
hostname: "host.example.com",
database: "our_database",
username: "${MYSQL_USR}",
password: "${MYSQL_PWD}",
pool_size: 48
View event_store.ex
defmodule UpaEventSourcing.VideoWatchProgress.EventStore do
use GenStage
@event_processing_timeout 11 #Max seconds to process a track video watch progress event
def start_link() do
View video_watch_progress_controller.ex
#Phoenix Action
def track_time(conn, params) do
RequestParamsHandler.prepare(conn, params)
|> EventStore.enqueue #Send to GenStage pipeline
send_resp(conn, 201, "")
end
View upa_event_sourcing_application.ex
#Supervision Tree definition for Events
children = [
worker(UpaEventSourcing.VideoWatchProgress.EventStore, []),
worker(UpaEventSourcing.VideoWatchProgress.EventConsumer, [
%{producer: UpaEventSourcing.VideoWatchProgress.EventStore,
processor: UpaEventSourcing.VideoWatchProgress.EventAggregator}
])
]
View elixirconf-2017-recap.md

Elixir Native UI - Boyd Multerer https://www.youtube.com/watch?v=77FW-jrCyCs

Thinking In Ecto - Darin Wilson https://www.youtube.com/watch?v=YQxopjai0CU

  1. Repository pattern https://youtu.be/YQxopjai0CU?t=2m12s
  2. Explicitness https://youtu.be/YQxopjai0CU?t=5m29s
View HOWTO.md

Instructions

CloudFlare is an awesome reverse cache proxy and CDN that provides DNS, free HTTPS (TLS) support, best-in-class performance settings (gzip, SDCH, HTTP/2, sane Cache-Control and E-Tag headers, etc.), minification, etc.

  1. Make sure you have registered a domain name.
  2. Sign up for CloudFlare and create an account for your domain.
  3. In your domain registrar's admin panel, point the nameservers to CloudFlare's (refer to this awesome list of links for instructions for various registrars).
  4. From the CloudFlare settings for that domain, enable HTTPS/SSL and set up a Page Rule to force HTTPS redirects. (If you want to get fancy, you can also enable automatic minification for text-based assets [HTML/CSS/JS/SVG/etc.], which is a pretty cool feature if you don't want already have a build step for minification.)
  5. If you
View up-and-running-with-edeliver-on-do.md

Build Server

  • Go to Digital Ocean
  • Create new droplet
  • London
  • Ubuntu
  • No apps
  • Add SSH keys