From e4c643a762edddf72bc68216f19355b97ab42dc2 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 27 Nov 2019 04:42:21 -0800 Subject: [PATCH] [Service] Refactor tizen extension module to be called on demand The tiezn extension module is loaded on demand to reduce memory usage. It's not loaded until web service starts. Change-Id: I760310b617de49bb6f1968cf64d6938d3bec63cb Signed-off-by: Youngsoo Choi --- wrt_app/service/tizen_extension.js | 68 ++++++++++++++++++-------------------- wrt_app/src/runtime.js | 14 +++++++- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/wrt_app/service/tizen_extension.js b/wrt_app/service/tizen_extension.js index 6e80497..3c88d5a 100644 --- a/wrt_app/service/tizen_extension.js +++ b/wrt_app/service/tizen_extension.js @@ -14,7 +14,6 @@ * limitations under the License. */ -(function() { const extension = require('./wrt_service_extension'); const wrt = require('../browser/wrt'); var window = global; @@ -22,33 +21,33 @@ var api_ = {}; var extensions_ = {}; var runtime_variables_ = {'runtime_name': 'wrt-service'}; -var ExtensionLoader = function() { - let plugins = require('./plugins.json'); - extension.initialize(runtime_variables_); - - var extensions = extension.getExtensions(); - for (var i = 0; i < extensions.length; i++) { - extensions[i].loaded = false; - for (var idx in plugins) { - if (extensions[i].name === plugins[idx].name) { - console.log("ExtensionLoader name " + extensions[i].name); - extensions_[extensions[i].name] = extensions[i]; +class TizenExtension { + constructor() { + let plugins = require('./plugins.json'); + extension.initialize(runtime_variables_); + + var extensions = extension.getExtensions(); + for (var i = 0; i < extensions.length; i++) { + extensions[i].loaded = false; + for (var idx in plugins) { + if (extensions[i].name === plugins[idx].name) { + console.log("ExtensionLoader name " + extensions[i].name); + extensions_[extensions[i].name] = extensions[i]; + } } } - } - for (var name in extensions_) { - if (!extensions_[name].use_trampoline) { - this.load(extensions_[name]); + for (var name in extensions_) { + if (!extensions_[name].use_trampoline) { + this.load(extensions_[name]); + } } - } - for (var name in extensions_) { - if (extensions_[name].use_trampoline) { - this.installTrampoline(extensions_[name]); + for (var name in extensions_) { + if (extensions_[name].use_trampoline) { + this.installTrampoline(extensions_[name]); + } } } -}; -ExtensionLoader.prototype = { /** * Creates namespace for 'name' in given object. * Eg. this.createNamespace(GLOBAL, 'tizen.contact') will create: @@ -57,15 +56,16 @@ ExtensionLoader.prototype = { * @param {Object} object * @param {String} name */ - createNamespace: function(object, name) { + createNamespace(object, name) { var obj = object; var arr = name.split('.'); for (var i = 0; i < arr.length; i++) { obj[arr[i]] = obj[arr[i]] || {}; obj = obj[arr[i]]; } - }, - exposeApi: function (ext) { + } + + exposeApi(ext) { var i, entry_points, entry_point, tmp, parent_name, base_name; // additional entry points are installed in GLOBAL context by eval() @@ -99,12 +99,12 @@ ExtensionLoader.prototype = { enumerable: true }); } - }, + } /** * @param {Object} ext */ - load: function(ext) { + load(ext) { if (ext.loaded) { return; } @@ -168,7 +168,7 @@ ExtensionLoader.prototype = { } catch (err) { console.log('Error loading extension "' + ext.name + '": ' + err.message); } - }, + } /** * This is used to defer extension loading to it's first usage. @@ -176,7 +176,7 @@ ExtensionLoader.prototype = { * * @param {Object} ext */ - installTrampoline: function(ext) { + installTrampoline(ext) { var entry_points = [...new Set(ext.entry_points)]; entry_points.push(ext.name); for (var i = 0; i < entry_points.length; i++) { @@ -201,9 +201,9 @@ ExtensionLoader.prototype = { enumerable: true }); } - }, + } - deleteTrampoline: function(ext) { + deleteTrampoline(ext) { var entry_points = [...new Set(ext.entry_points)]; entry_points.push(ext.name); @@ -214,7 +214,5 @@ ExtensionLoader.prototype = { delete GLOBAL[parent_name][base_name]; } } -}; - -new ExtensionLoader(); -})(); +} +module.exports = TizenExtension; diff --git a/wrt_app/src/runtime.js b/wrt_app/src/runtime.js index 077bdcf..7ca90c2 100755 --- a/wrt_app/src/runtime.js +++ b/wrt_app/src/runtime.js @@ -33,6 +33,7 @@ class Runtime { this.isLaunched = false; this.inspectorEnabledByVconf = false; this.sandbox = []; + this.sandbox_count = 0; this.webContents = null; this.addonPkgs = []; @@ -209,6 +210,10 @@ class Runtime { const vm = require('vm'); if (type === 'startService') { if (_this.sandbox[app_id] === undefined) { + if (_this.sandbox_count === 0) { + new TizenExtension(); + } + _this.sandbox_count++; const fs = require('fs'); const Module = require('module'); _this.sandbox[app_id] = { @@ -253,12 +258,19 @@ class Runtime { event.preventDefault(); } else if (type === 'stopService') { if (_this.sandbox[app_id]['stopped'] === undefined) { + _this.sandbox_count--; _this.sandbox[app_id]['stopped'] = true; _this.sandbox[app_id]['started'] = undefined; const stop_callback_string = 'if (module.exports.onStop !== undefined) { module.exports.onStop(); }'; vm.runInContext(stop_callback_string, _this.sandbox[app_id]); _this.sandbox[app_id]['timer_manager'].releaseRemainingTimers(); - _this.sandbox[app_id] = undefined; + for(let key in _this.sandbox[app_id]) { + delete _this.sandbox[app_id][key]; + } + delete _this.sandbox[app_id]; + if (sandbox_count === 0) { + tizen = null; + } } else { console.log('UI service has been stopped.'); } -- 2.7.4