Skip to content

Commit

Permalink
deprecate CLUSTER_ROOT_NODES, fix max payload size (#40)
Browse files Browse the repository at this point in the history
* deprecate CLUSTER_ROOT_NODES, fix max payload size

* use const for max payload size
  • Loading branch information
bryce-fitzsimons authored Nov 1, 2023
1 parent 6de4de8 commit c6d5fee
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 34 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ The GrowthBook Proxy repository is a mono-repo containing the following packages

### What's new

**Version 1.1.2**
- Fix max payload size bug
- Deprecate `CLUSTER_ROOT_NODES` in favor of `CLUSTER_ROOT_NODES_JSON`

**Version 1.1.1**
- Multi organization support
- Support paginated SDK Connection polling
Expand Down Expand Up @@ -110,9 +114,8 @@ Redis-specific options for cluster mode:<br />
_(Note that CACHE_CONNECTION_URL is ignored when using cluster mode)_

- `USE_CLUSTER` - "true" or "1" to enable (default: `false`)
- `CLUSTER_ROOT_NODES` - simple: comma-separated URLs to your cluster seed nodes
- `CLUSTER_ROOT_NODES_JSON` - advanced: JSON array of ClusterNode objects (ioredis)
- `CLUSTER_OPTIONS_JSON` - advanced: JSON object of ClusterOptions (ioredis)
- `CLUSTER_ROOT_NODES_JSON` - JSON array of ClusterNode objects (ioredis)
- `CLUSTER_OPTIONS_JSON` - JSON object of ClusterOptions (ioredis)

#### MongoDB

Expand Down
2 changes: 1 addition & 1 deletion packages/apps/proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"node": ">=18"
},
"description": "GrowthBook proxy server for caching, realtime updates, telemetry, etc",
"version": "1.1.1",
"version": "1.1.2",
"main": "dist/app.js",
"license": "MIT",
"repository": {
Expand Down
3 changes: 2 additions & 1 deletion packages/apps/proxy/src/controllers/adminController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import express, { Request, Response } from "express";
import { registrar } from "../services/registrar";
import { adminMiddleware } from "../middleware/adminMiddleware";
import logger from "../services/logger";
import { MAX_PAYLOAD_SIZE } from "../init";

const postConnection = (req: Request, res: Response) => {
const apiKey = req.body.apiKey;
Expand Down Expand Up @@ -57,7 +58,7 @@ adminRouter.post(
"/connection",
adminMiddleware,
express.json({
limit: process.env.MAX_PAYLOAD_SIZE ?? "2mb",
limit: process.env.MAX_PAYLOAD_SIZE ?? MAX_PAYLOAD_SIZE,
}),
postConnection,
);
Expand Down
6 changes: 5 additions & 1 deletion packages/apps/proxy/src/controllers/featuresController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { sseSupportMiddleware } from "../middleware/sseSupportMiddleware";
import logger from "../services/logger";
import { fetchFeatures } from "../services/features";
import { Context } from "../types";
import { MAX_PAYLOAD_SIZE } from "../init";

const getFeatures = async (req: Request, res: Response, next: NextFunction) => {
if (!registrar?.growthbookApiHost) {
Expand Down Expand Up @@ -181,7 +182,9 @@ export const featuresRouter = (ctx: Context) => {
router.post(
"/api/eval/*",
apiKeyMiddleware,
express.json(),
express.json({
limit: process.env.MAX_PAYLOAD_SIZE ?? MAX_PAYLOAD_SIZE,
}),
sseSupportMiddleware,
getEvaluatedFeatures,
);
Expand All @@ -192,6 +195,7 @@ export const featuresRouter = (ctx: Context) => {
"/proxy/features",
apiKeyMiddleware,
express.json({
limit: process.env.MAX_PAYLOAD_SIZE ?? MAX_PAYLOAD_SIZE,
verify: (req: Request, res: Response, buf: Buffer) =>
(res.locals.rawBody = buf),
}),
Expand Down
7 changes: 3 additions & 4 deletions packages/apps/proxy/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import dotenv from "dotenv";
import { CacheEngine, Context } from "./types";
dotenv.config({ path: "./.env.local" });

export const MAX_PAYLOAD_SIZE = "2mb";

export default async () => {
const context: Partial<Context> = {
growthbookApiHost: process.env.GROWTHBOOK_API_HOST,
Expand All @@ -15,7 +17,7 @@ export default async () => {
verboseDebugging: ["true", "1"].includes(
process.env.VERBOSE_DEBUGGING ?? "0",
),
maxPayloadSize: process.env.MAX_PAYLOAD_SIZE ?? "2mb",
maxPayloadSize: process.env.MAX_PAYLOAD_SIZE ?? MAX_PAYLOAD_SIZE,
// SDK Connections settings:
createConnectionsFromEnv: ["true", "1"].includes(process.env.CREATE_CONNECTIONS_FROM_ENV ?? "1"),
pollForConnections: ["true", "1"].includes(process.env.POLL_FOR_CONNECTIONS ?? "1"),
Expand All @@ -37,9 +39,6 @@ export default async () => {
),
// Redis only - cluster:
useCluster: ["true", "1"].includes(process.env.USE_CLUSTER ?? "0"),
clusterRootNodes: process.env.CLUSTER_ROOT_NODES
? process.env.CLUSTER_ROOT_NODES.replace(" ", "").split(",")
: undefined,
clusterRootNodesJSON: process.env.CLUSTER_ROOT_NODES_JSON
? JSON.parse(process.env.CLUSTER_ROOT_NODES_JSON)
: undefined,
Expand Down
27 changes: 4 additions & 23 deletions packages/apps/proxy/src/services/cache/RedisCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class RedisCache {
public readonly allowStale: boolean;

private readonly useCluster: boolean;
private readonly clusterRootNodes?: ClusterNode[];
private readonly clusterRootNodesJSON?: ClusterNode[];
private readonly clusterOptions?: ClusterOptions;

private readonly appContext?: Context;
Expand All @@ -36,7 +36,6 @@ export class RedisCache {
useAdditionalMemoryCache,
publishPayloadToChannel = false,
useCluster = false,
clusterRootNodes,
clusterRootNodesJSON,
clusterOptionsJSON,
}: CacheSettings = {},
Expand All @@ -48,8 +47,7 @@ export class RedisCache {
this.allowStale = allowStale;
this.publishPayloadToChannel = publishPayloadToChannel;
this.useCluster = useCluster;
this.clusterRootNodes =
clusterRootNodesJSON ?? this.transformRootNodes(clusterRootNodes);
this.clusterRootNodesJSON = clusterRootNodesJSON;
this.clusterOptions = clusterOptionsJSON;

this.appContext = appContext;
Expand All @@ -69,9 +67,9 @@ export class RedisCache {
? new Redis(this.connectionUrl)
: new Redis();
} else {
if (this.clusterRootNodes) {
if (this.clusterRootNodesJSON) {
this.client = new Redis.Cluster(
this.clusterRootNodes,
this.clusterRootNodesJSON,
this.clusterOptions,
);
} else {
Expand Down Expand Up @@ -268,21 +266,4 @@ export class RedisCache {
public getsubscriberClient() {
return this.subscriberClient;
}

private transformRootNodes(rootNodes?: string[]): ClusterNode[] | undefined {
if (!rootNodes) return undefined;
return rootNodes
.map((node) => {
try {
const url = new URL(node);
const host = url.protocol + "//" + url.hostname + url.pathname;
const port = parseInt(url.port);
return { host, port };
} catch (e) {
logger.error(e, "Error parsing Redis cluster node");
return undefined;
}
})
.filter(Boolean) as ClusterNode[];
}
}
1 change: 0 additions & 1 deletion packages/apps/proxy/src/services/cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export interface CacheSettings {
useAdditionalMemoryCache?: boolean;
publishPayloadToChannel?: boolean; // for RedisCache pub/sub
useCluster?: boolean; // for RedisCache
clusterRootNodes?: string[]; // for RedisCache
clusterRootNodesJSON?: ClusterNode[]; // for RedisCache
clusterOptionsJSON?: ClusterOptions; // for RedisCache
}
Expand Down

0 comments on commit c6d5fee

Please sign in to comment.