fix: onboarding job runner and min snode count for broken testnet

pull/3178/head
Audric Ackermann 8 months ago
parent e9a03bdfba
commit 7a3a80825b
No known key found for this signature in database

@ -39,6 +39,7 @@ async function getSessionIDForOnsName(onsNameCase: string) {
if (isTestNet()) { if (isTestNet()) {
window.log.info('OnsResolve response are not registered to anything on testnet'); window.log.info('OnsResolve response are not registered to anything on testnet');
throw new Error('OnsResolve response are not registered to anything on testnet');
} }
const onsResolveRequests = buildOnsResolveRequests(base64EncodedNameHash); const onsResolveRequests = buildOnsResolveRequests(base64EncodedNameHash);

@ -10,6 +10,7 @@ import { ed25519Str } from '../../utils/String';
import { SeedNodeAPI } from '../seed_node_api'; import { SeedNodeAPI } from '../seed_node_api';
import { ServiceNodesList } from './getServiceNodesList'; import { ServiceNodesList } from './getServiceNodesList';
import { requestSnodesForPubkeyFromNetwork } from './getSwarmFor'; import { requestSnodesForPubkeyFromNetwork } from './getSwarmFor';
import { minimumGuardCount, ONION_REQUEST_HOPS } from '../../onions/onionPath';
/** /**
* If we get less than this snode in a swarm, we fetch new snodes for this pubkey * If we get less than this snode in a swarm, we fetch new snodes for this pubkey
@ -20,7 +21,7 @@ const minSwarmSnodeCount = 3;
* If we get less than minSnodePoolCount we consider that we need to fetch the new snode pool from a seed node * If we get less than minSnodePoolCount we consider that we need to fetch the new snode pool from a seed node
* and not from those snodes. * and not from those snodes.
*/ */
export const minSnodePoolCount = 12; export const minSnodePoolCount = minimumGuardCount * (ONION_REQUEST_HOPS + 1) * 2;
/** /**
* If we get less than this amount of snodes (24), lets try to get an updated list from those while we can * If we get less than this amount of snodes (24), lets try to get an updated list from those while we can

@ -1,5 +1,5 @@
import moment from 'moment'; import moment from 'moment';
import { isCI, isDevProd } from '../../shared/env_vars'; import { isDevProd } from '../../shared/env_vars';
import { LocalizerKeys } from '../../types/LocalizerKeys'; import { LocalizerKeys } from '../../types/LocalizerKeys';
type TimerOptionsEntry = { name: string; value: number }; type TimerOptionsEntry = { name: string; value: number };
@ -67,7 +67,7 @@ const VALUES: Array<number> = timerOptionsDurations.map(t => {
}); });
const filterOutDebugValues = (option: number) => { const filterOutDebugValues = (option: number) => {
return isDevProd() || isCI() || option > 60; // when not a dev build nor on CI, filter out options with less than 60s return isDevProd() || option > 60; // when not a dev build, filter out options with less than 60s
}; };
const DELETE_AFTER_READ = VALUES.filter(option => { const DELETE_AFTER_READ = VALUES.filter(option => {

@ -18,9 +18,9 @@ import { UserUtils } from '../utils';
import { allowOnlyOneAtATime } from '../utils/Promise'; import { allowOnlyOneAtATime } from '../utils/Promise';
import { ed25519Str } from '../utils/String'; import { ed25519Str } from '../utils/String';
const desiredGuardCount = 3; export const desiredGuardCount = 2;
const minimumGuardCount = 2; export const minimumGuardCount = 1;
const ONION_REQUEST_HOPS = 3; export const ONION_REQUEST_HOPS = 3;
export function getOnionPathMinTimeout() { export function getOnionPathMinTimeout() {
return DURATION.SECONDS; return DURATION.SECONDS;
@ -31,9 +31,7 @@ export let onionPaths: Array<Array<Snode>> = [];
/** /**
* Used for testing only * Used for testing only
* @returns a copy of the onion path currently used by the app. * @returns a copy of the onion path currently used by the app.
*
*/ */
export const TEST_getTestOnionPath = () => { export const TEST_getTestOnionPath = () => {
return _.cloneDeep(onionPaths); return _.cloneDeep(onionPaths);
}; };

@ -108,7 +108,19 @@ export abstract class PersistedJob<T extends PersistedJobData> {
public async runJob() { public async runJob() {
if (!this.runningPromise) { if (!this.runningPromise) {
this.runningPromise = this.run(); // eslint-disable-next-line more/no-then
this.runningPromise = this.run()
.then(jobResult => {
this.runningPromise = null;
return jobResult;
})
.catch(e => {
window.log.warn(
'runJob() threw. this cannot happen, but rehtrowing as this should be handled in each jobs run()',
e
);
throw e;
});
} }
return this.runningPromise; return this.runningPromise;
} }

@ -23,8 +23,8 @@ import {
} from '../PersistedJob'; } from '../PersistedJob';
import { DURATION } from '../../../constants'; import { DURATION } from '../../../constants';
const defaultMsBetweenRetries = 15000; // a long time between retries, to avoid running multiple jobs at the same time, when one was postponed at the same time as one already planned (5s) const defaultMsBetweenRetries = 5000; // a long time between retries, to avoid running multiple jobs at the same time, when one was postponed at the same time as one already planned (5s)
const defaultMaxAttempts = 2; const defaultMaxAttempts = 4;
/** /**
* We want to run each of those jobs at least 3seconds apart. * We want to run each of those jobs at least 3seconds apart.
@ -56,8 +56,6 @@ async function retrieveSingleDestinationChanges(
return { messages: outgoingConfResults, allOldHashes: compactedHashes }; return { messages: outgoingConfResults, allOldHashes: compactedHashes };
} }
let firstJobStart: number | undefined;
/** /**
* This function is run once we get the results from the multiple batch-send. * This function is run once we get the results from the multiple batch-send.
*/ */
@ -194,18 +192,6 @@ class ConfigurationSyncJob extends PersistedJob<ConfigurationSyncPersistedData>
return RunJobResult.Success; return RunJobResult.Success;
} }
const singleDestChanges = await retrieveSingleDestinationChanges(thisJobDestination); const singleDestChanges = await retrieveSingleDestinationChanges(thisJobDestination);
if (!firstJobStart) {
firstJobStart = Date.now();
}
// not ideal, but we need to postpone the first sync job to after we've handled the incoming config messages
// otherwise we are pushing an incomplete config to the network, which will need to be merged and that action alone
// will bump the timestamp of the config.
// We rely on the timestamp of configs to know when to drop messages that would unhide/unremove a conversation.
// The whole thing is a dirty fix of a dirty fix, that will **eventually** need proper fixing
if (Date.now() - firstJobStart <= 20 * DURATION.SECONDS) {
return RunJobResult.RetryJobIfPossible;
}
// If there are no pending changes then the job can just complete (next time something // If there are no pending changes then the job can just complete (next time something
// is updated we want to try and run immediately so don't scuedule another run in this case) // is updated we want to try and run immediately so don't scuedule another run in this case)
@ -332,18 +318,18 @@ async function queueNewJobIfNeeded() {
!lastRunConfigSyncJobTimestamp || !lastRunConfigSyncJobTimestamp ||
lastRunConfigSyncJobTimestamp < Date.now() - defaultMsBetweenRetries lastRunConfigSyncJobTimestamp < Date.now() - defaultMsBetweenRetries
) { ) {
// window.log.debug('Scheduling ConfSyncJob: ASAP'); // Note: we postpone by 3s for two reasons:
// we postpone by 1000ms to make sure whoever is adding this job is done with what is needs to do first // - to make sure whoever is adding this job is done with what is needs to do first
// - to allow a just created device to process incoming config messages before pushing a new one
// this call will make sure that there is only one configuration sync job at all times // this call will make sure that there is only one configuration sync job at all times
await runners.configurationSyncRunner.addJob( await runners.configurationSyncRunner.addJob(
new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() + 1000 }) new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() + 3 * DURATION.SECONDS })
); );
} else { } else {
// if we did run at t=100, and it is currently t=110, the difference is 10 // if we did run at t=100, and it is currently t=110, the difference is 10
const diff = Math.max(Date.now() - lastRunConfigSyncJobTimestamp, 0); const diff = Math.max(Date.now() - lastRunConfigSyncJobTimestamp, 0);
// but we want to run every 30, so what we need is actually `30-10` from now = 20 // but we want to run every 30, so what we need is actually `30-10` from now = 20
const leftBeforeNextTick = Math.max(defaultMsBetweenRetries - diff, 1000); const leftBeforeNextTick = Math.max(defaultMsBetweenRetries - diff, DURATION.SECONDS);
// window.log.debug('Scheduling ConfSyncJob: LATER');
await runners.configurationSyncRunner.addJob( await runners.configurationSyncRunner.addJob(
new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() + leftBeforeNextTick }) new ConfigurationSyncJob({ nextAttemptTimestamp: Date.now() + leftBeforeNextTick })

@ -5,19 +5,16 @@ function envAppInstanceIncludes(prefix: string) {
return !!process.env.NODE_APP_INSTANCE.includes(prefix); return !!process.env.NODE_APP_INSTANCE.includes(prefix);
} }
export function isCI() {
// this is set by session-playwright to run a build on CI
return !!process.env.CI;
}
export function isDevProd() { export function isDevProd() {
return envAppInstanceIncludes('devprod'); return envAppInstanceIncludes('devprod');
} }
export function isTestNet() { export function isTestNet() {
return envAppInstanceIncludes('testnet') || isCI(); // when running on CI, we always want to use testnet return envAppInstanceIncludes('testnet');
} }
export function isTestIntegration() { export function isTestIntegration() {
return envAppInstanceIncludes('test-integration') || isCI(); // when running on CI, we always want the 'test-integration' behavior return envAppInstanceIncludes('test-integration');
} }

Loading…
Cancel
Save