Skip to content

Commit

Permalink
Merge pull request #2931 from Emurgo/remove-mutex-on-connector
Browse files Browse the repository at this point in the history
remove mutex on connector handler
  • Loading branch information
vsubhuman committed Aug 5, 2022
2 parents 65da2a4 + 6669a6e commit 4c58d49
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 55 deletions.
68 changes: 29 additions & 39 deletions packages/yoroi-extension/chrome/extension/background.js
Expand Up @@ -77,7 +77,6 @@ import type { lf$Database, } from 'lovefield';
import { schema } from 'lovefield';
import { copyDbToMemory, loadLovefieldDB, } from '../../app/api/ada/lib/storage/database/index';
import { migrateNoRefresh } from '../../app/api/common/migration';
import { Mutex, } from 'async-mutex';
import {
getCardanoHaskellBaseConfig,
isCardanoHaskell
Expand Down Expand Up @@ -197,13 +196,6 @@ const ports: Map<TabId, any> = new Map();

let pendingTxs: PendingTransaction[] = [];

/**
* need to make sure JS tasks run in an order where no two of them have different DB instances
* Otherwise, caching logic may make things go wrong
* TODO: this doesn't help if the Yoroi Extension or a Web Worker makes a query during this execution
*/
const dbAccessMutex = new Mutex();

/**
* Performs wallet version migration if needed
* Then calls the continuation with storage objects
Expand All @@ -214,39 +206,37 @@ const dbAccessMutex = new Mutex();
async function withDb<T>(
continuation: (lf$Database, LocalStorageApi) => Promise<T>
): Promise<T> {
return await dbAccessMutex.runExclusive(async () => {
// note: lovefield internally caches queries an optimization
// this doesn't work for us because the DB can change under our feet through the Yoroi Extension
// so instead, we create the DB, use it, then close the connection
const db = await loadLovefieldDB(schema.DataStoreType.INDEXED_DB);
let inMemoryDb: void | lf$Database = undefined;
try {
// process migration here before anything involving storage is cached
// as dApp can't easily recover from refreshing a page to wipe cache after storage migration
const localStorageApi = new LocalStorageApi();
// note: it's safe that this call modifies the DB that is shared with the main extension
// since if a migration actually needs to be processed,
// it means the extension hasn't been launched since the Yoroi version updated
// which means it's not running at the same time as the connector
await migrateNoRefresh({
localStorageApi,
persistentDb: db,
currVersion: environment.getVersion(),
})
// note: lovefield internally caches queries an optimization
// this doesn't work for us because the DB can change under our feet through the Yoroi Extension
// so instead, we create the DB, use it, then close the connection
const db = await loadLovefieldDB(schema.DataStoreType.INDEXED_DB);
let inMemoryDb: void | lf$Database = undefined;
try {
// process migration here before anything involving storage is cached
// as dApp can't easily recover from refreshing a page to wipe cache after storage migration
const localStorageApi = new LocalStorageApi();
// note: it's safe that this call modifies the DB that is shared with the main extension
// since if a migration actually needs to be processed,
// it means the extension hasn't been launched since the Yoroi version updated
// which means it's not running at the same time as the connector
await migrateNoRefresh({
localStorageApi,
persistentDb: db,
currVersion: environment.getVersion(),
})

// note: we can't close the persistent DB connection here after copying it
// since lovefield closes some shared workers causing the in-memory connection to fail as well
inMemoryDb = await copyDbToMemory(db);
// note: we can't close the persistent DB connection here after copying it
// since lovefield closes some shared workers causing the in-memory connection to fail as well
inMemoryDb = await copyDbToMemory(db);

return await continuation(inMemoryDb, localStorageApi);
} catch (e) {
Logger.error(`DB continuation call failed due to internal error: ${e}\n${e.stack}`);
throw e;
} finally {
inMemoryDb?.close();
db.close();
}
});
return await continuation(inMemoryDb, localStorageApi);
} catch (e) {
Logger.error(`DB continuation call failed due to internal error: ${e}\n${e.stack}`);
throw e;
} finally {
inMemoryDb?.close();
db.close();
}
}

async function createFetcher(
Expand Down
15 changes: 0 additions & 15 deletions packages/yoroi-extension/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/yoroi-extension/package.json
Expand Up @@ -186,7 +186,6 @@
"@mui/lab": "^5.0.0-alpha.51",
"@mui/material": "^5.0.4",
"@svgr/webpack": "5.5.0",
"async-mutex": "^0.3.1",
"axios": "0.21.1",
"bech32": "2.0.0",
"bignumber.js": "9.0.1",
Expand Down

0 comments on commit 4c58d49

Please sign in to comment.