たとえば、大量のデータを処理する場合、最大の環境リソースを使用して作業に費やす合計時間を削減するために、異なるオブジェクトに対して同様のタスクを同時に実行する競合プロセスを使用する必要があります。
npmの簡単なパッケージを開発しているとします。 たとえば、
storage (storage)と名前を付けましょう。
FsStorage (ファイルストレージ)、
MysqlStorage (MySQLストレージ)、
MongoStorage (Mongoストレージ)など、いくつかのタイプのストレージのいずれかを使用する可能性を予測します。
パッケージのソースコードの内容を配布します(ネタバレの下):
プロジェクトのソースコードの大まかなスケッチpackage.json :
{ "name": "storage", "version": "0.1.0", "main": "./lib/index.js", "dependencies": { "mysql": "*", "mongoose": "*" } }
lib/index.js :
module.exports = { FsStorage: require('./fs-storage.jsx'), MysqlStorage: require('./mysql-storage.jsx'), MongoStorage: require('./mongo-storage.jsx') };
lib/fs-storage.js :
var fs = require('fs'); module.exports = FsStorage; function FsStorage() {
lib/mysql-storage.js :
var mysql = require('mysql'); module.exports = MysqlStorage; function MysqlStorage() {
lib/mongo-storage.js :
var mongoose = require('mongoose'); module.exports = MongoStorage; function MongoStorage() {
直接的な
mysqlおよび
mongoose依存関係コードは、デモには必要ありません。 したがって、
mysqlおよび
mongooseコードの代わりに、スタブを(スポイラーの下に)配置します。
Mysqlおよびmongooseスタブソースコード パッケージのファイル構造は次のようになります(ネタバレの下):
ファイル構造ツリーのレイアウト storage/ ├ lib/ │ ├ index.js │ ├ fs-storage.js │ ├ mongo-storage.js │ └ mysql-storage.js ├ node_modules/ │ ├ mongoose/ │ │ └ index.js │ └ mysql/ │ └ index.js └ package.json
ここで、いくつかの子プロセスを使用して実行する非常に大きなタスクがあり、その完了時にファイル形式のストレージを使用する必要があると想像してください。
var storage = require('storage'); var fsStorage = new storage.FsStorage();
開始して観察します。各子プロセスは、予想よりも1桁多くのメモリを占有します。 競合するプロセスの数が100を超える場合、これがリアルタイムでサーバー上で実行される唯一のタスクではありません。
ここでは、たとえば、ファイルストレージを使用する場合、
MySQLデータベース管理ライブラリと
Mongo ODMクライアントの両方をダウンロードする必要がないことを理解しています。
require('storage')呼び出した直後に、メッセージがコンソールに表示されます:
MySQL module loaded Mongoose module loaded
Object.defineProperty()メソッド
Object.defineProperty()実験して、私は
demandProperty()関数として設計した驚くべき結果を達成しました。
function demandProperty(obj, name, modPath) { Object.defineProperty(obj, name, { configurable: true, enumerable: true, get: function() { var mod = require(modPath); Object.defineProperty(obj, name, { configurable: false, enumerable: true, value: mod }); return mod } }) }
操作の原理は単純です。たとえば、
MysqlStorage()への直接リンクの代わりに、アクセサー(
getter )が作成されます。 アクセサーへの要求では、
require()トリガーされ、アクセサー自体が
require()結果を返します。 さらに、同じ
Object.defineProperty()を使用して、アクセサではなく
require()同じ結果(つまり
MysqlStorage() )への直接リンクを設定し直しました。 したがって、すべてのリクエスト(もちろん、最初のリクエストを除く)は、従来の
require()をそのままにしているかのように、リークからの同じ速度と信頼性で動作します。
lib/index.js変更し
lib/index.js 。 交換:
module.exports = { FsStorage: require('./fs-storage.jsx'), MysqlStorage: require('./mysql-storage.jsx'), MongoStorage: require('./mongo-storage.jsx'), };
に:
demandProperty(module.exports, 'FsStorage', './fs-storage.jsx'); demandProperty(module.exports, 'MysqlStorage', './mysql-storage.jsx'); demandProperty(module.exports, 'MongoStorage', './mongo-storage.jsx');
そして使用:
var storage = require('storage'); console.log(util.inspect(storage)); console.log(util.inspect(storage.FsStorage.name));
別の微妙な点があります。
demandProperty()関数の定義が
libフォルダー内のモジュールの外部で取得される場合、最後の引数はモジュールへのフルパスでなければなりません。
demandProperty(module.exports, 'FsStorage', path.resolve(__dirname, './fs-storage.jsx')); demandProperty(module.exports, 'MysqlStorage', path.resolve(__dirname, './mysql-storage.jsx')); demandProperty(module.exports, 'MongoStorage', path.resolve(__dirname, './mongo-storage.jsx'));
すべての成功した実験!