Skip to content

Commit

Permalink
feat(workers): cache
Browse files Browse the repository at this point in the history
  • Loading branch information
shaokeyibb committed Jul 17, 2024
1 parent 2184a24 commit 689e921
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 16 deletions.
23 changes: 23 additions & 0 deletions cloudflare-workers/src/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { getPaths } from './db';

export async function purgeAllCommentCache(env: Env, cache: Cache, baseUrl: string) {
const paths = await getPaths(env);

await Promise.all(
paths.map((path) => {
purgeCommentCache(env, cache, baseUrl, path);
}),
);
}

export async function purgeCommentCache(env: Env, cache: Cache, baseUrl: string, path: string) {
await cache.delete(`${baseUrl}/comment${path}`);
}

export async function putCommentCache(env: Env, cache: Cache, baseUrl: string, path: string, resp: Response): Promise<void> {
await cache.put(`${baseUrl}/comment${path}`, resp);
}

export async function matchCommentCache(env: Env, cache: Cache, baseUrl: string, path: string): Promise<Response | undefined> {
return await cache.match(`${baseUrl}/comment${path}`);
}
6 changes: 6 additions & 0 deletions cloudflare-workers/src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,9 @@ export async function getMeta(env: Env, key: string): Promise<string | undefined

return meta?.value;
}

export async function getPaths(env: Env): Promise<string[]> {
const db = env.DB;

return (await db.prepare('SELECT path FROM pages').all()).results.map((page) => page.path as string);
}
77 changes: 63 additions & 14 deletions cloudflare-workers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,30 @@
*/

import { AutoRouter, error } from 'itty-router';
import { GetCommentBody, GetCommentRespBody, GetCommitHashRespBody, PostCommentBody, PutCommitHashBody, ResponseBody } from './types';
import { getComment, getMeta, postComment } from './db';
import { GetCommentBody, GetCommentRespBody, PostCommentBody, PutCommitHashBody, ResponseBody } from './types';
import { getComment, postComment } from './db';
import { validateSecret, setCommitHash, compareCommitHash } from './administration';
import { matchCommentCache, purgeAllCommentCache, purgeCommentCache, putCommentCache } from './cache';

const router = AutoRouter();

router.post('/comment', async (req, env, ctx) => {
router.post('/comment/:path', async (req, env, ctx) => {
const params = req.params as GetCommentBody;

if (params == undefined || params.path == undefined) {
return error(400, 'Invalid request body');
}

params.path = decodeURIComponent(params.path);

if (!params.path.startsWith('/')) {
return error(400, 'Invalid path');
}

const body = await req.json<PostCommentBody>();

if (
body == undefined ||
body.path == undefined ||
body.offset == undefined ||
body.commenter == undefined ||
body.comment == undefined ||
Expand All @@ -35,10 +47,6 @@ router.post('/comment', async (req, env, ctx) => {
return error(400, 'Invalid request body');
}

if (!body.path.startsWith('/')) {
return error(400, 'Invalid path');
}

if (body.offset.start < 0 || body.offset.end < 0 || body.offset.start >= body.offset.end) {
return error(400, 'Invalid offset');
}
Expand All @@ -56,7 +64,7 @@ router.post('/comment', async (req, env, ctx) => {
}

await postComment(env, {
path: body.path,
path: params.path,
offset: body.offset,
commenter: {
name: body.commenter.name,
Expand All @@ -66,6 +74,9 @@ router.post('/comment', async (req, env, ctx) => {
comment: body.comment,
});

const cache = caches.default;
ctx.waitUntil(purgeCommentCache(env, cache, new URL(req.url).origin, params.path));

return {
status: 200,
} satisfies ResponseBody;
Expand All @@ -80,12 +91,25 @@ router.get('/comment/:path', async (req, env, ctx) => {

params.path = decodeURIComponent(params.path);

const rst = await getComment(env, params);
const cache = caches.default;
let resp = await matchCommentCache(env, cache, new URL(req.url).origin, params.path);

if (!resp) {
resp = new Response(
JSON.stringify({
status: 200,
data: await getComment(env, params),
} satisfies ResponseBody<GetCommentRespBody>),
{
headers: {
'Content-Type': 'application/json',
},
},
);
ctx.waitUntil(putCommentCache(env, cache, new URL(req.url).origin, params.path, resp.clone()));
}

return {
status: 200,
data: rst,
} satisfies ResponseBody<GetCommentRespBody>;
return resp;
});

router.put('/meta/commithash', async (req, env, ctx) => {
Expand Down Expand Up @@ -122,4 +146,29 @@ router.put('/meta/commithash', async (req, env, ctx) => {
} satisfies ResponseBody;
});

router.delete('/cache', async (req, env, ctx) => {
const authorization = req.headers.get('Authorization');

if (!authorization) {
return error(401, 'Unauthorized');
}

const [scheme, secret] = authorization.split(' ');

if (scheme !== 'Bearer' || !secret) {
return error(400, 'Malformed authorization header');
}

if (validateSecret(env, secret) !== true) {
return error(401, 'Unauthorized');
}

const cache = caches.default;
await purgeAllCommentCache(env, cache, new URL(req.url).origin);

return {
status: 200,
} satisfies ResponseBody;
});

export default { ...router } satisfies ExportedHandler<Env>;
5 changes: 3 additions & 2 deletions cloudflare-workers/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type PostCommentBody = {
path: string;
offset: {
start: number;
end: number;
Expand All @@ -16,7 +15,9 @@ export type PostComment = {
user_agent: string;
ip_address: string | null;
};
} & Omit<PostCommentBody, 'commit_hash'>;
} & Omit<PostCommentBody, 'commit_hash'> & {
path: string;
};

export type GetCommentBody = {
path: string;
Expand Down

0 comments on commit 689e921

Please sign in to comment.