-
Notifications
You must be signed in to change notification settings - Fork 214
[Question] Runtime loading/unloading modules #144
Comments
Specifically, we want to deploy hypernova in such a way that it supports multiple versions (ie. releases) of our SSR code, without having to restart it. However, we've noticed memory leaks. The scheme is the following:
The SSR code is the following: // components.js
const renderReact = require('hypernova-react').renderReact;
const MyComponent = require('./MyComponent');
module.exports = {
MyComponent: renderReact('MyComponent', MyComponent),
}; and in // hypernova.js
// ...
function loadCodeSeparateContext(path) {
return hypernova.createGetComponent({
"0": path
})("0");
}
const getComponent = async (name) => {
var start = process.hrtime();
const [componentName, release] = name.split('.');
if (!componentName || !release) {
return null;
}
if (!componentsPerRelease[release]) {
var componentsPath = path.resolve(path.join('./testdata', release, 'components.js'));
if (await fs.pathExists(componentsPath)){
var releaseComponents = loadCodeSeparateContext(componentsPath);
componentsPerRelease[release] = {components: releaseComponents};
}
else {
return null;
}
}
componentsPerRelease[release].lastAccessed = start;
if (!componentsPerRelease[release].components[componentName]) {
return null;
}
var [seconds, nanos] = process.hrtime(start);
return componentsPerRelease[release].components[componentName];
};
function unloadReleases(expirySeconds) {
Object.entries(componentsPerRelease).forEach(([releaseId, release]) => {
if (release.lastAccessed) {
var seconds = process.hrtime(release.lastAccessed)[0];
if (seconds > expirySeconds) {
delete componentsPerRelease[releaseId];
console.log(`Unloaded release ${releaseId}`);
}
}
})
}
setInterval(() => unloadReleases(5), 5000);
hypernova({
devMode: true,
getComponent: getComponent,
port: 3030,
}); We run load tests with a total of 100 releases. The tests are made so that they keep a rolling window of 5 versions that moves by 1 version forward every ~5seconds. This means that hypernova unloads (ie. deletes from map) an old version and loads a new one every ~5secs. Unfortunately, we noticed that the instance is leaking memory at a constant rate. After some profiling, it seems that the code of a release (react etc.) is never reclaimed by the collector, since However, after bundling all the SSR code using webpack, so as to avoid the I'm not sure if this is a supported use-case, so we'd like your advice here. Is that something hypernova supports (ie. multiple versions in an instance) and what is the suggested way to do this? Thanks in advance. |
Did you ever figure out why memory was growing when loading new bundles in? Can you expand more on how you used Webpack to avoid |
We have been experimenting with hypernova for our SSR architecture. A problem arose when we wanted to add or remove a module in the
getComponent
method on runtime. Is there a suggested way that we could do this without restarting the server?The text was updated successfully, but these errors were encountered: