Run KV get() in parallel to origin fetch() - intermittent failures

I am using HTMLRewriter to make changes to pages, which may or may not be cached. The changes are driven by values in the KV store that are updated by a separate periodic script (every few hours).

Sometimes a cold request to the KV store can take 40-50ms so in the interests of speeding things up, I want to run the KV get() in parallel to any potential request to origin (or cache check).

I am a bit shaky on Promises and async in JS, but I put something together which mostly just works. However, a small percentage of requests are failing; the Worker doesn’t throw an exception but tailing the logs I see The script will never generate a response.. I think this is related to Promises, but I cannot work out why that should be the case.

A minimal POC of my code is below. Can anyone help explain what is happening?

Many thanks!


class PageRewriter {

	constructor( request ) {

		// nothing relevant

	}

	async element( element ) {
		// Ensure the KV response has arrived
		myKvData = await myKvData

		// do stuff with KV values
		element.replace( new_content )
	}
}

async function handleRequest( event ) {
	const request = event.request
	const cacheUrl = new URL( request.url )
	const cacheKey = new Request( cacheUrl.toString(), request )
	const cache = caches.default
	let response

	// Only do KV get() if this worker session hasn't already done so
	if ( !myKvData ) {
		myKvData = KVNAMESPACE.get( "data", { cacheTtl: 7200, type: "json" } )
	}

	try {

		response = await cache.match( cacheKey )

	} catch ( e ) {
		response = false
	}

	// If not in cache, get it from origin
	if ( !response ) {

		response = await fetch( request )

		if ( response.status == 200 ) {
			event.waitUntil( cache.put( cacheKey, response.clone() ) )
		}
	}

	const rewriter = new HTMLRewriter()
		.on( ".special-tag", new PageRewriter( request ) )

	return rewriter.transform( response )
}


addEventListener( "fetch", event => {
	const request = event.request
} )