Skip to content

Commit 0865a96

Browse files
authored
Merge pull request #1276 from permaweb/VinceJuliano/dry-run-cache
feat(cu): add cache for dry run results
2 parents 0312e67 + c0e33b7 commit 0865a96

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

servers/cu/src/bootstrap.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,8 @@ export const createApis = async (ctx) => {
531531
logger: dryRunLogger
532532
}),
533533
DRY_RUN_DEFAULT_MAX_PROCESS_AGE: ctx.DRY_RUN_DEFAULT_MAX_PROCESS_AGE,
534-
DRY_RUN_PROCESS_CACHE_TTL: ctx.DRY_RUN_PROCESS_CACHE_TTL
534+
DRY_RUN_PROCESS_CACHE_TTL: ctx.DRY_RUN_PROCESS_CACHE_TTL,
535+
DRY_RUN_RESULT_MAX_AGE: ctx.DRY_RUN_RESULT_MAX_AGE
535536
})
536537

537538
/**

servers/cu/src/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ const CONFIG_ENVS = {
182182
HYDRATION_MODE_NONCE_LIMIT: process.env.HYDRATION_MODE_NONCE_LIMIT || 200,
183183
DRY_RUN_DEFAULT_MAX_PROCESS_AGE: process.env.DRY_RUN_DEFAULT_MAX_PROCESS_AGE || 100,
184184
DRY_RUN_PROCESS_CACHE_TTL: process.env.DRY_RUN_PROCESS_CACHE_TTL || 2000,
185+
DRY_RUN_RESULT_MAX_AGE: process.env.DRY_RUN_RESULT_MAX_AGE || 60000,
185186
LOAD_MESSAGES_PAGE_SIZE: process.env.LOAD_MESSAGES_PAGE_SIZE || 1000
186187
},
187188
production: {
@@ -244,6 +245,7 @@ const CONFIG_ENVS = {
244245
HYDRATION_MODE_NONCE_LIMIT: process.env.HYDRATION_MODE_NONCE_LIMIT || 200,
245246
DRY_RUN_DEFAULT_MAX_PROCESS_AGE: process.env.DRY_RUN_DEFAULT_MAX_PROCESS_AGE || 100,
246247
DRY_RUN_PROCESS_CACHE_TTL: process.env.DRY_RUN_PROCESS_CACHE_TTL || 2000,
248+
DRY_RUN_RESULT_MAX_AGE: process.env.DRY_RUN_RESULT_MAX_AGE || 60000,
247249
LOAD_MESSAGES_PAGE_SIZE: process.env.LOAD_MESSAGES_PAGE_SIZE || 1000
248250
}
249251
}

servers/cu/src/domain/api/dryRun.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ const TtlCache = ({ setTimeout, clearTimeout }) => {
4141
return cache
4242
}
4343

44+
const cyrb53 = (str, seed = 0) => {
45+
let h1 = 0xdeadbeef ^ seed; let h2 = 0x41c6ce57 ^ seed
46+
for (let i = 0, ch; i < str.length; i++) {
47+
ch = str.charCodeAt(i)
48+
h1 = Math.imul(h1 ^ ch, 2654435761)
49+
h2 = Math.imul(h2 ^ ch, 1597334677)
50+
}
51+
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507)
52+
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909)
53+
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507)
54+
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909)
55+
return 4294967296 * (2097151 & h2) + (h1 >>> 0)
56+
}
57+
4458
/**
4559
* @typedef Env
4660
*
@@ -58,6 +72,7 @@ const TtlCache = ({ setTimeout, clearTimeout }) => {
5872
*/
5973
export function dryRunWith (env) {
6074
const DRY_RUN_DEFAULT_MAX_PROCESS_AGE = env.DRY_RUN_DEFAULT_MAX_PROCESS_AGE
75+
const DRY_RUN_RESULT_MAX_AGE = env.DRY_RUN_RESULT_MAX_AGE
6176
const DRY_RUN_PROCESS_CACHE_TTL = env.DRY_RUN_PROCESS_CACHE_TTL
6277
const logger = env.logger
6378
const loadMessageMeta = loadMessageMetaWith(env)
@@ -73,6 +88,7 @@ export function dryRunWith (env) {
7388
})
7489

7590
const readStateCache = TtlCache(env)
91+
const dryRunResultCache = TtlCache(env)
7692

7793
function loadMessageCtx ({ messageTxId, processId }) {
7894
/**
@@ -159,6 +175,16 @@ export function dryRunWith (env) {
159175
}
160176

161177
return ({ processId, messageTxId, maxProcessAge = DRY_RUN_DEFAULT_MAX_PROCESS_AGE, dryRun }) => {
178+
const dryRunHash = cyrb53(JSON.stringify(dryRun))
179+
const cached = dryRunResultCache.get(dryRunHash)
180+
if (cached && new Date().getTime() - cached.age <= DRY_RUN_RESULT_MAX_AGE) {
181+
logger.debug(
182+
'Using recently cached dry-run result for dry-run to process "%s"',
183+
processId
184+
)
185+
return Resolved(cached.ctx)
186+
}
187+
162188
return of({ processId, messageTxId })
163189
.chain(loadMessageCtx)
164190
.chain(ensureProcessLoaded({ maxProcessAge }))
@@ -222,6 +248,11 @@ export function dryRunWith (env) {
222248
*/
223249
return evaluate({ ...ctx, dryRun: true, messages: Readable.from(dryRunMessage()) })
224250
})
225-
.map((res) => omit(['Memory'], res.output))
251+
.map((res) => {
252+
const omitted = omit(['Memory'], res.output)
253+
const cached = { age: new Date().getTime(), ctx: omitted }
254+
dryRunResultCache.set(dryRunHash, cached, DRY_RUN_RESULT_MAX_AGE)
255+
return omitted
256+
})
226257
}
227258
}

servers/cu/src/domain/model.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ export const domainConfigSchema = z.object({
263263
* The TTL of the dry run process cache in milliseconds.
264264
*/
265265
DRY_RUN_PROCESS_CACHE_TTL: positiveIntSchema,
266+
/*
267+
* Max time to cache a dry run result
268+
*/
269+
DRY_RUN_RESULT_MAX_AGE: positiveIntSchema,
266270
/**
267271
* The size of the page to load when fetching messages from the AO SU.
268272
*/

0 commit comments

Comments
 (0)