Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max buffer size #37

Merged
merged 2 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions packages/client-http/src/ApplyManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('ApplyManager', () => {
beforeEach(() => {
instanceUnderTest = new ApplyManager({
timeout: 100,
maxBufferSize: 3,
client: mockClient,
});
resolveMock.mockResolvedValue({});
Expand Down Expand Up @@ -99,4 +100,31 @@ describe('ApplyManager', () => {
'some-token2',
);
});

it('should send apply event when the max buffer size is met, and flush the apply events', async () => {
const applyTime = new Date().toISOString();

instanceUnderTest.apply('some-token', 'apply-test');
instanceUnderTest.apply('some-token', 'apply-test1');
instanceUnderTest.apply('some-token', 'apply-test2');

expect(resolveMock).toHaveBeenCalledTimes(1);
expect(resolveMock).toHaveBeenCalledWith(
[
{
flag: 'flags/apply-test',
applyTime: applyTime,
},
{
flag: 'flags/apply-test1',
applyTime: applyTime,
},
{
flag: 'flags/apply-test2',
applyTime: applyTime,
},
],
'some-token',
);
});
});
10 changes: 9 additions & 1 deletion packages/client-http/src/ApplyManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { ConfidenceClient, AppliedFlag } from './client';

export interface ApplyManagerOptions {
timeout: number;
maxBufferSize: number;
client: ConfidenceClient;
}

export class ApplyManager {
private resolveTokenPending: Map<string, AppliedFlag[]> = new Map();
private resolveTokenSeen: Map<string, Set<string>> = new Map();
private readonly timeout: number;
private readonly maxBufferSize: number;
private client: ConfidenceClient;
private flushTimeout: ReturnType<typeof setTimeout> | null = null;

constructor(options: ApplyManagerOptions) {
this.timeout = options.timeout;
this.maxBufferSize = options.maxBufferSize;
this.client = options.client;
}

Expand Down Expand Up @@ -61,6 +64,11 @@ export class ApplyManager {
if (this.flushTimeout) {
clearTimeout(this.flushTimeout);
}
this.flushTimeout = setTimeout(() => this.flush(), this.timeout);

if ((this.resolveTokenPending.get(resolveToken)?.length || 0) >= this.maxBufferSize) {
this.flush();
} else {
this.flushTimeout = setTimeout(() => this.flush(), this.timeout);
Billlynch marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import equal from 'fast-deep-equal';
import { ApplyManager, ConfidenceClient, Configuration, ResolveContext } from '@spotify-confidence/client-http';

const APPLY_TIMEOUT = 250;
const MAX_APPLY_BUFFER_SIZE = 20;
Billlynch marked this conversation as resolved.
Show resolved Hide resolved

export interface ConfidenceWebProviderOptions {
apply: 'access' | 'backend';
Expand All @@ -35,7 +36,11 @@ export class ConfidenceWebProvider implements Provider {
constructor(client: ConfidenceClient, options: ConfidenceWebProviderOptions) {
this.client = client;
if (options.apply !== 'backend') {
this.applyManager = new ApplyManager({ client: this.client, timeout: APPLY_TIMEOUT });
this.applyManager = new ApplyManager({
client: this.client,
timeout: APPLY_TIMEOUT,
maxBufferSize: MAX_APPLY_BUFFER_SIZE,
});
}
}

Expand Down
Loading