Skip to content

Commit

Permalink
feat: switch from cowboy to bandit
Browse files Browse the repository at this point in the history
  • Loading branch information
mhanberg committed Oct 21, 2023
1 parent 39f4078 commit 36cccc9
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 86 deletions.
23 changes: 19 additions & 4 deletions lib/tableau/components.ex
Expand Up @@ -15,39 +15,54 @@ defmodule Tableau.Components do
:def,
:live_reload,
~g'''
<script defer>
<% {:ok, config} = Tableau.Config.new(Application.get_env(:tableau, :config, %{}) |> Map.new()) %>
<script>
function log(message) {
if (<%= inspect(config.reload_log) %>) {
console.log(`[tableau] ${message}`)
}
}
function connect() {
try {
window.socket = new WebSocket('ws://' + location.host + '/ws');
window.socket.onmessage = function(e) {
if (e.data === "reload") {
log("reloading!");
location.reload();
} else if (e.data === "subscribed") {
log("connected and subscribed!");
}
}
window.socket.onopen = () => {
waitForConnection(() => window.socket.send("subscribe"), 300);
waitForConnection(() => {
log("sending 'subscribe' message");
window.socket.send("subscribe")
}
, 300);
};
window.socket.onclose = () => {
setTimeout(() => connect(), 500);
};
function waitForConnection(callback, interval) {
console.log("Waiting for connection!")
log("waiting for connection!")
if (window.socket.readyState === 1) {
callback();
} else {
console.log("setting a timeout")
log("setting a timeout")
setTimeout(() => waitForConnection(callback, interval), interval);
}
}
} catch (e) {
log(e);
setTimeout(() => connect(), 500);
}
}
log("about to connect");
connect();
</script>
'''html,
Expand Down
3 changes: 2 additions & 1 deletion lib/tableau/config.ex
Expand Up @@ -9,7 +9,7 @@ defmodule Tableau.Config do

import Schematic

defstruct [:url, include_dir: "extra", timezone: "Etc/UTC"]
defstruct [:url, include_dir: "extra", timezone: "Etc/UTC", reload_log: false]

def new(config) do
unify(schematic(), config)
Expand All @@ -21,6 +21,7 @@ defmodule Tableau.Config do
%{
optional(:include_dir) => str(),
optional(:timezone) => str(),
optional(:reload_log) => bool(),
url: str()
},
convert: false
Expand Down
92 changes: 50 additions & 42 deletions lib/tableau/extensions/post_extension.ex
Expand Up @@ -76,6 +76,7 @@ defmodule Tableau.PostExtension do
---
```
"""

{:ok, config} =
Tableau.PostExtension.Config.new(
Map.new(Application.compile_env(:tableau, Tableau.PostExtension, %{}))
Expand All @@ -86,50 +87,57 @@ defmodule Tableau.PostExtension do
use Tableau.Extension, key: :posts, type: :pre_build, priority: 100

def run(token) do
Module.create(
Tableau.PostExtension.Posts,
quote do
use NimblePublisher,
build: __MODULE__.Post,
from: "#{unquote(@config.dir)}/*.md",
as: :posts,
highlighters: [:makeup_elixir],
parser: Tableau.PostExtension.Posts.Post

def posts(_opts \\ []) do
@posts
|> Enum.sort_by(& &1.date, {:desc, DateTime})
|> then(fn posts ->
if unquote(@config.future) do
posts
else
Enum.reject(posts, &(DateTime.compare(&1.date, DateTime.utc_now()) == :gt))
:global.trans(
{:create_posts_module, make_ref()},
fn ->
Module.create(
Tableau.PostExtension.Posts,
quote do
use NimblePublisher,
build: __MODULE__.Post,
from: "#{unquote(@config.dir)}/*.md",
as: :posts,
highlighters: [:makeup_elixir],
parser: Tableau.PostExtension.Posts.Post

def posts(_opts \\ []) do
@posts
|> Enum.sort_by(& &1.date, {:desc, DateTime})
|> then(fn posts ->
if unquote(@config.future) do
posts
else
Enum.reject(posts, &(DateTime.compare(&1.date, DateTime.utc_now()) == :gt))
end
end)
end
end)
end
end,
Macro.Env.location(__ENV__)
)

posts =
for post <- apply(Tableau.PostExtension.Posts, :posts, []) do
{:module, _module, _binary, _term} =
Module.create(
Module.concat([post.id]),
quote do
@external_resource unquote(post.file)
use Tableau.Page, unquote(Macro.escape(Keyword.new(post)))

def template(_assigns) do
unquote(post.body)
end
end,
Macro.Env.location(__ENV__)
)

post
end

{:ok, Map.put(token, :posts, posts)}
end,
Macro.Env.location(__ENV__)
[Node.self()],
:infinity
)

posts =
for post <- apply(Tableau.PostExtension.Posts, :posts, []) do
{:module, _module, _binary, _term} =
Module.create(
Module.concat([post.id]),
quote do
@external_resource unquote(post.file)
use Tableau.Page, unquote(Macro.escape(Keyword.new(post)))

def template(_assigns) do
unquote(post.body)
end
end,
Macro.Env.location(__ENV__)
)

post
end

{:ok, Map.put(token, :posts, posts)}
end
end
7 changes: 7 additions & 0 deletions lib/tableau/router.ex
Expand Up @@ -18,8 +18,15 @@ defmodule Tableau.Router do
plug :match
plug :dispatch

get "/ws/index.html" do
conn
|> WebSockAdapter.upgrade(Tableau.Websocket, [], timeout: 60_000)
|> halt()
end

match _ do
Logger.error("File not found: #{conn.request_path}")
dbg conn

Check failure on line 29 in lib/tableau/router.ex

View workflow job for this annotation

GitHub Actions / Test (1.13.x/23.x)

** (CompileError) lib/tableau/router.ex:29: undefined function dbg/1 (expected Tableau.Router to define such a function or for it to be imported, but none are available)

Check failure on line 29 in lib/tableau/router.ex

View workflow job for this annotation

GitHub Actions / Test (1.13.x/24.x)

** (CompileError) lib/tableau/router.ex:29: undefined function dbg/1 (expected Tableau.Router to define such a function or for it to be imported, but none are available)

Check failure on line 29 in lib/tableau/router.ex

View workflow job for this annotation

GitHub Actions / Test (1.13.x/25.x)

** (CompileError) lib/tableau/router.ex:29: undefined function dbg/1 (expected Tableau.Router to define such a function or for it to be imported, but none are available)

send_resp(conn, 404, @not_found)
end
Expand Down
13 changes: 1 addition & 12 deletions lib/tableau/server.ex
Expand Up @@ -2,19 +2,8 @@ defmodule Tableau.Server do
@moduledoc false
def child_spec(_) do
Supervisor.child_spec(
{Plug.Cowboy,
scheme: :http, plug: Tableau.Router, options: [dispatch: dispatch(), port: 4999]},
{Bandit, scheme: :http, plug: Tableau.Router, port: 4999},
[]
)
end

defp dispatch() do
[
{:_,
[
{"/ws", Tableau.Websocket, []},
{:_, Plug.Cowboy.Handler, {Tableau.Router, []}}
]}
]
end
end
26 changes: 8 additions & 18 deletions lib/tableau/websocket.ex
@@ -1,39 +1,29 @@
defmodule Tableau.Websocket do
@moduledoc false
@behaviour :cowboy_websocket
@reloader_opts Application.compile_env(:tableau, :reloader, patterns: [])

require Logger

def init(request, state) do
{:cowboy_websocket, request, state}
end

def websocket_init(state) do
def init(_args) do
:ok = Tableau.LiveReload.init(name: :tableau_file_watcher)

{:ok, state}
end

def websocket_handle({:text, _text}, state) do
{:reply, {:text, "pong"}, state}
{:ok, []}
end

def websocket_handle({:ping, _text}, state) do
{:reply, {:pong, "PONG"}, state}
def handle_in({"subscribe", [opcode: :text]}, state) do
{:push, {:text, "subscribed"}, state}
end

def websocket_info({:reload, _asset_type}, state) do
{:reply, {:text, "reload"}, state}
def handle_info({:reload, _asset_type}, state) do
{:push, {:text, "reload"}, state}
end

def websocket_info({:file_event, _watcher_pid, {_path, _event}} = file_event, state) do
def handle_info({:file_event, _watcher_pid, {_path, _event}} = file_event, state) do
Tableau.LiveReload.reload!(file_event, patterns: @reloader_opts[:patterns])

{:ok, state}
end

def websocket_info(message, state) do
def handle_info(message, state) do
Logger.warning("Unhandled message: #{inspect(message)}")

{:ok, state}
Expand Down
4 changes: 3 additions & 1 deletion mix.exs
Expand Up @@ -35,14 +35,16 @@ defmodule Tableau.MixProject do
{:ex_doc, ">= 0.0.0", only: :dev},
{:file_system, "~> 0.2"},
{:libgraph, "~> 0.16.0"},
{:plug_cowboy, "~> 2.0"},
{:bandit, "~> 1.0"},
{:websock_adapter, "~> 0.5"},
{:plug_static_index_html, "~> 1.0"},
{:schematic, "~> 0.3.1"},
{:nimble_publisher, "~> 1.0"},
{:yaml_elixir, "~> 2.9"},
{:makeup_elixir, ">= 0.0.0"},
{:tz, "~> 0.26.2"},


# {:yaml_front_matter, "~> 1.0"},
# {:jason, "~> 1.4"},
# {:req, "~> 0.3", only: :test},
Expand Down
16 changes: 8 additions & 8 deletions mix.lock
@@ -1,27 +1,27 @@
%{
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"bandit": {:hex, :bandit, "1.0.0", "2bd87bbf713d0eed0090f2fa162cd1676198122e6c2b68a201c706e354a6d5e5", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [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", "32acf6ac030fee1f99fd9c3fcf81671911ae8637e0a61c98111861b466efafdb"},
"earmark": {:hex, :earmark, "1.4.46", "8c7287bd3137e99d26ae4643e5b7ef2129a260e3dcf41f251750cb4563c8fb81", [:mix], [], "hexpm", "798d86db3d79964e759ddc0c077d5eb254968ed426399fbf5a62de2b5ff8910a"},
"earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"},
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"nimble_publisher": {:hex, :nimble_publisher, "1.0.0", "e7c6b1dc0505a87dcb12e47427bce9f659eba36ab6f0afb8267d21f2ac701871", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "959ab4d9ff41a33a7269082ccf7e9fb76b840d850c872733dd4201591b6ea6f4"},
"plug": {:hex, :plug, "1.13.6", "187beb6b67c6cec50503e940f0434ea4692b19384d47e5fdfd701e93cadb4cc2", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02b9c6b9955bce92c829f31d6284bf53c591ca63c4fb9ff81dfd0418667a34ff"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.1", "7cc96ff645158a94cf3ec9744464414f02287f832d6847079adfe0b58761cbd0", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "107d0a5865fa92bcb48e631cc0729ae9ccfa0a9f9a1bd8f01acb513abf1c2d64"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"plug": {:hex, :plug, "1.15.1", "b7efd81c1a1286f13efb3f769de343236bd8b7d23b4a9f40d3002fc39ad8f74c", [: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", "459497bd94d041d98d948054ec6c0b76feacd28eec38b219ca04c0de13c79d30"},
"plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"},
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"schematic": {:hex, :schematic, "0.3.1", "be633c1472959dc0ace22dd0e1f1445b099991fec39f6d6e5273d35ebd217ac4", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "52c419b5c405286e2d0369b9ca472b00b850c59a8b0bdf0dd69172ad4418d5ea"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"thousand_island": {:hex, :thousand_island, "1.0.0", "63fc8807d8607c9d74fa670996897c8c8a1f2022c8c68d024182e45249acd756", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "996320c72ba8f34d7be9b02900622e44341649f24359e0f67643e4dda8f23995"},
"tz": {:hex, :tz, "0.26.2", "a40e4bb223344c6fc7b74dda25df1f26b88a30db23fa6e55de843bd79148ccdb", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.5", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "224b0618dd1e032778a094040bc710ef9aff6e2fa8fffc2716299486f27b9e68"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
"websock_adapter": {:hex, :websock_adapter, "0.5.4", "7af8408e7ed9d56578539594d1ee7d8461e2dd5c3f57b0f2a5352d610ddde757", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d2c238c79c52cbe223fcdae22ca0bb5007a735b9e933870e241fce66afb4f4ab"},
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
"yaml_elixir": {:hex, :yaml_elixir, "2.9.0", "9a256da867b37b8d2c1ffd5d9de373a4fda77a32a45b452f1708508ba7bbcb53", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "0cb0e7d4c56f5e99a6253ed1a670ed0e39c13fc45a6da054033928607ac08dfc"},
}

0 comments on commit 36cccc9

Please sign in to comment.