Skip to content

Commit cc6b83f

Browse files
madanagopaltmadanagopaltcomcast
authored andcommitted
cache framework changes (review) (#2182)
Co-authored-by: madanagopaltcomcast <35588028+madanagopaltcomcast@users.noreply.github.com>
1 parent f6bf576 commit cc6b83f

File tree

1 file changed

+165
-6
lines changed

1 file changed

+165
-6
lines changed

examples/pxScene2d/src/rcvrcore/ESMLoader.js

Lines changed: 165 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ var readFileAsync = promisify(fs.readFile)
2525
var ArrayJoin = Function.call.bind(Array.prototype.join);
2626
var ArrayMap = Function.call.bind(Array.prototype.map);
2727
var reqOrig = require;
28+
var frameWorkCache = {}
29+
var enableFrameworkCaching = undefined;
30+
var keepFrameworksOnExit = undefined;
2831

2932
// Normalize the URL, for consistency. Remove the query part.
3033
// All local URLs would have the 'file:' prefix.
@@ -350,10 +353,130 @@ var loadMjs = async function (source, url, context, modmap, version)
350353
return mod;
351354
}
352355

356+
function eligibleForFrameWorkCaching(scene, url, name, hash)
357+
{
358+
if (undefined == enableFrameworkCaching)
359+
{
360+
enableFrameworkCaching = scene.sparkSetting("enableFrameWorkCache");
361+
if (undefined == enableFrameworkCaching)
362+
{
363+
enableFrameworkCaching = true;
364+
}
365+
if (false == enableFrameworkCaching) {
366+
keepFrameworksOnExit = false;
367+
}
368+
}
369+
if (enableFrameworkCaching == true)
370+
{
371+
// currently enable only for .js file
372+
if ((/\.js$/.test(url)) && (hash != undefined) && ((url != undefined) || (name != undefined)))
373+
return true;
374+
}
375+
return false;
376+
}
377+
378+
function ensureUniqueFramework(url)
379+
{
380+
var noentries = frameWorkCache[url].length;
381+
if (noentries > 1) {
382+
var entriestoremove = []
383+
for (var i=0; i<noentries; i++) {
384+
if (frameWorkCache[url][i].numAppsUsing == 0)
385+
{
386+
entriestoremove.push(i)
387+
}
388+
}
389+
for (var i=0; i<entriestoremove.length-1; i++) {
390+
var index = entriestoremove[i];
391+
for (key in frameWorkCache[url][index]) {
392+
delete frameWorkCache[url][index][key]
393+
}
394+
}
395+
for (var i=0; i<entriestoremove.length-1; i++) {
396+
var index = entriestoremove[i];
397+
index = index-i;
398+
frameWorkCache[url].splice(entriestoremove[index], 1);
399+
}
400+
entriestoremove = []
401+
}
402+
}
403+
404+
function getCachePosition(url, hash)
405+
{
406+
var cacheposition = -1;
407+
if (frameWorkCache[url] != undefined)
408+
{
409+
for (var i=0; i<frameWorkCache[url].length; i++) {
410+
if (frameWorkCache[url][i].hash == hash)
411+
{
412+
cacheposition = i;
413+
break;
414+
}
415+
}
416+
/*
417+
// means we got a requirement for a framework version not in cache
418+
// removing unsed earlier to handle any scenarios to unwanted memory removal
419+
ensureUniqueFramework(url);
420+
*/
421+
}
422+
return cacheposition;
423+
}
424+
425+
async function loadFrameWorks(loadCtx, bootstrapUrl) {
426+
const list = loadCtx.bootstrap.frameworks;
427+
var frameWorkUsageInfo = {}
428+
for (let i = 0; i < list.length; i++) {
429+
let _framework = list[i];
430+
let _url = _framework.url || _framework;
431+
let _name = _framework.name
432+
433+
let _hash = _framework.md5
434+
let useFrameWorkCaching = eligibleForFrameWorkCaching(loadCtx.sandbox.global.sparkscene, _url, _name, _hash)
435+
436+
// store framework compiled scripts only for js files
437+
if (true == useFrameWorkCaching)
438+
{
439+
let _cachekey = (undefined != _name)?_name:_url;
440+
let _cachePostion = getCachePosition(_cachekey, _hash);
441+
if (_cachePostion != -1)
442+
{
443+
frameWorkUsageInfo[_cachekey] = _cachePostion;
444+
//console.log("framework "+ _cachekey + " available in cache at postion " + _cachePostion + " , no need to reload !!!!!!!!!!!!!!!!!!!");
445+
}
446+
else
447+
{
448+
if (!/^(http:|https:|file:)/.test(_url))
449+
_url = urlmain.resolve(bootstrapUrl, _url);
450+
451+
var frameWorkSource = await getFile(loadCtx.sandbox.global.sparkscene, _url);
452+
var frameWorkScript = new vm.Script(frameWorkSource);
453+
if (undefined == frameWorkCache[_cachekey]) {
454+
frameWorkCache[_cachekey] = []
455+
}
456+
frameWorkCache[_cachekey].push({'hash' : _hash, 'script' : frameWorkScript, 'numAppsUsing' : 0})
457+
frameWorkUsageInfo[_cachekey] = frameWorkCache[_cachekey].length - 1;
458+
//console.log("Newly loaded cache for " + _cachekey + " at position " + frameWorkUsageInfo[_cachekey]);
459+
}
460+
}
461+
else
462+
{
463+
await importModuleDynamically(_url, {url:bootstrapUrl, context:loadCtx.contextifiedSandbox}, _hash);
464+
}
465+
}
466+
for (var key in frameWorkUsageInfo)
467+
{
468+
var pos = frameWorkUsageInfo[key];
469+
frameWorkCache[key][pos].script.runInContext(loadCtx.contextifiedSandbox);
470+
frameWorkCache[key][pos].numAppsUsing = frameWorkCache[key][pos].numAppsUsing + 1;
471+
}
472+
loadCtx.frameWorkUsageInfo = frameWorkUsageInfo;
473+
}
474+
353475
function ESMLoader(params) {
354476
this.ctx = params
355477
this.loadESM = function(filename) {
356478
var loadCtx = this.ctx;
479+
loadCtx.frameWorkUsageInfo = {}
357480
let url = filename2url(filename);
358481
const loc = /^file:/.test(url) ? url.substring(7) : url;
359482

@@ -381,12 +504,7 @@ function ESMLoader(params) {
381504
try {
382505
// When URL is .spark, frameworkURL-s are loaded like dynamic imports.
383506
if (loadCtx.bootstrap && loadCtx.bootstrap.frameworks) {
384-
const list = loadCtx.bootstrap.frameworks;
385-
for (let i = 0; i < list.length; i++) {
386-
let _framework = list[i];
387-
let _url = _framework.url || _framework;
388-
await importModuleDynamically(_url, {url:bootstrapUrl, context:loadCtx.contextifiedSandbox}, _framework.md5);
389-
}
507+
await loadFrameWorks(loadCtx, bootstrapUrl);
390508
}
391509
var source = await getFile(loadCtx.global.sparkscene, url);
392510
loadCtx.app = await loadMjs(source, url, loadCtx.contextifiedSandbox, loadCtx.modmap);
@@ -411,6 +529,47 @@ function ESMLoader(params) {
411529
}
412530
}
413531
this.clearResources = function() {
532+
if (enableFrameworkCaching == true)
533+
{
534+
if (undefined == keepFrameworksOnExit)
535+
{
536+
keepFrameworksOnExit = this.ctx.global.sparkscene.sparkSetting("keepFrameworksOnExit");
537+
if (undefined == keepFrameworksOnExit)
538+
{
539+
keepFrameworksOnExit = true;
540+
}
541+
}
542+
if (undefined != this.ctx.frameWorkUsageInfo) {
543+
for (key in this.ctx.frameWorkUsageInfo)
544+
{
545+
var pos = this.ctx.frameWorkUsageInfo[key];
546+
frameWorkCache[key][pos].numAppsUsing--;
547+
if (false == keepFrameworksOnExit) {
548+
// not deleting the cache entry if someone is using
549+
if (frameWorkCache[key][pos].numAppsUsing == 0)
550+
{
551+
for(var k in frameWorkCache[key][pos])
552+
{
553+
delete frameWorkCache[key][pos][k];
554+
}
555+
frameWorkCache[key].splice(pos, 1);
556+
}
557+
if (frameWorkCache[key].length == 0)
558+
{
559+
delete frameWorkCache[key];
560+
}
561+
}
562+
else {
563+
ensureUniqueFramework(key);
564+
}
565+
}
566+
this.ctx.frameWorkUsageInfo = {}
567+
delete this.ctx.frameWorkUsageInfo;
568+
}
569+
}
570+
else {
571+
console.log("no framework manipulation !!!!!");
572+
}
414573
this.ctx = null
415574
}
416575
}

0 commit comments

Comments
 (0)