Skip to content

Commit 1ac99d0

Browse files
authored
set journal mode at storage_up time. this allows us to avoid problems… (#25)
* set journal mode at storage_up time. this allows us to avoid problems with setting it in parallel across all connections at connection time, which can hit database locked errors * format * bump exqlite, add changelog
1 parent 4cc1466 commit 1ac99d0

File tree

5 files changed

+13
-27
lines changed

5 files changed

+13
-27
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ jobs:
4545
# - run: mix compile --warnings-as-errors
4646
# if: ${{ matrix.lint }}
4747

48-
- run: mix test
48+
- run: mix test --trace
4949

50-
- run: EXQLITE_INTEGRATION=true mix test
50+
- run: EXQLITE_INTEGRATION=true mix test --trace

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ All notable changes will be documented in this file.
55
The format is based on [Keep a Changelog][keepachangelog], and this project
66
adheres to [Semantic Versioning][semver].
77

8+
## [0.5.5] - Unreleased
9+
- Fix "database is locked" issue by setting `journal_mode` at `storage_up` time.
10+
811

912
## [0.5.4] - 2021-04-06
1013
- Upgrade `ecto_sql` dependency to 3.6.0

lib/ecto/adapters/sqlite3.ex

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,10 @@ defmodule Ecto.Adapters.SQLite3 do
157157

158158
@impl Ecto.Adapter.Storage
159159
def storage_up(options) do
160-
options
161-
|> Keyword.get(:database)
162-
|> storage_up_with_path()
160+
storage_up_with_path(
161+
Keyword.get(options, :database),
162+
Keyword.get(options, :journal_mode, :wal)
163+
)
163164
end
164165

165166
@impl Ecto.Adapter.Migration
@@ -324,7 +325,7 @@ defmodule Ecto.Adapters.SQLite3 do
324325
## HELPERS
325326
##
326327

327-
defp storage_up_with_path(nil) do
328+
defp storage_up_with_path(nil, _) do
328329
raise ArgumentError,
329330
"""
330331
No SQLite database path specified. Please check the configuration for your Repo.
@@ -336,12 +337,13 @@ defmodule Ecto.Adapters.SQLite3 do
336337
"""
337338
end
338339

339-
defp storage_up_with_path(db_path) do
340+
defp storage_up_with_path(db_path, journal_mode) do
340341
if File.exists?(db_path) do
341342
{:error, :already_up}
342343
else
343344
db_path |> Path.dirname() |> File.mkdir_p!()
344345
{:ok, db} = Exqlite.Sqlite3.open(db_path)
346+
:ok = Exqlite.Sqlite3.execute(db, "PRAGMA JOURNAL_MODE = #{journal_mode}")
345347
:ok = Exqlite.Sqlite3.close(db)
346348
end
347349
end

lib/ecto/adapters/sqlite3/connection.ex

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,13 @@ defmodule Ecto.Adapters.SQLite3.Connection do
1515
import Ecto.Adapters.SQLite3.DataType
1616

1717
@parent_as __MODULE__
18-
@idx_connect_buffer 5
19-
@rand_connect_buffer 50
20-
21-
# db_connection eagerly obtains and holds the configured
22-
# pool_size of connections, which can cause us to hit
23-
# "SQLite Busy" issues. we solve this by making sure to wait
24-
# a bit by hooking into the :configure callback opt and
25-
# sleeping an amount of time which is a function of the pool_index
26-
def handle_thundering_herd(opts) do
27-
case Keyword.get(opts, :pool_index) do
28-
idx when is_integer(idx) -> :timer.sleep(idx * @idx_connect_buffer)
29-
nil -> :timer.sleep(:rand.uniform(@rand_connect_buffer))
30-
end
31-
32-
opts
33-
end
3418

3519
defp default_opts(opts) do
36-
# todo: we may want to consider wrapping any provided :configure
37-
# with our custom connection buffering logic
3820
opts
3921
|> Keyword.put_new(:journal_mode, :wal)
4022
|> Keyword.put_new(:cache_size, -64000)
4123
|> Keyword.put_new(:temp_store, :memory)
4224
|> Keyword.put_new(:pool_size, 5)
43-
|> Keyword.put_new(:configure, &handle_thundering_herd/1)
4425
end
4526

4627
def start_link(opts) do

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"ecto_sql": {:hex, :ecto_sql, "3.6.0", "5cb277b086618a644f2c5450316202a885716bb7726b9f13b74cb0708bea3a8f", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3486d6e29ee4a0e7a381390c9c289bfbbaf5dc1971e269c579799d2300e5bd5"},
1111
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
1212
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
13-
"exqlite": {:hex, :exqlite, "0.5.8", "b1942f9f51b27608917ec2f035e69f7ff6d846eccff5157e27c90c14a5d1a168", [:make, :mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "5bed331bf406c27c7dae42040b835f1371018595a9dc218f9b92927e8a7c47c5"},
13+
"exqlite": {:hex, :exqlite, "0.5.10", "678f1237e877b87dd59e56ee13d63a0479640aa99094ead946bcd8451b492868", [:make, :mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "d30baa1fca4d87b1bc80c2cc591fe398d81457e1b5975d2e5963d233b1275c1a"},
1414
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
1515
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
1616
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},

0 commit comments

Comments
 (0)