diff --git a/keyserver/src/cron/cron.js b/keyserver/src/cron/cron.js --- a/keyserver/src/cron/cron.js +++ b/keyserver/src/cron/cron.js @@ -1,9 +1,12 @@ // @flow import type { Account as OlmAccount } from '@commapp/olm'; +import olm from '@commapp/olm'; import cluster from 'cluster'; import schedule from 'node-schedule'; +import { verifyMemoryUsage } from 'lib/utils/olm-memory-utils.js'; + import { backupDB } from './backups.js'; import { createDailyUpdatesThread } from './daily-updates.js'; import { postMetrics } from './metrics.js'; @@ -125,6 +128,13 @@ } }, ); + schedule.scheduleJob( + '0,15,30,45 * * * *', // every 15 minutes + async () => { + await olm.init(); + verifyMemoryUsage('cronjob'); + }, + ); } if (isPrimaryNode || isAuxiliaryNode) { schedule.scheduleJob( diff --git a/lib/utils/olm-memory-utils.js b/lib/utils/olm-memory-utils.js new file mode 100644 --- /dev/null +++ b/lib/utils/olm-memory-utils.js @@ -0,0 +1,38 @@ +// @flow + +import olm from '@commapp/olm'; + +let olmTotalMemory = null, + olmUsedMemory = null; + +function verifyMemoryUsage(method: string) { + try { + if (olmTotalMemory === null && olmUsedMemory === null) { + olmTotalMemory = olm.get_total_memory(); + olmUsedMemory = olm.get_used_memory(); + return; + } + + const currentTotalMemory = olm.get_total_memory(); + if (currentTotalMemory !== olmTotalMemory) { + console.error( + `Olm's total memory changed from ${olmTotalMemory ?? 0} ` + + `to ${currentTotalMemory} after executing ${method} method`, + ); + olmTotalMemory = currentTotalMemory; + } + + const currentUsedMemory = olm.get_used_memory(); + if (currentUsedMemory !== olmUsedMemory) { + console.error( + `Olm's used memory changed from ${olmUsedMemory ?? 0} ` + + `to ${currentUsedMemory} after executing ${method} method`, + ); + olmUsedMemory = currentUsedMemory; + } + } catch (e) { + console.error('Encountered error while trying log Olm memory', e); + } +} + +export { verifyMemoryUsage }; diff --git a/web/shared-worker/worker/worker-crypto.js b/web/shared-worker/worker/worker-crypto.js --- a/web/shared-worker/worker/worker-crypto.js +++ b/web/shared-worker/worker/worker-crypto.js @@ -24,6 +24,7 @@ import type { InboundP2PMessage } from 'lib/types/sqlite-types.js'; import { getMessageForException } from 'lib/utils/errors.js'; import { entries } from 'lib/utils/objects.js'; +import { verifyMemoryUsage } from 'lib/utils/olm-memory-utils.js'; import { getOlmUtility } from 'lib/utils/olm-utility.js'; import { retrieveAccountKeysSet, @@ -388,6 +389,7 @@ message.olmWasmPath, message.initialCryptoStore, ); + verifyMemoryUsage('INITIALIZE_CRYPTO_ACCOUNT'); } else if (message.type === workerRequestMessageTypes.CALL_OLM_API_METHOD) { const method: (...$ReadOnlyArray<mixed>) => mixed = (olmAPI[ message.method @@ -395,6 +397,7 @@ // Flow doesn't allow us to bind the (stringified) method name with // the argument types so we need to pass the args as mixed. const result = await method(...message.args); + verifyMemoryUsage(message.method); return { type: workerResponseMessageTypes.CALL_OLM_API_METHOD, result,