Perf: Send SurrealDB a token instead of the password (~47ms faster per query)

SurrealDB re-checks the password against its slow hash on every request. The token from /signin is kept in the
isolate's memory and in KV until 10 min before it expires, replaced if refused, and the password is still used if
no token can be had.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 17:14:36 +00:00
co-authored by Claude Opus 5.5
parent a8420fe005
commit d5c5b3e620
3 changed files with 48 additions and 10 deletions
+1
View File
@@ -272,6 +272,7 @@ Other keys share the namespace. They use uppercase prefixes, which can never col
| `FREE:<src or auto>:<i>:<query>` (e.g. `FREE:wikimedia:2:orange cat`) | Same as above | 90 days |
| `AI:<src>:<i>:<query>` (e.g. `AI:auroraimg-6m:2:frog wizard`) | Same as above | 90 days |
| `OPENVERSE_TOKEN` | Openverse access token | Token lifetime minus 10 min |
| `SURREAL_TOKEN` | SurrealDB access token, sent instead of the password, which SurrealDB takes ~50ms to check on every request | Token lifetime minus 10 min |
An AI image served because a search found nothing is stored under the search's own key, like any other image. A search where that also fails, or a `free.` search with a `src` (which gets no AI image), stores `{"t":…,"err":true}` for 24h.
+2 -10
View File
@@ -3,6 +3,7 @@ import { bingImageSearchFallback } from "./_utils/bing.js";
import { freeImageUrls, parseFreeSource, FREE_UA } from "./_utils/free.js";
import { isFlickrPlaceholder } from "./_utils/flickr.js";
import { aiImage, parseAiSource, DEFAULT_AI_SOURCE } from "./_utils/ai.js";
import { surreal } from "./_utils/surreal.js";
import * as LIMITS from "../assets/rate-limit.js";
const TTL_SECONDS = 90 * 24 * 60 * 60;
@@ -80,16 +81,7 @@ export async function onRequest(context) {
const limit = free ? LIMITS.FREE_DAILY_LIMIT : ai ? LIMITS.AI_DAILY_LIMIT : LIMITS.DAILY_LIMIT;
let count = 1, wait = false, locked = false, list = null;
const db = env.SURREAL_URL && env.SURREAL_USER && env.SURREAL_PASS && (body => fetch(`${env.SURREAL_URL}/sql`, {
method: "POST",
headers: {
"Accept": "application/json",
"Authorization": `Basic ${btoa(`${env.SURREAL_USER}:${env.SURREAL_PASS}`)}`,
"surreal-ns": "direct_img",
"surreal-db": "rate_limit",
},
body
}));
const db = surreal(env);
if (db) {
// Counts the search and claims this query's lock in the same round trip, so concurrent misses (on any isolate or
+45
View File
@@ -0,0 +1,45 @@
// Uppercase so it can't collide with query cache keys, which are always lowercased
const TOKEN_KEY = "SURREAL_TOKEN";
// SurrealDB re-checks a password against its deliberately slow hash on every request (~47ms), but a token in ~1ms. A
// token lasts 60 min, so it's kept in this isolate's memory and in KV until 10 min before it expires.
let cached = null;
// A token from memory, then KV, then a new /signin (fresh skips memory and KV). null if signing in fails.
async function getToken(env, fresh) {
if (!fresh && cached?.until > Date.now()) return cached.token;
let token = !fresh && await env.DIRECT_IMG_CACHE.get(TOKEN_KEY), signedIn = !token;
if (signedIn) {
const res = await fetch(`${env.SURREAL_URL}/signin`, {
method: "POST",
headers: { "Accept": "application/json" },
body: JSON.stringify({ user: env.SURREAL_USER, pass: env.SURREAL_PASS }),
});
token = res.ok && (await res.json()).token;
if (!token) return null;
}
const ttl = Math.floor(JSON.parse(atob(token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"))).exp - Date.now() / 1000) - 600;
if (signedIn && ttl >= 60) await env.DIRECT_IMG_CACHE.put(TOKEN_KEY, token, { expirationTtl: ttl }).catch(() => {});
cached = ttl > 0 ? { token, until: Date.now() + ttl * 1000 } : null;
return token;
}
// Runs SurrealQL in direct_img/rate_limit and resolves to the Response, or null if SurrealDB isn't configured. Uses the
// password only if no token can be had, so it still works, just slower.
export function surreal(env) {
if (!env.SURREAL_URL || !env.SURREAL_USER || !env.SURREAL_PASS) return null;
const send = (token, body) => fetch(`${env.SURREAL_URL}/sql`, {
method: "POST",
headers: {
"Accept": "application/json",
"Authorization": token ? `Bearer ${token}` : `Basic ${btoa(`${env.SURREAL_USER}:${env.SURREAL_PASS}`)}`,
"surreal-ns": "direct_img",
"surreal-db": "rate_limit",
},
body
});
return async body => {
const token = await getToken(env).catch(() => null), res = await send(token, body);
// A refused token (expired early or revoked) means the query never ran, so it's safe to retry with a new one
return res.status === 401 && token ? send(await getToken(env, true).catch(() => null), body) : res;
};
}