Skip to content

Commit

Permalink
feat: add a configuration for lambda (#708)
Browse files Browse the repository at this point in the history
* feat: add a configuration for lambda

Make the number of data clients a cache client creates configurable.
6 is likely too many for lambdas as the extra latency for the first 6
calls isn't worth it in a short-lived environment.

Create a new configuration, InRegion.Lambda, for use inside lambdas.
It only creates 1 data client instead of 6.

* PR fixes

Move the lambda config out of InRegion.

Get rid of the v1 config since it isn't set in stone yet. We will make
one in the future.

Make the numClients unique in the various tests.

Add a test showing numClients can be overridden.
  • Loading branch information
nand4011 authored Aug 11, 2023
1 parent 9cef01d commit 0a5ea06
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 9 deletions.
13 changes: 4 additions & 9 deletions packages/client-sdk-nodejs/src/cache-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,10 @@ export class CacheClient extends AbstractCacheClient implements ICacheClient {
credentialProvider: props.credentialProvider,
});

// For high load, we get better performance with multiple clients. Here we
// are setting a default, hard-coded value for the number of clients to use,
// because we haven't yet designed the API for users to use to configure
// tunables:
// https://github.com/momentohq/dev-eco-issue-tracker/issues/85
// The choice of 6 as the initial value is a rough guess at a reasonable
// default for the short-term, based on load testing results captured in:
// https://github.com/momentohq/oncall-tracker/issues/186
const numClients = 6;
const numClients = props.configuration
.getTransportStrategy()
.getGrpcConfig()
.getNumClients();
const dataClients = range(numClients).map(() => new DataClient(props));
super(controlClient, dataClients);

Expand Down
29 changes: 29 additions & 0 deletions packages/client-sdk-nodejs/src/config/configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,35 @@ export class Laptop extends CacheConfiguration {
}
}

export class Lambda extends CacheConfiguration {
/**
* Provides the latest recommended configuration for a lambda environment. NOTE: this configuration may
* change in future releases to take advantage of improvements we identify for default configurations.
* @param {MomentoLoggerFactory} [loggerFactory=defaultLoggerFactory]
* @returns {CacheConfiguration}
*/
static latest(
loggerFactory: MomentoLoggerFactory = defaultLoggerFactory
): CacheConfiguration {
const deadlineMillis = 1100;
const grpcConfig: GrpcConfiguration = new StaticGrpcConfiguration({
deadlineMillis: deadlineMillis,
maxSessionMemoryMb: defaultMaxSessionMemoryMb,
numClients: 1,
});
const transportStrategy: TransportStrategy = new StaticTransportStrategy({
grpcConfiguration: grpcConfig,
maxIdleMillis: defaultMaxIdleMillis,
});
return new Lambda({
loggerFactory: loggerFactory,
retryStrategy: defaultRetryStrategy(loggerFactory),
transportStrategy: transportStrategy,
middlewares: defaultMiddlewares,
});
}
}

class InRegionDefault extends CacheConfiguration {
/**
* Provides the latest recommended configuration for a typical in-region environment. NOTE: this configuration may
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface GrpcConfigurationProps {
* more than this amount will return a ResourceExhausted error.
*/
maxSessionMemoryMb: number;

/**
* The number of internal clients a cache client will create to communicate with Momento. More of them allows
* more concurrent requests, at the cost of more open connections and the latency of setting up each client.
*/
numClients?: number;
}

/**
Expand Down Expand Up @@ -42,4 +48,17 @@ export interface GrpcConfiguration {
* @returns {GrpcConfiguration} a new GrpcConfiguration with the specified maximum memory
*/
withMaxSessionMemoryMb(maxSessionMemoryMb: number): GrpcConfiguration;

/**
* @returns {number} the number of internal clients a cache client will create to communicate with Momento. More of
* them will allow for more concurrent requests.
*/
getNumClients(): number;

/**
* Copy constructor for overriding the number of clients to create
* @param {number} numClients the number of internal clients to create
* @returns {GrpcConfiguration} a new GrpcConfiguration with the specified number of clients
*/
withNumClients(numClients: number): GrpcConfiguration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,16 @@ export interface TransportStrategyProps {
export class StaticGrpcConfiguration implements GrpcConfiguration {
private readonly deadlineMillis: number;
private readonly maxSessionMemoryMb: number;
private readonly numClients: number;
constructor(props: GrpcConfigurationProps) {
this.deadlineMillis = props.deadlineMillis;
this.maxSessionMemoryMb = props.maxSessionMemoryMb;
if (props.numClients !== undefined && props.numClients !== null) {
this.numClients = props.numClients;
} else {
// This is the previously hardcoded value and a safe default for most environments.
this.numClients = 6;
}
}

getDeadlineMillis(): number {
Expand All @@ -78,13 +85,27 @@ export class StaticGrpcConfiguration implements GrpcConfiguration {
return new StaticGrpcConfiguration({
deadlineMillis: deadlineMillis,
maxSessionMemoryMb: this.maxSessionMemoryMb,
numClients: this.numClients,
});
}

withMaxSessionMemoryMb(maxSessionMemoryMb: number): StaticGrpcConfiguration {
return new StaticGrpcConfiguration({
deadlineMillis: this.deadlineMillis,
maxSessionMemoryMb: maxSessionMemoryMb,
numClients: this.numClients,
});
}

getNumClients(): number {
return this.numClients;
}

withNumClients(numClients: number): GrpcConfiguration {
return new StaticGrpcConfiguration({
deadlineMillis: this.deadlineMillis,
maxSessionMemoryMb: this.maxSessionMemoryMb,
numClients: numClients,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('configuration.ts', () => {
const testGrpcConfiguration = new StaticGrpcConfiguration({
deadlineMillis: 90210,
maxSessionMemoryMb: 90211,
numClients: 2,
});
const testMaxIdleMillis = 90212;
const testTransportStrategy = new StaticTransportStrategy({
Expand Down Expand Up @@ -52,6 +53,7 @@ describe('configuration.ts', () => {
const newGrpcConfiguration = new StaticGrpcConfiguration({
deadlineMillis: 5000,
maxSessionMemoryMb: 5001,
numClients: 3,
});
const newMaxIdleMillis = 5002;
const newTransportStrategy = new StaticTransportStrategy({
Expand All @@ -77,6 +79,7 @@ describe('configuration.ts', () => {
grpcConfiguration: new StaticGrpcConfiguration({
deadlineMillis: newClientTimeoutMillis,
maxSessionMemoryMb: testGrpcConfiguration.getMaxSessionMemoryMb(),
numClients: testGrpcConfiguration.getNumClients(),
}),
maxIdleMillis: testMaxIdleMillis,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
describe('StaticGrpcConfiguration', () => {
const testDeadlineMillis = 90210;
const testMaxSessionMemoryMb = 90211;
const testNumClients = 4;
const testGrpcConfiguration = new StaticGrpcConfiguration({
deadlineMillis: testDeadlineMillis,
maxSessionMemoryMb: testMaxSessionMemoryMb,
numClients: testNumClients,
});

it('should support overriding deadline millis', () => {
Expand All @@ -34,14 +36,26 @@ describe('StaticGrpcConfiguration', () => {
newMaxSessionMemory
);
});

it('should support overriding num clients', () => {
const newNumClients = 9;
const configWithNewDeadline =
testGrpcConfiguration.withNumClients(newNumClients);
expect(configWithNewDeadline.getNumClients()).toEqual(newNumClients);
expect(configWithNewDeadline.getMaxSessionMemoryMb()).toEqual(
testMaxSessionMemoryMb
);
});
});

describe('StaticTransportStrategy', () => {
const testDeadlineMillis = 90210;
const testMaxSessionMemoryMb = 90211;
const testNumClients = 5;
const testGrpcConfiguration = new StaticGrpcConfiguration({
deadlineMillis: testDeadlineMillis,
maxSessionMemoryMb: testMaxSessionMemoryMb,
numClients: testNumClients,
});

const testMaxIdleMillis = 90212;
Expand All @@ -56,6 +70,7 @@ describe('StaticTransportStrategy', () => {
const newGrpcConfig = new StaticGrpcConfiguration({
deadlineMillis: newDeadlineMillis,
maxSessionMemoryMb: newMaxSessionMemoryMb,
numClients: testNumClients,
});
const strategyWithNewGrpcConfig =
testTransportStrategy.withGrpcConfig(newGrpcConfig);
Expand All @@ -82,6 +97,7 @@ describe('StaticTransportStrategy', () => {
const expectedGrpcConfig = new StaticGrpcConfiguration({
deadlineMillis: newClientTimeout,
maxSessionMemoryMb: testMaxSessionMemoryMb,
numClients: testNumClients,
});
const strategyWithNewClientTimeout =
testTransportStrategy.withClientTimeoutMillis(newClientTimeout);
Expand Down

0 comments on commit 0a5ea06

Please sign in to comment.