Skip to content

Commit ccb6940

Browse files
recompile articles on change
1 parent 031a020 commit ccb6940

File tree

7 files changed

+83
-10
lines changed

7 files changed

+83
-10
lines changed

config/config.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Config
2+
3+
config :exsync,
4+
addition_dirs: ["/priv"]

lib/boc/application.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ defmodule Boc.Application do
77
def start(_type, _args) do
88
children = [
99
{Bandit, plug: Boc.Router},
10-
{Boc.Articles.DB, []}
10+
{Boc.Articles.DB, []},
11+
{Boc.ArticlesMonitor, []}
1112
]
1213

1314
opts = [strategy: :one_for_one, name: Boc.Supervisor]

lib/boc/articles/db.ex

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@ defmodule Boc.Articles.DB do
22
use Agent
33

44
def start_link(_initial_value) do
5-
Agent.start_link(
6-
fn ->
7-
Boc.Articles.compile_articles()
8-
|> Enum.map(&{&1.key, &1})
9-
|> Map.new()
10-
end,
11-
name: __MODULE__
12-
)
5+
Agent.start_link(&prepare_articles/0, name: __MODULE__)
136
end
147

158
def get_article(key) do
@@ -19,4 +12,14 @@ defmodule Boc.Articles.DB do
1912
def put_article(%{key: key} = article) do
2013
Agent.update(__MODULE__, &Map.put(&1, key, article))
2114
end
15+
16+
def reset() do
17+
Agent.update(__MODULE__, fn _ -> prepare_articles() end)
18+
end
19+
20+
defp prepare_articles() do
21+
Boc.Articles.compile_articles()
22+
|> Enum.map(&{&1.key, &1})
23+
|> Map.new()
24+
end
2225
end

lib/boc/articles_monitor.ex

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
defmodule Boc.ArticlesMonitor do
2+
use GenServer
3+
4+
require Logger
5+
6+
@throttle_timeout_ms 100
7+
8+
defmodule State do
9+
defstruct [:throttle_timer, :file_events, :watcher_pid]
10+
end
11+
12+
def start_link(_opts \\ []) do
13+
GenServer.start_link(__MODULE__, [])
14+
end
15+
16+
@impl GenServer
17+
def init([]) do
18+
{:ok, watcher_pid} =
19+
FileSystem.start_link(dirs: [Boc.articles_path()])
20+
21+
FileSystem.subscribe(watcher_pid)
22+
Logger.debug("Boc articles monitor started.")
23+
{:ok, %State{watcher_pid: watcher_pid}}
24+
end
25+
26+
@impl GenServer
27+
def handle_info({:file_event, watcher_pid, {path, events}}, %{watcher_pid: watcher_pid} = state) do
28+
matching_extension? = Path.extname(path) === ".md"
29+
30+
matching_event? = :modified in events
31+
32+
state =
33+
if matching_extension? && matching_event? do
34+
maybe_recomplete(state)
35+
else
36+
state
37+
end
38+
39+
{:noreply, state}
40+
end
41+
42+
def handle_info({:file_event, watcher_pid, :stop}, %{watcher_pid: watcher_pid} = state) do
43+
Logger.debug("Boc articles monitor stopped.")
44+
{:noreply, state}
45+
end
46+
47+
def handle_info(:throttle_timer_complete, state) do
48+
Boc.Articles.DB.reset()
49+
50+
state = %State{state | throttle_timer: nil}
51+
{:noreply, state}
52+
end
53+
54+
defp maybe_recomplete(%State{throttle_timer: nil} = state) do
55+
throttle_timer = Process.send_after(self(), :throttle_timer_complete, @throttle_timeout_ms)
56+
%State{state | throttle_timer: throttle_timer}
57+
end
58+
59+
defp maybe_recomplete(%State{} = state), do: state
60+
end

mix.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ defmodule Boc.MixProject do
3131
{:plug, "~> 1.18"},
3232
{:bandit, "~> 1.8"},
3333
{:earmark, "~> 1.4"},
34-
{:yaml_elixir, "~> 2.11"}
34+
{:yaml_elixir, "~> 2.11"},
35+
{:exsync, "~> 0.4", only: :dev},
36+
{:file_system, "~> 1.1", only: :dev}
3537
]
3638
end
3739
end

mix.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
%{
22
"bandit": {:hex, :bandit, "1.8.0", "c2e93d7e3c5c794272fa4623124f827c6f24b643acc822be64c826f9447d92fb", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "8458ff4eed20ff2a2ea69d4854883a077c33ea42b51f6811b044ceee0fa15422"},
33
"earmark": {:hex, :earmark, "1.4.48", "5f41e579d85ef812351211842b6e005f6e0cef111216dea7d4b9d58af4608434", [:mix], [], "hexpm", "a461a0ddfdc5432381c876af1c86c411fd78a25790c75023c7a4c035fdc858f9"},
4+
"exsync": {:hex, :exsync, "0.4.1", "0a14fe4bfcb80a509d8a0856be3dd070fffe619b9ba90fec13c58b316c176594", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "cefb22aa805ec97ffc5b75a4e1dc54bcaf781e8b32564bf74abbe5803d1b5178"},
5+
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
46
"hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"},
57
"mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"},
68
"plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"},

priv/articles/dev.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ title: "My dev Tools"
55
- alacritty
66
- starship
77
- zellij
8+
- zsh

0 commit comments

Comments
 (0)