Skip to content

Commit 8d5eb74

Browse files
authored
Implement Cloudflare KV as cache backend (#5)
1 parent f205706 commit 8d5eb74

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ Clone the repo and install dependencies.
2121
You will need to sign up for two services (which both have free tiers):
2222

2323
- [Cloudflare](https://www.cloudflare.com): Where our worker will be hosted.
24-
- [Upstash](https://upstash.com): We use Upstash's redis-over-HTTP service for storing cached OpenAI responses. Depending on your usage, you may try replacing Redis with [Cloudflare KV](https://developers.cloudflare.com/workers/runtime-apis/kv/) instead which is eventually consistent but will likely provide better read latency.
24+
- [Upstash](https://upstash.com): We use Upstash's redis-over-HTTP service for storing cached OpenAI responses.
2525

2626
Finally, set up your redis secrets based on instructions in `wrangler.toml`.
2727

28+
Depending on your usage, you may try replacing Redis with [Cloudflare KV](https://developers.cloudflare.com/workers/runtime-apis/kv/) instead which is eventually consistent but will likely provide better read latency. Check `wrangler.toml` for setup instructions.
29+
2830
### Usage
2931

3032
Start the proxy server at http://localhost:8787 with:

src/cache.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,29 @@ interface CachedResponse {
8080
}
8181

8282
export class ResponseCache {
83-
redis: Redis;
83+
redis: Redis | undefined;
84+
kv: KVNamespace | undefined;
8485

8586
constructor({ env }: { env: Env }) {
86-
this.redis = new Redis({
87-
url: env.UPSTASH_REDIS_REST_URL,
88-
token: env.UPSTASH_REDIS_REST_TOKEN,
89-
});
87+
if (env.UPSTASH_REDIS_REST_URL && env.UPSTASH_REDIS_REST_TOKEN) {
88+
this.redis = new Redis({
89+
url: env.UPSTASH_REDIS_REST_URL,
90+
token: env.UPSTASH_REDIS_REST_TOKEN,
91+
});
92+
} else {
93+
this.kv = env.OPENAI_CACHE;
94+
}
9095
}
9196

9297
read = async ({ cacheKey }: { cacheKey: string }): Promise<Response | null> => {
93-
const result = await this.redis.get(cacheKey);
98+
let result;
99+
if (this.redis) {
100+
result = await this.redis.get(cacheKey);
101+
} else if (this.kv) {
102+
result = await this.kv.get(cacheKey);
103+
} else {
104+
return null;
105+
}
94106
if (result) {
95107
// Note: Upstash seems to automatically parse it to JSON:
96108
const cachedResponse =
@@ -118,7 +130,12 @@ export class ResponseCache {
118130
headers: getHeadersAsObject(response.headers),
119131
body: body ? body : null,
120132
};
121-
const options = ttl != null ? { ex: ttl } : {};
122-
await this.redis.set(cacheKey, JSON.stringify(responseObject), options);
133+
if (this.redis) {
134+
const options = ttl != null ? { ex: ttl } : {};
135+
await this.redis.set(cacheKey, JSON.stringify(responseObject), options);
136+
} else if (this.kv) {
137+
const options = ttl != null ? { expirationTtl: ttl } : {};
138+
await this.kv.put(cacheKey, JSON.stringify(responseObject), options);
139+
}
123140
};
124141
}

src/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ export interface Env {
1010

1111
UPSTASH_REDIS_REST_URL: string;
1212
UPSTASH_REDIS_REST_TOKEN: string;
13+
OPENAI_CACHE: KVNamespace;
1314
}

wrangler.toml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@ name = "openai-caching-proxy-worker"
22
main = "src/index.ts"
33
compatibility_date = "2022-12-11"
44

5-
# https://developers.cloudflare.com/workers/platform/environment-variables/#comparing-secrets-and-environment-variables
6-
[vars]
5+
# This cloudflare worker uses either Upstash or workers KV to store cache.
76

8-
# This cloudflare worker uses Upstash (hosted redis-over-REST):
7+
# To use Upstash (hosted redis-over-REST),
98
# https://docs.upstash.com/redis/quickstarts/cloudflareworkers
109
#
11-
# After signing up for a free account at upstash.com, set your secrets below based on instructions
10+
# 1. signing up for a free account at upstash.com, set your secrets below based on instructions
1211
# here for `wrangler secret put` (or alternatively use the Cloudflare Workers web UI):
1312
# https://developers.cloudflare.com/workers/platform/environment-variables/#adding-secrets-via-wrangler
14-
15-
# The necessary secrets are:
13+
# 2. Uncomment following environment variables config:
14+
# [vars]
1615
# - UPSTASH_REDIS_REST_TOKEN
1716
# - UPSTASH_REDIS_REST_URL
17+
18+
# To use workers KV,
19+
# 1. Run `wrangler kv:namespace create <YOUR_NAMESPACE>` in your terminal
20+
# 2. Uncomment following config and fill in <YOUR_ID>:
21+
# kv_namespaces = [
22+
# { binding = "OPENAI_CACHE", id = "<YOUR_ID>" }
23+
# ]

0 commit comments

Comments
 (0)