mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Fixing lock issues and reverting back to single connection.
Summary: Removing `createNewConnection` method that was used in tests to create a "scoped" version of `HomeDbManager`. Currently this won't work as there are many methods (like `Users.findOne`) that are using the default (global) connection. Additionally `HomeDBManger` had couple of bugs that were causing locks, which manifested themselves in postgresql tests (that are not serializing transactions). Repository methods like `Users.findOne` or `user.save()`, even when wrapped in transaction were using a separate connection from the pool (and a separate transaction). Some tests in `UsersManager` are still skipped or refactored, as sinon's `fakeTimers` doesn't work well with postgresql driver (which is using `setTimout` a lot). Date mappings in `User` entity were fixed, they were using `SQLite` configuration only, which caused problems with postgresql database. Test Plan: Refactored. Reviewers: paulfitz Reviewed By: paulfitz Subscribers: paulfitz Differential Revision: https://phab.getgrist.com/D4342
This commit is contained in:
@@ -55,43 +55,33 @@ export function getConnectionName() {
|
||||
*/
|
||||
const connectionMutex = new Mutex();
|
||||
|
||||
async function buildConnection(overrideConf?: Partial<DataSourceOptions>) {
|
||||
const settings = getTypeORMSettings(overrideConf);
|
||||
const connection = await createConnection(settings);
|
||||
// When using Sqlite, set a busy timeout of 3s to tolerate a little
|
||||
// interference from connections made by tests. Logging doesn't show
|
||||
// any particularly slow queries, but bad luck is possible.
|
||||
// This doesn't affect when Postgres is in use. It also doesn't have
|
||||
// any impact when there is a single connection to the db, as is the
|
||||
// case when Grist is run as a single process.
|
||||
if (connection.driver.options.type === 'sqlite') {
|
||||
await connection.query('PRAGMA busy_timeout = 3000');
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
export async function getOrCreateConnection(): Promise<Connection> {
|
||||
return connectionMutex.runExclusive(async () => {
|
||||
return connectionMutex.runExclusive(async() => {
|
||||
try {
|
||||
// If multiple servers are started within the same process, we
|
||||
// share the database connection. This saves locking trouble
|
||||
// with Sqlite.
|
||||
return getConnection(getConnectionName());
|
||||
const connection = getConnection();
|
||||
return connection;
|
||||
} catch (e) {
|
||||
if (!String(e).match(/ConnectionNotFoundError/)) {
|
||||
throw e;
|
||||
}
|
||||
return buildConnection();
|
||||
const connection = await createConnection(getTypeORMSettings());
|
||||
// When using Sqlite, set a busy timeout of 3s to tolerate a little
|
||||
// interference from connections made by tests. Logging doesn't show
|
||||
// any particularly slow queries, but bad luck is possible.
|
||||
// This doesn't affect when Postgres is in use. It also doesn't have
|
||||
// any impact when there is a single connection to the db, as is the
|
||||
// case when Grist is run as a single process.
|
||||
if (connection.driver.options.type === 'sqlite') {
|
||||
await connection.query('PRAGMA busy_timeout = 3000');
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function createNewConnection(overrideConf?: Partial<DataSourceOptions>): Promise<Connection> {
|
||||
return connectionMutex.runExclusive(async () => {
|
||||
return buildConnection(overrideConf);
|
||||
});
|
||||
}
|
||||
|
||||
export async function runMigrations(connection: Connection) {
|
||||
// on SQLite, migrations fail if we don't temporarily disable foreign key
|
||||
// constraint checking. This is because for sqlite typeorm copies each
|
||||
@@ -100,9 +90,7 @@ export async function runMigrations(connection: Connection) {
|
||||
// transaction, or it has no effect.
|
||||
const sqlite = connection.driver.options.type === 'sqlite';
|
||||
if (sqlite) { await connection.query("PRAGMA foreign_keys = OFF;"); }
|
||||
await connection.transaction(async tr => {
|
||||
await tr.connection.runMigrations();
|
||||
});
|
||||
await connection.runMigrations({ transaction: "all" });
|
||||
if (sqlite) { await connection.query("PRAGMA foreign_keys = ON;"); }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user