Page MenuHomePhorge

D7568.1767110463.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D7568.1767110463.diff

diff --git a/keyserver/src/updaters/olm-account-updater.js b/keyserver/src/updaters/olm-account-updater.js
new file mode 100644
--- /dev/null
+++ b/keyserver/src/updaters/olm-account-updater.js
@@ -0,0 +1,112 @@
+// @flow
+
+import type { Account as OlmAccount } from '@commapp/olm';
+
+import { ServerError } from 'lib/utils/errors.js';
+import sleep from 'lib/utils/sleep.js';
+
+import { SQL, dbQuery } from '../database/database.js';
+import { unpickleOlmAccount } from '../utils/olm-utils.js';
+
+const maxOlmAccountUpdateRetriesCount = 5;
+const olmAccountUpdateRetryDelay = 200;
+
+async function fetchCallUpdateOlmAccount<T>(
+ olmAccountType: 'content' | 'notifications',
+ callback: (account: OlmAccount) => Promise<T>,
+): Promise<T> {
+ const isContent = olmAccountType === 'content';
+ let retriesLeft = maxOlmAccountUpdateRetriesCount;
+
+ while (retriesLeft > 0) {
+ const [olmAccountResult] = await dbQuery(
+ SQL`
+ SELECT version, pickling_key, pickled_olm_account
+ FROM olm_accounts
+ WHERE is_content = ${isContent}
+ `,
+ );
+
+ if (olmAccountResult.length === 0) {
+ throw new ServerError('missing_olm_account');
+ }
+
+ const [
+ {
+ version,
+ pickling_key: picklingKey,
+ pickled_olm_account: pickledAccount,
+ },
+ ] = olmAccountResult;
+
+ const account = await unpickleOlmAccount({
+ picklingKey,
+ pickledAccount,
+ });
+ const result = await callback(account);
+ const updatedAccount = account.pickle(picklingKey);
+
+ const [transactionResult] = await dbQuery(
+ SQL`
+ START TRANSACTION;
+
+ SELECT version INTO @currentVersion
+ FROM olm_accounts
+ WHERE is_content = ${isContent}
+ FOR UPDATE;
+
+ UPDATE olm_accounts
+ SET
+ pickled_olm_account = ${updatedAccount},
+ version = ${version} + 1
+ WHERE version = ${version} AND is_content = ${isContent};
+
+ COMMIT;
+
+ SELECT @currentVersion AS versionOnUpdateAttempt;
+ `,
+ { multipleStatements: true },
+ );
+ const selectResult = transactionResult.pop();
+ const [{ versionOnUpdateAttempt }] = selectResult;
+
+ if (version === versionOnUpdateAttempt) {
+ return result;
+ }
+
+ retriesLeft = retriesLeft - 1;
+ await sleep(olmAccountUpdateRetryDelay);
+ }
+
+ throw new ServerError('max_olm_account_update_retry_exceeded');
+}
+
+async function fetchOlmAccount(
+ olmAccountType: 'content' | 'notifications',
+): Promise<{
+ account: OlmAccount,
+ picklingKey: string,
+}> {
+ const isContent = olmAccountType === 'content';
+ const [olmAccountResult] = await dbQuery(
+ SQL`
+ SELECT pickling_key, pickled_olm_account
+ FROM olm_accounts
+ WHERE is_content = ${isContent}
+ `,
+ );
+ if (olmAccountResult.length === 0) {
+ throw new ServerError('missing_olm_account');
+ }
+ const picklingKey = olmAccountResult[0].pickling_key;
+ const pickledAccount = olmAccountResult[0].pickled_olm_account;
+
+ const account = await unpickleOlmAccount({
+ picklingKey,
+ pickledAccount,
+ });
+
+ return { account, picklingKey };
+}
+
+export { fetchCallUpdateOlmAccount, fetchOlmAccount };

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 30, 4:01 PM (11 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5867524
Default Alt Text
D7568.1767110463.diff (3 KB)

Event Timeline