From 03406001b741a3ed3930d0a2f794a57f2e1aba3b Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 15 Oct 2024 21:24:14 +0200 Subject: [PATCH] feat: set slower backoff for current context Signed-off-by: Philippe Martin --- .../src/plugin/kubernetes/backoff.spec.ts | 8 ++-- .../main/src/plugin/kubernetes/backoff.ts | 3 +- .../plugin/kubernetes/contexts-constants.ts | 6 +++ .../src/plugin/kubernetes/contexts-manager.ts | 41 ++++++++++++++----- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/packages/main/src/plugin/kubernetes/backoff.spec.ts b/packages/main/src/plugin/kubernetes/backoff.spec.ts index fb9650358391d..6b967fea9dc42 100644 --- a/packages/main/src/plugin/kubernetes/backoff.spec.ts +++ b/packages/main/src/plugin/kubernetes/backoff.spec.ts @@ -21,7 +21,7 @@ import { expect, test } from 'vitest'; import { Backoff } from './backoff.js'; test('backoff increment and limit without jitter', () => { - const backoff = new Backoff(100, 500, 0); + const backoff = new Backoff(100, 2, 500, 0); expect(backoff.get()).toEqual(100); expect(backoff.get()).toEqual(200); expect(backoff.get()).toEqual(400); @@ -32,7 +32,7 @@ test('backoff increment and limit without jitter', () => { test('backoff with jitter', () => { let jitterFound = false; let base = 100; - let backoff: Backoff = new Backoff(base, 500, 10); + let backoff: Backoff = new Backoff(base, 2, 500, 10); // run several tests, as we cannot rely on a single one due to the random nature for (let i = 0; i < 10; i++) { const value = backoff.get(); @@ -40,7 +40,7 @@ test('backoff with jitter', () => { expect(value).toBeLessThan(base * 1.1); if (value === base) { // this can happen, try again - backoff = new Backoff(base, 500, 10); + backoff = new Backoff(base, 2, 500, 10); continue; } jitterFound = true; @@ -54,7 +54,7 @@ test('backoff with jitter', () => { }); test('backoff reset', () => { - const backoff = new Backoff(100, 500, 0); + const backoff = new Backoff(100, 2, 500, 0); expect(backoff.get()).toBe(100); expect(backoff.get()).toBe(200); expect(backoff.get()).toBe(400); diff --git a/packages/main/src/plugin/kubernetes/backoff.ts b/packages/main/src/plugin/kubernetes/backoff.ts index 7dc0d86a22556..be9f0bf09df48 100644 --- a/packages/main/src/plugin/kubernetes/backoff.ts +++ b/packages/main/src/plugin/kubernetes/backoff.ts @@ -20,6 +20,7 @@ export class Backoff { private readonly initial: number; constructor( public value: number, + public multiplier: number, private readonly max: number, private readonly jitter: number, ) { @@ -29,7 +30,7 @@ export class Backoff { get(): number { const current = this.value; if (this.value < this.max) { - this.value *= 2; + this.value *= this.multiplier; this.value += this.getJitter(); } return current; diff --git a/packages/main/src/plugin/kubernetes/contexts-constants.ts b/packages/main/src/plugin/kubernetes/contexts-constants.ts index fcef187ede9a7..cd3b63f972461 100644 --- a/packages/main/src/plugin/kubernetes/contexts-constants.ts +++ b/packages/main/src/plugin/kubernetes/contexts-constants.ts @@ -21,8 +21,14 @@ export const connectTimeout = 1000; // initial delay between two connection attempts export const backoffInitialValue = 1000; +// the backoff will be multiplied by this number every time +export const backoffMultiplier = 2.0; +// the backoff will be multiplied by this number every time for current context +export const backoffMultiplierCurrentContext = 1.2; // maximum delay between two connection attempts export const backoffLimit = 60_000; +// maximum delay between two connection attempts for current context +export const backoffLimitCurrentContext = 10_000; // jitter to add to the delay between two connection attempts export const backoffJitter = 300; // the time to wait for any update on the data to dispatch before to send it diff --git a/packages/main/src/plugin/kubernetes/contexts-manager.ts b/packages/main/src/plugin/kubernetes/contexts-manager.ts index 608808d24d5e5..364268b2e4f97 100644 --- a/packages/main/src/plugin/kubernetes/contexts-manager.ts +++ b/packages/main/src/plugin/kubernetes/contexts-manager.ts @@ -58,7 +58,15 @@ import type { V1Route } from '/@api/openshift-types.js'; import type { ApiSenderType } from '../api.js'; import { Backoff } from './backoff.js'; -import { backoffInitialValue, backoffJitter, backoffLimit, connectTimeout } from './contexts-constants.js'; +import { + backoffInitialValue, + backoffJitter, + backoffLimit, + backoffLimitCurrentContext, + backoffMultiplier, + backoffMultiplierCurrentContext, + connectTimeout, +} from './contexts-constants.js'; import { ContextsInformersRegistry } from './contexts-informers-registry.js'; import type { ContextInternalState } from './contexts-states-registry.js'; import { ContextsStatesRegistry, dispatchAllResources, isSecondaryResourceName } from './contexts-states-registry.js'; @@ -379,7 +387,7 @@ export class ContextsManager { checkReachable: true, resource: 'pods', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -447,7 +455,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'deployments', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -494,7 +502,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'configmaps', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -536,7 +544,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'secrets', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -581,7 +589,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'persistentvolumeclaims', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -625,7 +633,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'nodes', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -665,7 +673,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'services', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -705,7 +713,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'ingresses', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -751,7 +759,7 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { resource: 'routes', timer: timer, - backoff: new Backoff(backoffInitialValue, backoffLimit, backoffJitter), + backoff: this.getBackoffForContext(context.name), connectionDelay: connectionDelay, onAdd: obj => { this.states.setStateAndDispatch(context.name, { @@ -968,4 +976,17 @@ export class ContextsManager { clearTimeout(timer); } } + + private getBackoffForContext(contextName: string): Backoff { + if (contextName === this.kubeConfig.currentContext) { + return new Backoff( + backoffInitialValue, + backoffMultiplierCurrentContext, + backoffLimitCurrentContext, + backoffJitter, + ); + } else { + return new Backoff(backoffInitialValue, backoffMultiplier, backoffLimit, backoffJitter); + } + } }