Arcology.Application detangled
parent
2b8356513f
commit
22de64460f
|
@ -0,0 +1,109 @@
|
|||
:PROPERTIES:
|
||||
:ID: 20230303T100429.248407
|
||||
:END:
|
||||
#+TITLE: Arcology Elixir Backend Logic
|
||||
|
||||
#+AUTO_TANGLE: t
|
||||
|
||||
* Setting up the =Arcology= elixir module
|
||||
|
||||
This is a module, the submodules are where the interesting things happen. The module doc says what it does:
|
||||
|
||||
#+begin_src text :noweb-ref arcology.moduledoc
|
||||
Arcology keeps the contexts that define your domain
|
||||
and business logic.
|
||||
|
||||
Contexts are also responsible for managing your data, regardless
|
||||
if it comes from the database, an external API or others.
|
||||
#+end_src
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology.ex :noweb yes
|
||||
defmodule Arcology do
|
||||
@moduledoc """
|
||||
<<arcology.moduledoc>>
|
||||
"""
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* =Arcology.Application= Elixir Application Startup
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology/application.ex :noweb yes
|
||||
defmodule Arcology.Application do
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
<<start_2>>
|
||||
|
||||
<<config_change_3>>
|
||||
end
|
||||
#+end_src
|
||||
|
||||
So =Arcology.Application.start/2= is the entrypoint of the Phoenix [[https://hexdocs.pm/elixir/Application.html][OTP application]], it starts up a bunch of other *Supervised*[fn:1] Elixir processes and makes sure they keep running.
|
||||
|
||||
** =Arcology.Application.start/2=
|
||||
|
||||
We start the Ecto repository [[roam:Arcology.Repo]]:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
Arcology.Repo
|
||||
#+end_src
|
||||
|
||||
We start the PubSub messaging system:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
{Phoenix.PubSub, name: Arcology.PubSub}
|
||||
#+end_src
|
||||
|
||||
We start [[https://github.com/sneako/finch][Finch]], an HTTP client:
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
{Finch, name: Arcology.Finch}
|
||||
#+end_src
|
||||
|
||||
We start the [[roam:ArcologyWeb.Endpoint]] which handles HTTP requests from the web.
|
||||
|
||||
#+begin_src elixir :noweb-ref app-children
|
||||
ArcologyWeb.Endpoint
|
||||
#+end_src
|
||||
|
||||
We will also start the =ArcologyWeb.Telemetry= server provided by Phoenix [n.b. this code block isn't directly included so that i can generate decent list-syntax without relying on metaprogramming or not being able to detangle this to my heart's content]
|
||||
|
||||
This supervisor is configured to only restart a single process when the process dies; for other applications you may want it to restart *all* children, or to only restart "younger" processes which may rely on state within the dead process. This is pretty simple for now. Check out [[https://hexdocs.pm/elixir/Supervisor.html][the docs]] if you care.
|
||||
|
||||
#+begin_src elixir :noweb-ref start_2 :noweb yes
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
ArcologyWeb.Telemetry
|
||||
, <<app-children>>
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Arcology.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
#+end_src
|
||||
|
||||
This =config_change= function is a stub that sends new configuration to the =ArcologyWeb.Endpoint= process when the appication is upgraded. I'll probably just restart the thing in place, but for highly-available OTP applications this sort of stuff is bread-and-butter.
|
||||
|
||||
#+begin_src elixir :noweb-ref config_change_3
|
||||
@impl true
|
||||
def config_change(changed, _new, removed) do
|
||||
ArcologyWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* =Arcology.Mailer=
|
||||
|
||||
This is a stub for now -- maybe i'll send mails for new posts in the future but *shrug*:
|
||||
|
||||
#+begin_src elixir :tangle lib/arcology/mailer.ex
|
||||
defmodule Arcology.Mailer do
|
||||
use Swoosh.Mailer, otp_app: :arcology
|
||||
end
|
||||
#+end_src
|
||||
|
||||
* Footnotes
|
||||
|
||||
[fn:1] Elixir is built on Erlang, and Erlang has a process-based Actor model, you can send messages to processes whose IDs you have. The Supervisor is responsible for starting and managing the lifecycle of these processes. See [[https://www.erlang.org/doc/design_principles/sup_princ.html][the OTP Design Principles]] doc.
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Arcology do
|
||||
@moduledoc """
|
||||
Arcology keeps the contexts that define your domain
|
||||
and business logic.
|
||||
|
||||
Contexts are also responsible for managing your data, regardless
|
||||
if it comes from the database, an external API or others.
|
||||
"""
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
defmodule Arcology.Application do
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
ArcologyWeb.Telemetry
|
||||
, Arcology.Repo
|
||||
, {Phoenix.PubSub, name: Arcology.PubSub}
|
||||
, {Finch, name: Arcology.Finch}
|
||||
, ArcologyWeb.Endpoint
|
||||
]
|
||||
|
||||
opts = [strategy: :one_for_one, name: Arcology.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def config_change(changed, _new, removed) do
|
||||
ArcologyWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
defmodule Arcology.Mailer do
|
||||
use Swoosh.Mailer, otp_app: :arcology
|
||||
end
|
Loading…
Reference in New Issue