File tree Expand file tree Collapse file tree 3 files changed +24
-4
lines changed
src/backingstore/better-sqlite3 Expand file tree Collapse file tree 3 files changed +24
-4
lines changed Original file line number Diff line number Diff line change @@ -23,6 +23,8 @@ COPY --from=build-stage /tmp/src/package.json /
2323
2424ENV NODE_ENV=production
2525ENV NODE_CONFIG_DIR=/data/config
26+ # Set SQLite's temporary directory. See #746 for context.
27+ ENV SQLITE_TMPDIR=/data
2628
2729CMD ["bot" ]
2830ENTRYPOINT ["./draupnir-entrypoint.sh" ]
Original file line number Diff line number Diff line change @@ -14,7 +14,7 @@ import { Logger } from "matrix-protection-suite";
1414const log = new Logger ( "BetterSqliteStore" ) ;
1515
1616export function sqliteV0Schema ( db : Database ) {
17- // we have to prepare and run them seperatley becasue prepare checks if the
17+ // we have to prepare and run them separately because ` prepare` checks if the
1818 // table exists.
1919 const createTable = db . transaction ( ( ) => {
2020 db . prepare (
@@ -176,3 +176,20 @@ export abstract class BetterSqliteStore {
176176 throw Error ( "Couldn't fetch schema version" ) ;
177177 }
178178}
179+
180+ /**
181+ * Wraps `fn` in a transaction without creating nested SAVEPOINTs.
182+ * Reduces the likelihood of temporary file creation.
183+ * Initially investigated as part of #746.
184+ *
185+ * See https://www.sqlite.org/lang_savepoint.html
186+ * See https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md#transactionfunction---function
187+ */
188+ export function flatTransaction < Arguments extends unknown [ ] , Result > (
189+ db : Database ,
190+ fn : ( ...args : Arguments ) => Result
191+ ) {
192+ const t = db . transaction ( fn ) ;
193+ return ( ...args : Arguments ) : Result =>
194+ db . inTransaction ? fn ( ...args ) : t ( ...args ) ;
195+ }
Original file line number Diff line number Diff line change @@ -15,7 +15,7 @@ import {
1515 StateEvent ,
1616 isError ,
1717} from "matrix-protection-suite" ;
18- import { BetterSqliteStore } from "./BetterSqliteStore" ;
18+ import { BetterSqliteStore , flatTransaction } from "./BetterSqliteStore" ;
1919import { jsonReviver } from "../../utils" ;
2020import { StringRoomID } from "@the-draupnir-project/matrix-basic-types" ;
2121
@@ -64,6 +64,7 @@ export class SqliteRoomStateBackingStore
6464 ) ;
6565 this . db . pragma ( "journal_mode = WAL" ) ;
6666 this . db . pragma ( "foreign_keys = ON" ) ;
67+ this . db . pragma ( "temp_store = file" ) ; // Avoid unnecessary memory usage.
6768 this . ensureSchema ( ) ;
6869 }
6970
@@ -85,8 +86,8 @@ export class SqliteRoomStateBackingStore
8586 JSON . stringify ( event ) ,
8687 ] ;
8788 } ;
88- // i don't understand why the library makes us do this but ok .
89- const replace = this . db . transaction ( ( events : StateEvent [ ] ) => {
89+ // `flatTransaction` optimizes away unnecessary temporary files .
90+ const replace = flatTransaction ( this . db , ( events : StateEvent [ ] ) => {
9091 for ( const event of events ) {
9192 replaceStatement . run ( createValue ( event ) ) ;
9293 }
You can’t perform that action at this time.
0 commit comments