Skip to content

Commit 5d2b5d1

Browse files
committed
add application supervision tree
1 parent 008d525 commit 5d2b5d1

File tree

10 files changed

+90
-24
lines changed

10 files changed

+90
-24
lines changed

benchmarks/bench.exs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,25 @@ defmodule SQL.Repo do
88
use SQL, adapter: SQL.Adapters.Postgres
99
import Ecto.Query
1010
def sql() do
11-
# SQL.transaction do
12-
# SQL.transaction do
11+
SQL.transaction do
12+
SQL.transaction do
1313
Enum.to_list(~SQL"SELECT 1")
14-
# end
15-
# end
14+
end
15+
end
1616
end
1717

1818
def ecto() do
19-
# SQL.Repo.transaction(fn ->
20-
# SQL.Repo.transaction(fn ->
19+
SQL.Repo.transaction(fn ->
20+
SQL.Repo.transaction(fn ->
2121
SQL.Repo.all(select(from("users"), [1]))
22-
# end)
23-
# end)
22+
end)
23+
end)
2424
end
2525
end
2626
Application.put_env(:sql, :ecto_repos, [SQL.Repo])
27-
Application.put_env(:sql, SQL.Repo, log: false, username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", pool_size: 10, ssl: false)
27+
Application.put_env(:sql, SQL.Repo, log: false, username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", pool_size: :erlang.system_info(:schedulers_online), ssl: false)
2828
SQL.Repo.__adapter__().storage_up(SQL.Repo.config())
2929
SQL.Repo.start_link()
30-
SQL.Pool.start_link(%{username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", adapter: SQL.Adapters.Postgres, ssl: false})
3130
# query = "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n])
3231
# sql = ~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]
3332
# result = Tuple.to_list(SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)"))
@@ -58,7 +57,7 @@ Benchee.run(
5857
# "runtime ecto" => fn _ -> SQL.Repo.to_sql(:all, "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n])) end,
5958
# "comptime ecto" => fn _ -> SQL.Repo.to_sql(:all, query) end
6059
},
61-
parallel: 50,
60+
parallel: 1,
6261
memory_time: 2,
6362
reduction_time: 2,
6463
unit_scaling: :smallest,

config/config.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: 2025 DBVisor
3+
4+
import Config
5+
import_config "#{config_env()}.exs"

config/dev.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: 2025 DBVisor
3+
4+
import Config
5+
6+
config :sql, pools: [
7+
default: %{
8+
username: "postgres",
9+
password: "postgres",
10+
hostname: "localhost",
11+
database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}",
12+
adapter: SQL.Adapters.Postgres,
13+
ssl: false}
14+
]

config/prod.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: 2025 DBVisor
3+
4+
import Config

config/test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: 2025 DBVisor
3+
4+
import Config
5+
6+
config :sql, pools: [
7+
default: %{
8+
username: "postgres",
9+
password: "postgres",
10+
hostname: "localhost",
11+
database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}",
12+
adapter: SQL.Adapters.Postgres,
13+
ssl: false}
14+
]

lib/adapters/postgres.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule SQL.Adapters.Postgres do
1616
@execute <<?E,9::32,0,0::32-big>>
1717

1818
def start(state) do
19-
spawn(fn -> init(state) end)
19+
{:ok, spawn(fn -> init(state) end)}
2020
end
2121

2222
defp to_iodata({:in, m, [{:not, _, left}, {:binding, _, [idx]}]}, format, case, acc) do
@@ -38,7 +38,7 @@ defmodule SQL.Adapters.Postgres do
3838
:socket.connect(socket, Map.take(state, [:family, :port, :addr]), handle)
3939
receive do
4040
{:"$socket", ^socket, :select, ^handle} ->
41-
:ok = :socket.connect(socket)
41+
:socket.connect(socket)
4242
:socket.recv(socket, 0, [], handle)
4343
state
4444
|> Map.put(:socket, socket)
@@ -95,7 +95,7 @@ defmodule SQL.Adapters.Postgres do
9595
{:ssl_error, ^socket, reason} ->
9696
raise reason
9797
after
98-
0 ->
98+
5 ->
9999
case owner do
100100
nil ->
101101
case :queue.out(queue) do

lib/application.ex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# SPDX-FileCopyrightText: 2025 DBVisor
3+
4+
defmodule SQL.Application do
5+
@moduledoc false
6+
7+
def start(_type, _args) do
8+
pools = Application.get_env(:sql, :pools, [])
9+
children = for {name, opts} <- pools, do: {SQL.Pool, Map.put(opts, :name, name)}
10+
result = {:ok, _sup} = Supervisor.start_link(children, strategy: :one_for_all)
11+
for {name, _} <- pools do
12+
pid = Process.whereis(name)
13+
children = Supervisor.which_children(pid)
14+
pids = Enum.map(children, fn {_id, pid, _type, _mod} -> pid end)
15+
:persistent_term.put(name, List.to_tuple(pids))
16+
end
17+
result
18+
end
19+
end

lib/pool.ex

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,25 @@
33

44
defmodule SQL.Pool do
55
@moduledoc false
6-
use GenServer
6+
use Supervisor
77

88
@default %{ssl: false, timeout: 5000, parameter: %{}, name: :default, protocol: :tcp, use_registry: false, debug: false, otp: %{rcvbuf: {64_000, 128_000}}, socket: %{keepalive: true, linger: %{onoff: true, linger: 5}}, family: :inet, port: 5432, addr: {127, 0, 0, 1}}
99
def start_link(opts) do
10-
GenServer.start_link(__MODULE__, Map.merge(@default, opts), name: __MODULE__)
10+
Supervisor.start_link(__MODULE__, Map.merge(@default, opts), name: opts[:name])
1111
end
1212

1313
@impl true
1414
def init(state) do
15-
:persistent_term.put(state.name, List.to_tuple(for n <- 1..:erlang.system_info(:schedulers_online), do: state.adapter.start(Map.put(state, :scheduler_id, n))))
16-
{:ok, state}
15+
children =
16+
for n <- 1..:erlang.system_info(:schedulers_online) do
17+
%{
18+
id: {:conn, n},
19+
start: {state.adapter, :start, [Map.put(state, :scheduler_id, n)]},
20+
restart: :permanent,
21+
shutdown: 5000,
22+
type: :worker,
23+
}
24+
end
25+
Supervisor.init(children, strategy: :one_for_one)
1726
end
1827
end

mix.exs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ defmodule SQL.MixProject do
1111
app: :sql,
1212
version: @version,
1313
elixir: "~> 1.19",
14+
start_permanent: Mix.env() == :prod,
1415
deps: deps(),
1516
description: "Brings an extensible SQL parser and sigil to Elixir, confidently write SQL with automatic parameterized queries.",
1617
name: "SQL",
@@ -21,6 +22,12 @@ defmodule SQL.MixProject do
2122
]
2223
end
2324

25+
def application do
26+
[
27+
mod: {SQL.Application, []}
28+
]
29+
end
30+
2431
defp elixirc_paths(:test), do: ["lib", "test"]
2532
defp elixirc_paths(_), do: ["lib"]
2633

@@ -50,7 +57,7 @@ defmodule SQL.MixProject do
5057
{:postgrex, ">= 0.0.0", only: :dev},
5158
{:tds, ">= 0.0.0", only: :dev},
5259
{:myxql, ">= 0.0.0", only: :dev},
53-
{:yamerl, ">= 0.0.0", only: :dev},
60+
{:yamerl, ">= 0.0.0", only: [:dev, :test]},
5461
{:unicode_set, "~> 1.0"}
5562
]
5663
end

test/adapters/postgres_test.exs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ defmodule SQL.Adapters.PostgresTest do
55
use SQL.Case, async: true
66
use SQL, adapter: SQL.Adapters.Postgres
77

8-
setup_all do
9-
{:ok, _pid} = SQL.Pool.start_link(%{username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", adapter: SQL.Adapters.Postgres, ssl: false})
10-
:ok
11-
end
12-
138
describe "with" do
149
test "recursive" do
1510
assert "with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)" == to_string(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)])

0 commit comments

Comments
 (0)