Path: blob/trunk/third_party/closure/goog/labs/net/webchannel/forwardchannelrequestpool.js
1865 views
// Copyright 2013 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview A pool of forward channel requests to enable real-time16* messaging from the client to server.17*18* @visibility {:internal}19*/202122goog.provide('goog.labs.net.webChannel.ForwardChannelRequestPool');2324goog.require('goog.array');25goog.require('goog.string');26goog.require('goog.structs.Set');2728goog.scope(function() {29/** @suppress {missingRequire} type checking only */30var ChannelRequest = goog.labs.net.webChannel.ChannelRequest;31323334/**35* This class represents the state of all forward channel requests.36*37* @param {number=} opt_maxPoolSize The maximum pool size.38*39* @constructor40* @final41*/42goog.labs.net.webChannel.ForwardChannelRequestPool = function(opt_maxPoolSize) {43/**44* THe max pool size as configured.45*46* @private {number}47*/48this.maxPoolSizeConfigured_ = opt_maxPoolSize ||49goog.labs.net.webChannel.ForwardChannelRequestPool.MAX_POOL_SIZE_;5051/**52* The current size limit of the request pool. This limit is meant to be53* read-only after the channel is fully opened.54*55* If SPDY is enabled, set it to the max pool size, which is also56* configurable.57*58* @private {number}59*/60this.maxSize_ = ForwardChannelRequestPool.isSpdyEnabled_() ?61this.maxPoolSizeConfigured_ :621;6364/**65* The container for all the pending request objects.66*67* @private {goog.structs.Set<ChannelRequest>}68*/69this.requestPool_ = null;7071if (this.maxSize_ > 1) {72this.requestPool_ = new goog.structs.Set();73}7475/**76* The single request object when the pool size is limited to one.77*78* @private {ChannelRequest}79*/80this.request_ = null;81};8283var ForwardChannelRequestPool =84goog.labs.net.webChannel.ForwardChannelRequestPool;858687/**88* The default size limit of the request pool.89*90* @private {number}91*/92ForwardChannelRequestPool.MAX_POOL_SIZE_ = 10;939495/**96* @return {boolean} True if SPDY is enabled for the current page using97* chrome specific APIs.98* @private99*/100ForwardChannelRequestPool.isSpdyEnabled_ = function() {101return !!(102goog.global.chrome && goog.global.chrome.loadTimes &&103goog.global.chrome.loadTimes() &&104goog.global.chrome.loadTimes().wasFetchedViaSpdy);105};106107108/**109* Once we know the client protocol (from the handshake), check if we need110* enable the request pool accordingly. This is more robust than using111* browser-internal APIs (specific to Chrome).112*113* @param {string} clientProtocol The client protocol114*/115ForwardChannelRequestPool.prototype.applyClientProtocol = function(116clientProtocol) {117if (this.requestPool_) {118return;119}120121if (goog.string.contains(clientProtocol, 'spdy') ||122goog.string.contains(clientProtocol, 'quic') ||123goog.string.contains(clientProtocol, 'h2')) {124this.maxSize_ = this.maxPoolSizeConfigured_;125this.requestPool_ = new goog.structs.Set();126if (this.request_) {127this.addRequest(this.request_);128this.request_ = null;129}130}131};132133134/**135* @return {boolean} True if the pool is full.136*/137ForwardChannelRequestPool.prototype.isFull = function() {138if (this.request_) {139return true;140}141142if (this.requestPool_) {143return this.requestPool_.getCount() >= this.maxSize_;144}145146return false;147};148149150/**151* @return {number} The current size limit.152*/153ForwardChannelRequestPool.prototype.getMaxSize = function() {154return this.maxSize_;155};156157158/**159* @return {number} The number of pending requests in the pool.160*/161ForwardChannelRequestPool.prototype.getRequestCount = function() {162if (this.request_) {163return 1;164}165166if (this.requestPool_) {167return this.requestPool_.getCount();168}169170return 0;171};172173174/**175* @param {ChannelRequest} req The channel request.176* @return {boolean} True if the request is a included inside the pool.177*/178ForwardChannelRequestPool.prototype.hasRequest = function(req) {179if (this.request_) {180return this.request_ == req;181}182183if (this.requestPool_) {184return this.requestPool_.contains(req);185}186187return false;188};189190191/**192* Adds a new request to the pool.193*194* @param {!ChannelRequest} req The new channel request.195*/196ForwardChannelRequestPool.prototype.addRequest = function(req) {197if (this.requestPool_) {198this.requestPool_.add(req);199} else {200this.request_ = req;201}202};203204205/**206* Removes the given request from the pool.207*208* @param {ChannelRequest} req The channel request.209* @return {boolean} Whether the request has been removed from the pool.210*/211ForwardChannelRequestPool.prototype.removeRequest = function(req) {212if (this.request_ && this.request_ == req) {213this.request_ = null;214return true;215}216217if (this.requestPool_ && this.requestPool_.contains(req)) {218this.requestPool_.remove(req);219return true;220}221222return false;223};224225226/**227* Clears the pool and cancel all the pending requests.228*/229ForwardChannelRequestPool.prototype.cancel = function() {230if (this.request_) {231this.request_.cancel();232this.request_ = null;233return;234}235236if (this.requestPool_ && !this.requestPool_.isEmpty()) {237goog.array.forEach(238this.requestPool_.getValues(), function(val) { val.cancel(); });239this.requestPool_.clear();240}241};242243244/**245* @return {boolean} Whether there are any pending requests.246*/247ForwardChannelRequestPool.prototype.hasPendingRequest = function() {248return (this.request_ != null) ||249(this.requestPool_ != null && !this.requestPool_.isEmpty());250};251252253/**254* Cancels all pending requests and force the completion of channel requests.255*256* Need go through the standard onRequestComplete logic to expose the max-retry257* failure in the standard way.258*259* @param {function(!ChannelRequest)} onComplete The completion callback.260* @return {boolean} true if any request has been forced to complete.261*/262ForwardChannelRequestPool.prototype.forceComplete = function(onComplete) {263if (this.request_ != null) {264this.request_.cancel();265onComplete(this.request_);266return true;267}268269if (this.requestPool_ && !this.requestPool_.isEmpty()) {270goog.array.forEach(this.requestPool_.getValues(), function(val) {271val.cancel();272onComplete(val);273});274return true;275}276277return false;278};279}); // goog.scope280281282