Create archives in worker to lessen load time
Also use new response helpers to set content type later when Raxx doesn't crash from it
This commit is contained in:
parent
8ca9ff1690
commit
e7ff21ace3
6 changed files with 70 additions and 12 deletions
|
@ -28,6 +28,9 @@ defmodule Mebe2.Engine.DB do
|
|||
# Table for storing menu data
|
||||
@menu_table :mebe2_menu
|
||||
|
||||
# Table for storing archives
|
||||
@archives_table :mebe2_archives
|
||||
|
||||
@spec init() :: :ok
|
||||
def init() do
|
||||
# Only create tables if they don't exist already
|
||||
|
@ -38,6 +41,7 @@ defmodule Mebe2.Engine.DB do
|
|||
:ets.new(@single_post_table, [:named_table, :set, :protected, read_concurrency: true])
|
||||
:ets.new(@tag_table, [:named_table, :ordered_set, :protected, read_concurrency: true])
|
||||
:ets.new(@menu_table, [:named_table, :ordered_set, :protected, read_concurrency: true])
|
||||
:ets.new(@archives_table, [:named_table, :set, :protected, read_concurrency: true])
|
||||
end
|
||||
|
||||
:ok
|
||||
|
@ -50,6 +54,7 @@ defmodule Mebe2.Engine.DB do
|
|||
:ets.delete_all_objects(@post_table)
|
||||
:ets.delete_all_objects(@single_post_table)
|
||||
:ets.delete_all_objects(@tag_table)
|
||||
:ets.delete_all_objects(@archives_table)
|
||||
:ok
|
||||
end
|
||||
|
||||
|
@ -107,6 +112,15 @@ defmodule Mebe2.Engine.DB do
|
|||
:ets.insert(@tag_table, tag_posts)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Insert archive data into the archive table.
|
||||
"""
|
||||
@spec insert_archives([{integer, integer}], :months) :: true
|
||||
@spec insert_archives(%{optional(String.t()) => integer}, :tags) :: true
|
||||
def insert_archives(data, type) when is_atom(type) do
|
||||
:ets.insert(@archives_table, {type, data})
|
||||
end
|
||||
|
||||
@spec get_menu() :: [Models.MenuItem.t()]
|
||||
def get_menu() do
|
||||
case :ets.match(@menu_table, :"$1") do
|
||||
|
@ -185,6 +199,19 @@ defmodule Mebe2.Engine.DB do
|
|||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get data from archives with the given type.
|
||||
"""
|
||||
@spec get_archives(:months) :: [{integer, integer}]
|
||||
@spec get_archives(:tags) :: %{optional(String.t()) => integer}
|
||||
def get_archives(type) do
|
||||
case :ets.match_object(@archives_table, {type, :"$1"}) do
|
||||
[{_, data}] -> data
|
||||
_ when type == :months -> []
|
||||
_ when type == :tags -> %{}
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_page(String.t()) :: Models.Page.t() | nil
|
||||
def get_page(slug) do
|
||||
case :ets.match_object(@page_table, {slug, :"$1"}) do
|
||||
|
|
|
@ -11,6 +11,7 @@ defmodule Mebe2.Engine.Worker do
|
|||
GenServer.start_link(__MODULE__, :ok, opts)
|
||||
end
|
||||
|
||||
@spec init(:ok) :: {:ok, nil}
|
||||
def init(:ok) do
|
||||
load_db()
|
||||
{:ok, nil}
|
||||
|
@ -21,17 +22,21 @@ defmodule Mebe2.Engine.Worker do
|
|||
{:reply, :ok, nil}
|
||||
end
|
||||
|
||||
@spec refresh_db() :: :ok
|
||||
def refresh_db() do
|
||||
Logger.info("Destroying database…")
|
||||
DB.destroy()
|
||||
:ok = DB.destroy()
|
||||
Logger.info("Reloading database…")
|
||||
load_db()
|
||||
:ok = load_db()
|
||||
Logger.info("Update done!")
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
@doc """
|
||||
Initialize the database by crawling the configured path and parsing data to the DB.
|
||||
"""
|
||||
@spec load_db() :: :ok
|
||||
def load_db() do
|
||||
data_path = Mebe2.get_conf(:data_path)
|
||||
|
||||
|
@ -71,6 +76,11 @@ defmodule Mebe2.Engine.Worker do
|
|||
DB.insert_count(:month, month, Enum.count(months[month]))
|
||||
end)
|
||||
|
||||
DB.get_all_months() |> DB.insert_archives(:months)
|
||||
DB.get_all_tags() |> DB.insert_archives(:tags)
|
||||
|
||||
Logger.info("Posts loaded.")
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,10 +28,10 @@ defmodule Mebe2.Web.Middleware.Archives do
|
|||
"""
|
||||
@spec put_archives() :: :ok
|
||||
def put_archives() do
|
||||
months = Mebe2.Engine.DB.get_all_months()
|
||||
months = Mebe2.Engine.DB.get_archives(:months)
|
||||
Process.put(@month_archives_key, months)
|
||||
|
||||
tags = Mebe2.Engine.DB.get_all_tags()
|
||||
tags = Mebe2.Engine.DB.get_archives(:tags)
|
||||
Process.put(@tag_archives_key, tags)
|
||||
:ok
|
||||
end
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
defmodule Mebe2.Web.Routes.Page do
|
||||
use Raxx.SimpleServer
|
||||
alias Mebe2.Engine.{DB, Models}
|
||||
alias Mebe2.Web.Routes.Utils
|
||||
|
||||
@impl Raxx.SimpleServer
|
||||
def handle_request(%Raxx.Request{path: [slug]} = _req, _state) do
|
||||
with {:page, %Models.Page{} = page} <- {:page, DB.get_page(slug)} do
|
||||
response(200)
|
||||
Utils.html_response(200)
|
||||
|> Mebe2.Web.Views.Page.render(page)
|
||||
else
|
||||
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||
_ -> Utils.render_404()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
defmodule Mebe2.Web.Routes.Post do
|
||||
use Raxx.SimpleServer
|
||||
alias Mebe2.Engine.{DB, Models}
|
||||
alias Mebe2.Web.Routes.Utils
|
||||
|
||||
@impl Raxx.SimpleServer
|
||||
def handle_request(%Raxx.Request{path: [y_str, m_str, d_str, slug]} = _req, _state) do
|
||||
|
@ -8,10 +9,10 @@ defmodule Mebe2.Web.Routes.Post do
|
|||
{:month, {month, ""}} <- {:month, Integer.parse(m_str)},
|
||||
{:day, {day, ""}} <- {:day, Integer.parse(d_str)},
|
||||
{:post, %Models.Post{} = post} <- {:post, DB.get_post(year, month, day, slug)} do
|
||||
response(200)
|
||||
Utils.html_response(200)
|
||||
|> Mebe2.Web.Views.SinglePost.render(post)
|
||||
else
|
||||
_ -> Mebe2.Web.Routes.Utils.render_404()
|
||||
_ -> Utils.render_404()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,9 +46,9 @@ defmodule Mebe2.Web.Routes.Utils do
|
|||
) :: Raxx.Response.t()
|
||||
def render_posts(page \\ "1", post_getter, renderer) do
|
||||
with n when is_integer(n) <- parse_page_number(page),
|
||||
{first, limit} = Mebe2.Web.Routes.Utils.get_post_range(n),
|
||||
{first, limit} = get_post_range(n),
|
||||
{[_ | _] = posts, total} <- post_getter.(first, limit) do
|
||||
Raxx.response(200) |> renderer.(posts, total, n)
|
||||
html_response(200) |> renderer.(posts, total, n)
|
||||
else
|
||||
_ -> render_404()
|
||||
end
|
||||
|
@ -67,7 +67,7 @@ defmodule Mebe2.Web.Routes.Utils do
|
|||
{first, limit} = get_post_range(1, Mebe2.get_conf(:posts_in_feed))
|
||||
{posts, _} = post_getter.(first, limit)
|
||||
|
||||
Raxx.response(200)
|
||||
rss_response(200)
|
||||
|> Mebe2.Web.Views.Feeds.PostList.render(posts)
|
||||
else
|
||||
_ -> render_404()
|
||||
|
@ -79,7 +79,26 @@ defmodule Mebe2.Web.Routes.Utils do
|
|||
"""
|
||||
@spec render_404() :: Raxx.Response.t()
|
||||
def render_404() do
|
||||
Raxx.response(404)
|
||||
html_response(404)
|
||||
|> Mebe2.Web.Views.NotFound.render()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get an HTML response with the proper content type.
|
||||
"""
|
||||
@spec html_response(integer) :: Raxx.Response.t()
|
||||
def html_response(code) when is_integer(code) do
|
||||
Raxx.response(code)
|
||||
# TODO: Fix these when Raxx doesn't crash on setting content type when using views
|
||||
# |> Raxx.set_header("content-type", "text/html; charset=utf-8")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get an RSS response with the proper content type.
|
||||
"""
|
||||
@spec rss_response(integer) :: Raxx.Response.t()
|
||||
def rss_response(code) when is_integer(code) do
|
||||
Raxx.response(code)
|
||||
# |> Raxx.set_header("content-type", "application/xml+rss; charset=utf-8")
|
||||
end
|
||||
end
|
||||
|
|
Reference in a new issue