database-jones/Adapter/common/DictionaryCall.js (52 lines of code) (raw):

/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ "use strict"; var unified_debug = require("unified_debug"), udebug = unified_debug.getLogger("DictionaryCall.js"), assert = require("assert"), QueuedAsyncCall = require("./QueuedAsyncCall").QueuedAsyncCall; /* Calls into the data dictionary often arrive as a large number of accesses to the same item all at once. Queue() provides a way to serialize all calls into the dictionary, run each call once, and distribute the results to every caller. */ function Call() { this.callbacks = {}; this.apiCall = null; } Call.prototype.makeGroupCallback = function(key) { var callbackList = this.callbacks[key]; var owner = this; return function(param1, param2) { var i; udebug.log("GroupCallback for", key, "with", callbackList.length, callbackList.length == 1 ? "user" : "users"); for(i = 0 ; i < callbackList.length ; i++) { callbackList[i](param1, param2); } owner.callbacks[key] = []; // Clear the list }; }; Call.prototype.queueExecCall = function(execQueue, impl, arg, masterCallback) { var apiCall = new QueuedAsyncCall(execQueue, masterCallback); apiCall.impl = impl; apiCall.arg = arg; apiCall.run = function() { this.impl(this.arg, this.callback); }; this.apiCall = apiCall; this.apiCall.enqueue(); }; /* add() returns true if the exec call should be created, false if it already exists */ Call.prototype.add = function(key, callback) { if(this.callbacks[key] && this.callbacks[key].length) { this.callbacks[key].push(callback); return false; } this.callbacks[key] = [ callback ]; return true; }; /* Queue() manages the common case for Call() by providing its own execQueue and using the default GroupCallback */ function Queue() { this.execQueue = []; this.call = new Call(); } Queue.prototype.add = function(key, impl, arg, callback) { if(this.call.add(key, callback)) { this.call.queueExecCall(this.execQueue, impl, arg, this.call.makeGroupCallback(key)); } }; exports.Call = Call; exports.Queue = Queue;