Skip to content

Commit

Permalink
Add Deno platform cache to codegen service (#47)
Browse files Browse the repository at this point in the history
* Add Deno platform cache to codegen service

* register cache differently?

* Another attempt at edge caching

* Redo platform cache fetch

* add debug event

* Hmm so we need to do cache versioning?

* Add tracing event for cache hit failure

* Ok, maybe need to x- the header

* Remove debug tracing event
  • Loading branch information
danopia authored Sep 23, 2024
1 parent f6a9b6c commit cede987
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 5 deletions.
65 changes: 65 additions & 0 deletions generation/deploy/cache-platform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Cache } from "https://deno.land/x/[email protected]/mod.ts";
import { trace } from "./tracer.ts";

// https://docs.deno.com/deploy/manual/edge-cache

function transformUrl(url: string) {
return url.replace(/\/\/[^\/]+\//, '//upstream-cache-v2/');
}

export async function platformCache(
name = 'http-policy-cache',
): Promise<Cache> {

const nativeCache = await caches.open(name);

return new Cache({

async get(url) {
const cached = await nativeCache.match(transformUrl(url));
if (!cached) return undefined;

type CachePolicy = Parameters<ConstructorParameters<typeof Cache>[0]['set']>[1]['policy'];

const {
'x-cache-policy': policyHeader,
...resh
} = Object.fromEntries(cached.headers.entries());

if (!policyHeader) {
trace.getActiveSpan()?.addEvent('edgecache.fail', {
'message': 'platform cache hit lacked policy',
});
console.warn('WARN: platform cache lacked policy', cached);
return undefined;
}
const policy = {
...JSON.parse(policyHeader),
resh,
} as CachePolicy;

const BodyBuffer = new Uint8Array(await cached.arrayBuffer());

return {
policy,
body: BodyBuffer,
};
},

async set(url, resp) {
const {resh, ...rest} = resp.policy;
await nativeCache.put(transformUrl(url), new Response(resp.body, {
headers: {
...resh,
'x-cache-policy': JSON.stringify(rest),
},
}));
},

async delete(url) {
await nativeCache.delete(transformUrl(url));
},

close() {},
});
}
14 changes: 9 additions & 5 deletions generation/deploy/cache.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { inMemoryCache } from "https://deno.land/x/[email protected]/in_memory.ts";
import type { Cache } from "https://deno.land/x/[email protected]/mod.ts";
import { s3Cache } from "./cache-s3.ts";
import { S3 } from "./s3-api.ts";
import { ApiFactory } from "../../lib/client/mod.ts";
import { AsyncTracer, Span } from "./tracer.ts";

// can maybe replace this whole dep with deno edge cache once it's out of beta
import type { Cache } from "https://deno.land/x/[email protected]/mod.ts";
import { inMemoryCache } from "https://deno.land/x/[email protected]/in_memory.ts";
import { s3Cache } from "./cache-s3.ts";
import { platformCache } from "./cache-platform.ts";

const s3Api = new ApiFactory({
region: Deno.env.get('HTTPCACHE_S3_REGION') || 'us-east-2',
}).makeNew(S3);

const caches: Array<Cache> = [
inMemoryCache(40),
await platformCache(),
s3Cache(s3Api, Deno.env.get('HTTPCACHE_S3_BUCKET') || 'deno-httpcache'),
];
const cacheLabels = ['in-memory', 's3'];
const cacheLabels = ['in-memory', 'platform', 's3'];

import { AsyncTracer, Span } from "./tracer.ts";
const tracer = new AsyncTracer('cached-fetch');

export async function cachedFetch(mode: 'immutable' | 'mutable', label: string, url: string) {
Expand Down

0 comments on commit cede987

Please sign in to comment.