hypernova
hypernova copied to clipboard
add express response.locals object to the job context object
Addresses https://github.com/airbnb/hypernova/issues/111
Motivation: To be able to pass things from inside getComponent
to the rest of the express application (for custom middlewares)
(poked around in test/BatchManager-test.js
, but can't see a place we're already asserting things about what is on the context object that we're passing to getComponent
)
Thanks!
@goatslacker
rebased.
@schleyfox @goatslacker anything I can do to help nudge this along to be merged? Thanks!
@schleyfox @goatslacker Rebased again. ping :)
Motivation: To be able to pass things from inside getComponent to the rest of the express application (for custom middlewares)
What's an example of this? Maybe we can use this to create a test case for the feature.
@goatslacker Thanks for the feedback!
What's an example of this? Maybe we can use this to create a test case for the feature.
We have a few logging middlewares that run at the end of the request. As part of a profiling thing we're doing, we want to include in the log - did the request hit a cold bundle cache or not?
Erring on the side of being overly-verbose, I'll share our sample usage:
So right now, using my forked version, a simplified version of our code looks something like
// (CRS = "component rendering service")
// A home for all the stuff that CRS adds to the response object per component token
type CRSComponentContext = {
// Did the component request hit a cold cache?
wasBundleInCache?: boolean,
};
export default async function getComponent(
requestString: string,
context: Object,
) {
context.resLocals.crs = context.resLocals.crs || {};
const componentContexts = (context.resLocals.crs: { [token: string]: CRSComponentContext });
componentContexts[context.token] = {};
const componentContext = componentContexts[context.token];
// Decode requestString to get bundle/component info
const componentRequest = getComponentInfo(requestString);
// Fetch bundle from memory / disk / s3
const [bundle, wasBundleInCache] = await getBundle(componentRequest.service, componentRequest.sha);
componentContext.wasBundleInCache = wasBundleInCache;
const component = bundle.default[componentRequest.name];
return component;
}
This allows us in a middleware later on to access res.locals.crs[key];
and get arbitrary information about that specific component request.
(For example, somewhere else, in a logging middleware, we do something like)
// (uses https://www.npmjs.com/package/tweenz)
export default function AccessLog () {
return async (requestDetails, req, res) => {
// wait for request to complete
await requestDetails;
const componentRequests = Object.keys(hypernovaRequest).map(key => {
const componentContext = res.locals.crs[key];
return {
// we'd also actually log some other stuff here too like timing, status etc
...componentContext,
}
});
logSomewhere(componentRequests);
};
};