LiveBook-inspired code styling, remove line-number highlighting

Torey Heinz committed Feb 22, 2026
commit d1f3c647acd80ac9eed3552a3119f220eafb027c
Showing 3 changed files with 44 additions and 134 deletions
scratch.md +3 -1
@@ @@ -145,7 +145,9 @@ During my intro I want make sure to give a shout out to my employer Vianet Manag
**3.1 Email Marketing System** (6-8 min)
- The challenge: 500k+ personalized emails
- The challenge: Send 500k+ personalized emails through AWS, and if you exceed your rate limit AWS doesn't let you know, they just drop it.
-
+ - Each email sent generates 3-4 requests
+ - We don't want to take all day to send, it needs to be fast.
+ - we don't want to double send
**3.3 Internal Admin App**
- one of the values here is that instead of building admin tools into the main app, you can keep the main app focused on delivering business value.
slides/03-real-world.html +28 -130
@@ @@ -59,7 +59,7 @@
<h2>The Challenge</h2>
<p>Send <strong>500,000+ personalized marketing emails</strong> through AWS SES.</p>
<div class="callout fragment">
- <p><strong>The catch:</strong> If you exceed your rate limit, AWS doesn't tell you &mdash; they <strong>silently drop your emails</strong>. No error, no bounce, no notification.</p>
+ <p><strong>The catch:</strong> If you exceed your rate limit, AWS doesn't tell you &mdash; they <strong>silently drop your emails</strong>.</p>
</div>
<ul>
<li class="fragment">Rate limiter that <strong>never</strong> exceeds the AWS SES sending rate</li>
@@ @@ -75,29 +75,10 @@
<section>
<h2>The Architecture</h2>
- <div class="arch-diagram">
- Application Supervisor
- ┌──────────┬──────────────┬───────────┐
- │ Phoenix │ EmailRate │ Oban │
- │ Endpoint │ Limiter │ (Job Queue│)
- │ │ (GenServer) │ │
- └──────────┘──────────────┘───────────┘
- ▲ │
- │ ┌────┴────┐
- │ │Scheduler│
- │ │ Worker │
- │ └────┬────┘
- │ │
- │ ┌─────────┴────────┐
- │ │ 2,000 at a time │
- │ └─────────┬────────┘
- │ │
- │ ┌─────────┴────────┐
- └─────│ Mailer Workers │
- │ (one per email) │
- └──────────────────┘</div>
+
<ol style="font-size: 0.65em; margin-top: 15px;">
- <li class="fragment"><strong>Scheduler Worker</strong> queries DB, creates email jobs &mdash; 2,000 at a time</li>
+ <li class="fragment"><strong>Scheduler Worker</strong> queries DB, creates email jobs &mdash; in batches of 2,000</li>
+ <li class="fragment"><strong>Oban</strong> picks up each job and triggers a <strong>Mailer Worker</strong></li>
<li class="fragment"><strong>Mailer Worker</strong> handles one email: validate, personalize, rate-check, send</li>
<li class="fragment"><strong>Rate Limiter</strong> (GenServer) ensures we never exceed the AWS SES limit</li>
</ol>
@@ @@ -111,28 +92,18 @@
<h2>The Supervision Tree</h2>
<p class="muted small">The actual <code>application.ex</code> &mdash; entry point that starts every process</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="4-14|8|11|12">
- defmodule Marketing.Application do
- use Application
-
- def start(_type, _args) do
- children = [
- MarketingWeb.Telemetry,
- Marketing.Repo, # Database connection pool
- Marketing.PuppiesRepo, # Multi-database support
- Marketing.ReputableRoomsRepo,
- Marketing.RoommatesRepo,
- Marketing.NuzzleRepo,
- {Phoenix.PubSub, name: Marketing.PubSub},
- {Finch, name: Marketing.Finch}, # HTTP client
- MarketingWeb.Endpoint, # Web server
- Marketing.EmailRateLimiter, # ← Our rate limiter process
- {Oban, Application.fetch_env!(:marketing, Oban)} # Job queue
- ]
-
- opts = [strategy: :one_for_one, name: Marketing.Supervisor]
- Supervisor.start_link(children, opts)
- end
+ <pre class="small-code"><code class="language-elixir" data-trim>
+ def start(_type, _args) do
+ children = [
+ Marketing.Repo, # Database
+ MarketingWeb.Endpoint, # Web server
+ {Phoenix.PubSub, ...}, # PubSub
+ {Finch, ...}, # HTTP client
+ Marketing.EmailRateLimiter, # ← Rate limiter process
+ {Oban, ...} # ← Job queue
+ ]
+
+ Supervisor.start_link(children, strategy: :one_for_one)
end
</code></pre>
@@ @@ -150,12 +121,12 @@ end
<h2>The Rate Limiter</h2>
<p class="muted small">A GenServer using a token bucket algorithm</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="1-5|8|11-13|15-27">
+ <pre class="small-code"><code class="language-elixir" data-trim>
defmodule Marketing.EmailRateLimiter do
use GenServer
defstruct tokens: 0.0, capacity: 50.0, rate: 25.0,
- daily_remaining: 500_000, last_refill_ms: nil
+ daily_remaining: 750_000, last_refill_ms: nil
# Public API — other code just calls this
def ready?, do: GenServer.call(__MODULE__, :acquire)
@@ @@ -227,7 +198,7 @@ end
<h2>The Mailer Worker</h2>
<p class="muted small">Pattern matching handles every possible failure</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="3-11|12-19">
+ <pre class="small-code"><code class="language-elixir" data-trim>
def perform(%Oban.Job{args: args} = job) do
campaign_id = Map.get(args, "campaign_id")
member_id = Map.get(args, "member_id")
@@ @@ -256,46 +227,11 @@ end
</aside>
</section>
- <section>
- <h2>Reading the <code>else</code> Block</h2>
- <ul class="kv-list">
- <li class="fragment">
- <span class="kv-key">Rate exceeded?</span>
- <span class="kv-val">&rarr; Snooze 1 second, try again</span>
- </li>
- <li class="fragment">
- <span class="kv-key">Daily limit hit?</span>
- <span class="kv-val">&rarr; Snooze with exponential backoff, up to 1 hour</span>
- </li>
- <li class="fragment">
- <span class="kv-key">Already sent?</span>
- <span class="kv-val">&rarr; Discard (don't double-send)</span>
- </li>
- <li class="fragment">
- <span class="kv-key">Invalid email?</span>
- <span class="kv-val">&rarr; Discard (don't retry what won't work)</span>
- </li>
- <li class="fragment">
- <span class="kv-key">AWS rejected?</span>
- <span class="kv-val">&rarr; Discard</span>
- </li>
- <li class="fragment">
- <span class="kv-key">Any other error?</span>
- <span class="kv-val">&rarr; Retry (Oban handles retry logic)</span>
- </li>
- </ul>
- <p class="fragment" style="font-size: 0.8em; margin-top: 0.5em;">Every possible outcome handled. <strong>No silent failures. No lost emails.</strong></p>
-
- <aside class="notes">
- Let's read that else block like a specification. Rate exceeded — snooze 1 second. Daily limit — backoff up to an hour. Already sent — discard, don't double-send. Invalid email — discard, don't retry what won't work. AWS rejected parameters — discard. Anything else — retry with Oban's built-in retry logic. Every outcome is covered.
- </aside>
- </section>
-
<section>
<h2>Scheduling 500k Jobs</h2>
<p class="muted small">Stream records in chunks &mdash; constant memory usage</p>
- <pre><code class="language-elixir" data-trim data-line-numbers="5-8|11-15">
+ <pre><code class="language-elixir" data-trim>
defmodule Marketing.CampaignSchedulerWorker do
use Oban.Worker, queue: :default, max_attempts: 1
@chunk_size 2_000
@@ @@ -361,7 +297,7 @@ end
<h2>The Connection</h2>
<p class="muted small"><code>with</code> chains &mdash; same pattern as the email worker</p>
- <pre><code class="language-elixir" data-trim data-line-numbers="3-6|8-11">
+ <pre><code class="language-elixir" data-trim>
def connect(host, port, username, password, opts \\ []) do
with {:ok, socket_info} <- establish_ssl_connection(host, port, opts, timeout),
{:ok, greeting} <- read_greeting(socket_info, timeout),
@@ @@ -393,7 +329,7 @@ end
<h2>Binary Pattern Matching</h2>
<p class="muted small">Something you <strong>can't easily do</strong> in most languages</p>
- <pre><code class="language-elixir" data-trim data-line-numbers="3-5|7-8">
+ <pre><code class="language-elixir" data-trim>
# Sending: 4-byte length header (big-endian) + XML payload
def send_frame(socket_info, xml_data) do
xml_bytes = :unicode.characters_to_binary(xml_data, :unicode, :utf8)
@@ @@ -427,7 +363,7 @@ end
<h2>Connection Pool</h2>
<p class="muted small">Long-lived TCP sessions managed as supervised processes</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="4-6|8-22">
+ <pre class="small-code"><code class="language-elixir" data-trim>
defmodule OrbitFour.Epp.ConnectionPool do
use GenServer
@@ @@ -470,7 +406,7 @@ end
<h2>Health Checks</h2>
<p class="muted small">Pattern matching handles every possible socket state</p>
- <pre><code class="language-elixir" data-trim data-line-numbers="1-2|4-5|7-12|14-19|21-22">
+ <pre><code class="language-elixir" data-trim>
# No socket — unhealthy
defp connection_healthy?(%Connection{socket: nil}), do: false
@@ @@ -506,44 +442,6 @@ defp connection_healthy?(_conn), do: false
</aside>
</section>
- <section>
- <h2>OrbitFour Supervision Tree</h2>
- <p class="muted small">One supervisor managing everything</p>
-
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="5-14">
- defmodule OrbitFour.Application do
- use Application
-
- def start(_type, _args) do
- children = [
- OrbitFourWeb.Telemetry,
- OrbitFour.Repo, # Database
- {Phoenix.PubSub, name: OrbitFour.PubSub},
- {Finch, name: OrbitFour.Finch}, # HTTP client
- {Oban, ...}, # Job queue
- OrbitFour.Epp.ConnectionPool, # ← TCP connection pool
- OrbitFour.Epp.HealthCache, # ← Periodic health checks
- OrbitFour.Billing.ExchangeRates, # ← Currency rates cache
- OrbitFour.Rdap.Cache, # ← WHOIS data cache
- OrbitFourWeb.Endpoint # Web server
- ]
-
- opts = [strategy: :one_for_one, name: OrbitFour.Supervisor]
- Supervisor.start_link(children, opts)
- end
- end
- </code></pre>
-
- <p class="fragment" style="font-size: 0.7em; color: #555;">
- DB, web server, TCP pool, health monitors, caches, job queue &mdash;<br/>
- all supervised. If the connection pool crashes, the supervisor restarts it.<br/>
- <strong>No pager alerts. No manual restarts.</strong>
- </p>
-
- <aside class="notes">
- Here's OrbitFour's full supervision tree. Database, web server, TCP connection pool, health monitors, exchange rate caches, WHOIS caches, job queue — all in one tree. If the connection pool crashes from a bad TCP state or network blip, the supervisor restarts it. New connections are established automatically. No pager alerts, no manual intervention.
- </aside>
- </section>
<!-- =============================================
SECTION 3.3: Internal Admin
@@ @@ -577,7 +475,7 @@ end
<h2>Multi-Database Architecture</h2>
<p class="muted small">Connects to <strong>five databases</strong> simultaneously</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="5-16">
+ <pre class="small-code"><code class="language-elixir" data-trim>
defmodule VianetAdmin.Application do
use Application
@@ @@ -618,7 +516,7 @@ end
<h2>LiveView: Real-Time Admin Forms</h2>
<p class="muted small">Loading data from three databases asynchronously</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="4-7|8-16">
+ <pre class="small-code"><code class="language-elixir" data-trim>
def mount(params, _session, socket) do
{form, action} =
if Map.has_key?(params, "id") do
@@ @@ -659,7 +557,7 @@ end
<h2>LiveView: Real-Time Presence</h2>
<p class="muted small">Multiple admins viewing the same record can see each other</p>
- <pre><code class="language-elixir" data-trim data-line-numbers="1-5|8-13|15-18">
+ <pre><code class="language-elixir" data-trim>
# Track this admin's presence
Presence.track(self(), "admin:presence", admin.id, %{
initials: Utilities.initials(admin),
@@ @@ -697,7 +595,7 @@ end
<h2>LiveView: Async Charts</h2>
<p class="muted small">Data loads asynchronously, pushes chart updates to the browser</p>
- <pre class="small-code"><code class="language-elixir" data-trim data-line-numbers="5-7|10-17|20-24">
+ <pre class="small-code"><code class="language-elixir" data-trim>
def mount(_params, _session, socket) do
socket =
socket
slides/shared.css +13 -3
@@ @@ -46,19 +46,29 @@
border-radius: 4px;
}
- /* ----- Code ----- */
+ /* ----- Code (LiveBook-inspired dark theme) ----- */
.reveal pre {
width: 90%;
font-size: 0.55em;
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
- border-radius: 8px;
+ background: #1e1e2e;
+ border-radius: 14px;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.25);
+ padding: 0;
+ }
+
+ .reveal pre code {
+ font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
+ background: #1e1e2e;
+ border-radius: 14px;
+ padding: 1em;
}
.reveal code {
font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
}
+
/* ----- Section Dividers ----- */
.reveal .section-divider {