Skip to content

Commit

Permalink
Namespace Redis Connections (#349)
Browse files Browse the repository at this point in the history
We want to allow for all services to use the same Redis.

- Make sure each service has a different Redis connection namespace for
non-bull redis connections.
- Make sure all Bull Queues have unique names via prefixing the queues
- Note this as a BREAKING change

Services:

- [x] Graph Service
- [x] Account Service
- [x] Content Publishing Service
- [x] Content Watcher Service

Closes #189
  • Loading branch information
mattheworris authored Aug 8, 2024
1 parent 669e73a commit c4372bf
Show file tree
Hide file tree
Showing 18 changed files with 41 additions and 4 deletions.
1 change: 1 addition & 0 deletions services/account/ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This application recognizes the following environment variables:
| `API_PORT` | HTTP port that the application listens on | 1025 - 65535 | | 3000 |
| `BLOCKCHAIN_SCAN_INTERVAL_SECONDS` | How many seconds to delay between successive scans of the chain for new content (after end of chain is reached) | > 0 | | 12 |
| `TRUST_UNFINALIZED_BLOCKS` | Whether to examine blocks that have not been finalized when tracking extrinsic completion | boolean | | false |
| `CACHE_KEY_PREFIX` | Prefix to use for Redis cache keys | string | | account: |
| `CAPACITY_LIMIT` | Maximum amount of provider capacity this app is allowed to use (per epoch) type: 'percentage' 'amount' value: number (may be percentage, ie '80', or absolute amount of capacity) | JSON [(example)](./env.template) | Y | |
| `FREQUENCY_URL` | Blockchain node address | http(s): or ws(s): URL | Y | |
| `FREQUENCY_HTTP_URL` | Blockchain node address resolvable from the client browser | http(s): URL | Y | |
Expand Down
1 change: 1 addition & 0 deletions services/account/apps/api/src/api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { ApiService, AccountsService, HandlesService, DelegationService, KeysSer
config: [
{
url: configService.redisUrl.toString(),
keyPrefix: configService.cacheKeyPrefix,
maxRetriesPerRequest: null,
onClientCreated(client) {
redisEventsToEventEmitter(client, eventEmitter);
Expand Down
1 change: 1 addition & 0 deletions services/account/apps/worker/src/worker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { TransactionPublisherModule } from './transaction_publisher/publisher.mo
config: [
{
url: configService.redisUrl.toString(),
keyPrefix: configService.cacheKeyPrefix,
maxRetriesPerRequest: null,
onClientCreated(client) {
redisEventsToEventEmitter(client, eventEmitter);
Expand Down
3 changes: 3 additions & 0 deletions services/account/env.template
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ SIWF_DOMAIN=localhost

# Enable debug mode for development
DEBUG=true

# Prefix to use for Redis cache keys
CACHE_KEY_PREFIX=account:
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe('AccountSericeConfig', () => {
HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: undefined,
HEALTH_CHECK_MAX_RETRIES: undefined,
CAPACITY_LIMIT: undefined,
CACHE_KEY_PREFIX: undefined,
};

beforeAll(() => {
Expand Down Expand Up @@ -226,5 +227,9 @@ describe('AccountSericeConfig', () => {
it('should get capacity limit', () => {
expect(accountServiceConfig.capacityLimit).toStrictEqual(JSON.parse(ALL_ENV.CAPACITY_LIMIT!));
});

it('should get cache key prefix', () => {
expect(accountServiceConfig.cacheKeyPrefix).toStrictEqual(ALL_ENV.CACHE_KEY_PREFIX?.toString());
});
});
});
5 changes: 5 additions & 0 deletions services/account/libs/common/src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ConfigEnvironmentVariables {
HEALTH_CHECK_MAX_RETRY_INTERVAL_SECONDS: number;
HEALTH_CHECK_MAX_RETRIES: number;
CAPACITY_LIMIT: string;
CACHE_KEY_PREFIX: string;
}

/// Config service to get global app and provider-specific config values.
Expand All @@ -32,6 +33,10 @@ export class ConfigService {
this.capacityLimitObj = JSON.parse(this.nestConfigService.get<string>('CAPACITY_LIMIT')!);
}

public get cacheKeyPrefix(): string {
return this.nestConfigService.get('CACHE_KEY_PREFIX')!;
}

public get blockchainScanIntervalSeconds(): number {
return this.nestConfigService.get<number>('BLOCKCHAIN_SCAN_INTERVAL_SECONDS') ?? 12;
}
Expand Down
1 change: 1 addition & 0 deletions services/account/libs/common/src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ConfigModuleOptions } from '@nestjs/config';
export const configModuleOptions: ConfigModuleOptions = {
isGlobal: true,
validationSchema: Joi.object({
CACHE_KEY_PREFIX: Joi.string().default('account:'),
BLOCKCHAIN_SCAN_INTERVAL_SECONDS: Joi.number().min(1).default(12),
TRUST_UNFINALIZED_BLOCKS: Joi.bool().default(false),
REDIS_URL: Joi.string().uri().required(),
Expand Down
1 change: 1 addition & 0 deletions services/account/libs/common/src/queues/queues.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class QueueModule {
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
connection: new Redis(configService.redisUrl.toString(), redisOptions || {}),
prefix: `${configService.cacheKeyPrefix}:bull`,
}),
inject: [ConfigService],
}),
Expand Down
1 change: 1 addition & 0 deletions services/content-publishing/ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This application recognizes the following environment variables:
| Name | Description | Range/Type | Required? | Default |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------: | :----------: | :-----: |
| `API_PORT` | HTTP port that the application listens on | 1025 - 65535 | | 3000 |
| `CACHE_KEY_PREFIX` | Prefix to use for Redis cache keys | string | | content-publishing-service: |
| `CAPACITY_LIMIT` | Maximum amount of provider capacity this app is allowed to use (per epoch) type: 'percentage' 'amount' value: number (may be percentage, ie '80', or absolute amount of capacity) | JSON [(example)](./env.template) | Y | |
| `FREQUENCY_URL` | Blockchain node address | http(s): or ws(s): URL | Y | |
| `PROVIDER_ACCOUNT_SEED_PHRASE` | Seed phrase for provider MSA control key | string | Y | |
Expand Down
5 changes: 4 additions & 1 deletion services/content-publishing/apps/api/src/api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import { AssetControllerV1, ContentControllerV1, ProfileControllerV1 } from './c
{
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
config: [{ url: configService.redisUrl.toString() }],
config: [{
url: configService.redisUrl.toString(),
keyPrefix: configService.cacheKeyPrefix,
}],
}),
inject: [ConfigService],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { RequestProcessorModule } from './request_processor/request.processor.mo
{
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
config: [{ url: configService.redisUrl.toString() }],
config: [{ url: configService.redisUrl.toString(), keyPrefix: configService.cacheKeyPrefix }],
}),
inject: [ConfigService],
},
Expand Down
3 changes: 3 additions & 0 deletions services/content-publishing/env.template
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ BATCH_MAX_COUNT=1000
# Base delay in seconds used for exponential backoff while waiting for
# uploaded assets to be verified available before publishing a content notice.
ASSET_UPLOAD_VERIFICATION_DELAY_SECONDS=5

# Prefix to use for Redis cache keys
CACHE_KEY_PREFIX=content-publishing-service:
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('ContentPublishingConfigService', () => {
BATCH_INTERVAL_SECONDS: undefined,
BATCH_MAX_COUNT: undefined,
ASSET_UPLOAD_VERIFICATION_DELAY_SECONDS: undefined,
CACHE_KEY_PREFIX: undefined,
};

beforeAll(() => {
Expand Down Expand Up @@ -198,5 +199,9 @@ describe('ContentPublishingConfigService', () => {
it('should get batch max count', () => {
expect(contentPublishingConfigService.batchMaxCount).toStrictEqual(parseInt(ALL_ENV.BATCH_MAX_COUNT as string, 10));
});

it('should get cache key prefix', () => {
expect(contentPublishingConfigService.cacheKeyPrefix).toStrictEqual(ALL_ENV.CACHE_KEY_PREFIX?.toString());
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface ConfigEnvironmentVariables {
BATCH_INTERVAL_SECONDS: number;
BATCH_MAX_COUNT: number;
ASSET_UPLOAD_VERIFICATION_DELAY_SECONDS: number;
CACHE_KEY_PREFIX: string;
}

/// Config service to get global app and provider-specific config values.
Expand All @@ -31,6 +32,10 @@ export class ConfigService {
this.capacityLimit = JSON.parse(nestConfigService.get('CAPACITY_LIMIT')!);
}

public get cacheKeyPrefix(): string {
return this.nestConfigService.get('CACHE_KEY_PREFIX')!;
}

public get environment(): ChainEnvironment {
return this.nestConfigService.get<ChainEnvironment>('CHAIN_ENVIRONMENT')!;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ export const configModuleOptions: ConfigModuleOptions = {
return value;
})
.required(),
CACHE_KEY_PREFIX: Joi.string().default('content-publishing:'),
}),
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import * as QueueConstants from './queue.constants';
password: password || undefined,
db: pathname?.length > 1 ? Number(pathname.slice(1)) : undefined,
},
prefix: `${configService.cacheKeyPrefix}:bull`,
};
},
inject: [ConfigService],
Expand Down
2 changes: 1 addition & 1 deletion services/graph/ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This application recognizes the following environment variables:
| Name | Description | Range/Type | Required? | Default |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------: | :----------: | :-----: |
| `API_PORT` | HTTP port that the application listens on | 1025 - 65535 | | 3000 |
| `CACHE_KEY_PREFIX` | Prefix to use for Redis cache keys | string | | content-watcher: |
| `CACHE_KEY_PREFIX` | Prefix to use for Redis cache keys | string | | graph: |
| `CAPACITY_LIMIT` | Maximum amount of provider capacity this app is allowed to use (per epoch) type: 'percentage' 'amount' value: number (may be percentage, ie '80', or absolute amount of capacity) | JSON [(example)](./env.template) | Y | |
|`DEBOUNCE_SECONDS`|Number of seconds to retain pending graph updates in the Redis cache to avoid redundant fetches from the chain|>= 0||| | > 0 | | 100 |
| `FREQUENCY_URL` | Blockchain node address | http(s): or ws(s): URL | Y | |
Expand Down
2 changes: 1 addition & 1 deletion services/graph/libs/common/src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ConfigModuleOptions } from '@nestjs/config';
export const configModuleOptions: ConfigModuleOptions = {
isGlobal: true,
validationSchema: Joi.object({
CACHE_KEY_PREFIX: Joi.string().default('graph-service:'),
CACHE_KEY_PREFIX: Joi.string().default('graph:'),
REDIS_URL: Joi.string().uri().required(),
FREQUENCY_URL: Joi.string().uri().required(),
QUEUE_HIGH_WATER: Joi.number().min(100).default(1000),
Expand Down

0 comments on commit c4372bf

Please sign in to comment.