Skip to content

Commit 5d2e274

Browse files
committed
Change defaults
1 parent 1efe2cc commit 5d2e274

4 files changed

Lines changed: 75 additions & 21 deletions

File tree

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,12 @@ PORT=3333
2929

3030
# These have defaults hard-coded, but are being overridden
3131
CACHE_VIEWS=false
32+
33+
# SQLite durability/concurrency notes:
34+
# - WAL improves concurrent reads/writes for the default SQLite deployment.
35+
# - FULL is the safer default for production durability.
36+
# - NORMAL reduces fsync pressure, but may lose the last committed transactions
37+
# on sudden power loss or kernel crash.
38+
DB_SQLITE_JOURNAL_MODE=WAL
39+
DB_SQLITE_SYNCHRONOUS=FULL
40+
DB_BUSY_TIMEOUT=5000

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ Ferdium-server's configuration is saved inside an `.env` file. Besides AdonisJS'
117117
- `CONNECT_WITH_FRANZ` (`true` or `false`, default: `true`): Whether to enable connections to the Franz server. By enabling this option, Ferdium-server can:
118118
- Show the full Franz recipe library instead of only custom recipes
119119
- Import Franz accounts
120+
- `DB_SQLITE_JOURNAL_MODE` (`DELETE`, `TRUNCATE`, `PERSIST`, `MEMORY`, `WAL`, or `OFF`, default: `WAL`): SQLite journal mode. `WAL` improves concurrency for the default single-file deployment.
121+
- `DB_SQLITE_SYNCHRONOUS` (`OFF`, `NORMAL`, `FULL`, or `EXTRA`, default: `FULL`): SQLite synchronous mode. `FULL` is the safer default for production durability. `NORMAL` reduces write latency but can lose the last committed transactions on sudden power loss.
122+
- `DB_BUSY_TIMEOUT` (milliseconds, default: `5000`): How long SQLite should wait for a locked database before failing a query.
120123
</details>
121124
<details>
122125
<summary>Importing your Franz/Ferdi account</summary>

config/database.ts

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,33 @@ type SqlitePoolCallback = (
1919
connection: SqliteConnection,
2020
) => void;
2121

22+
const SQLITE_JOURNAL_MODE_VALUES = new Set([
23+
'DELETE',
24+
'TRUNCATE',
25+
'PERSIST',
26+
'MEMORY',
27+
'WAL',
28+
'OFF',
29+
]);
30+
const SQLITE_SYNCHRONOUS_VALUES = new Set(['OFF', 'NORMAL', 'FULL', 'EXTRA']);
2231
const SQLITE_BUSY_TIMEOUT_DEFAULT = 5000;
32+
const SQLITE_JOURNAL_MODE_DEFAULT = 'WAL';
33+
const SQLITE_SYNCHRONOUS_DEFAULT = 'FULL';
34+
35+
function getSqlitePragmaValue(
36+
envName: string,
37+
defaultValue: string,
38+
allowedValues: Set<string>,
39+
) {
40+
const configuredValue = Env.get(envName, defaultValue).trim().toUpperCase();
41+
42+
if (!allowedValues.has(configuredValue)) {
43+
return defaultValue;
44+
}
45+
46+
return configuredValue;
47+
}
48+
2349
const sqliteBusyTimeoutEnv = Env.get(
2450
'DB_BUSY_TIMEOUT',
2551
SQLITE_BUSY_TIMEOUT_DEFAULT.toString(),
@@ -29,6 +55,16 @@ const sqliteBusyTimeout =
2955
Number.isFinite(sqliteBusyTimeoutParsed) && sqliteBusyTimeoutParsed > 0
3056
? sqliteBusyTimeoutParsed
3157
: SQLITE_BUSY_TIMEOUT_DEFAULT;
58+
const sqliteJournalMode = getSqlitePragmaValue(
59+
'DB_SQLITE_JOURNAL_MODE',
60+
SQLITE_JOURNAL_MODE_DEFAULT,
61+
SQLITE_JOURNAL_MODE_VALUES,
62+
);
63+
const sqliteSynchronous = getSqlitePragmaValue(
64+
'DB_SQLITE_SYNCHRONOUS',
65+
SQLITE_SYNCHRONOUS_DEFAULT,
66+
SQLITE_SYNCHRONOUS_VALUES,
67+
);
3268

3369
function configureSqliteConnection(
3470
conn: SqliteConnection,
@@ -40,27 +76,30 @@ function configureSqliteConnection(
4076
return;
4177
}
4278

43-
conn.run('PRAGMA journal_mode = WAL', (journalModeError: Error | null) => {
44-
if (journalModeError) {
45-
cb(journalModeError, conn);
46-
return;
47-
}
48-
49-
conn.run(
50-
'PRAGMA synchronous = NORMAL',
51-
(synchronousError: Error | null) => {
52-
if (synchronousError) {
53-
cb(synchronousError, conn);
54-
return;
55-
}
56-
57-
conn.run(
58-
`PRAGMA busy_timeout = ${sqliteBusyTimeout}`,
59-
(busyTimeoutError: Error | null) => cb(busyTimeoutError, conn),
60-
);
61-
},
62-
);
63-
});
79+
conn.run(
80+
`PRAGMA journal_mode = ${sqliteJournalMode}`,
81+
(journalModeError: Error | null) => {
82+
if (journalModeError) {
83+
cb(journalModeError, conn);
84+
return;
85+
}
86+
87+
conn.run(
88+
`PRAGMA synchronous = ${sqliteSynchronous}`,
89+
(synchronousError: Error | null) => {
90+
if (synchronousError) {
91+
cb(synchronousError, conn);
92+
return;
93+
}
94+
95+
conn.run(
96+
`PRAGMA busy_timeout = ${sqliteBusyTimeout}`,
97+
(busyTimeoutError: Error | null) => cb(busyTimeoutError, conn),
98+
);
99+
},
100+
);
101+
},
102+
);
64103
});
65104
}
66105

data/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
ferdium.sqlite
2+
ferdium.sqlite-shm
3+
ferdium.sqlite-wal
4+
ferdium-*.log

0 commit comments

Comments
 (0)