See demo
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 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 |
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 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 |
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
children = [ | |
worker(UpaEventSourcing.VideoWatchProgress.EventStore, []), | |
worker(UpaEventSourcing.VideoWatchProgress.EventConsumer, [ | |
%{producer: UpaEventSourcing.VideoWatchProgress.EventStore, | |
processor: UpaEventSourcing.VideoWatchProgress.EventAggregator} | |
]) | |
] |
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
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 |
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 UpaEventSourcing.VideoWatchProgress.EventStore do | |
use GenStage | |
@event_processing_timeout 11 #Max seconds to process a track video watch progress event | |
def start_link() 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
#Phoenix Action | |
def track_time(conn, params) do | |
RequestParamsHandler.prepare(conn, params) | |
|> EventStore.enqueue #Send to GenStage pipeline | |
send_resp(conn, 201, "") | |
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
#Supervision Tree definition for Events | |
children = [ | |
worker(UpaEventSourcing.VideoWatchProgress.EventStore, []), | |
worker(UpaEventSourcing.VideoWatchProgress.EventConsumer, [ | |
%{producer: UpaEventSourcing.VideoWatchProgress.EventStore, | |
processor: UpaEventSourcing.VideoWatchProgress.EventAggregator} | |
]) | |
] |
Elixir Native UI - Boyd Multerer https://www.youtube.com/watch?v=77FW-jrCyCs
- Only dependencies are Elixir, Erlang, and glut to access OpenGL.
- No UI threads! Individual processes can be used to track mouse
- Slides track mouse as long as button is down https://youtu.be/77FW-jrCyCs?t=37m35s
- Sliders can be rotated https://youtu.be/77FW-jrCyCs?t=40m4s
- 500 lines animating still a few ms to render https://youtu.be/77FW-jrCyCs?t=43m34s
Thinking In Ecto - Darin Wilson https://www.youtube.com/watch?v=YQxopjai0CU
- Repository pattern https://youtu.be/YQxopjai0CU?t=2m12s
- Explicitness https://youtu.be/YQxopjai0CU?t=5m29s
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.
- Make sure you have registered a domain name.
- Sign up for CloudFlare and create an account for your domain.
- 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).
- 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.)
- If you