Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-gcp / build / src / gcp_channel_factory.js
diff --git a/legacy-libs/grpc-gcp/build/src/gcp_channel_factory.js b/legacy-libs/grpc-gcp/build/src/gcp_channel_factory.js
new file mode 100644 (file)
index 0000000..72ae76f
--- /dev/null
@@ -0,0 +1,249 @@
+"use strict";
+/**
+ * @license
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+const grpc = require("grpc");
+const channel_ref_1 = require("./channel_ref");
+const CLIENT_CHANNEL_ID = 'grpc_gcp.client_channel.id';
+/**
+ * A channel management factory that implements grpc.Channel APIs.
+ */
+class GcpChannelFactory {
+    /**
+     * @param address The address of the server to connect to.
+     * @param credentials Channel credentials to use when connecting
+     * @param options A map of channel options.
+     */
+    constructor(address, credentials, 
+    // tslint:disable-next-line:no-any options can be any object
+    options) {
+        this.methodToAffinity = {};
+        this.affinityKeyToChannelRef = {};
+        this.channelRefs = [];
+        if (!options) {
+            options = {};
+        }
+        if (typeof options !== 'object') {
+            throw new TypeError('Channel options must be an object with string keys and integer or string values');
+        }
+        this.maxSize = 10;
+        this.maxConcurrentStreamsLowWatermark = 100;
+        const gcpApiConfig = options.gcpApiConfig;
+        if (gcpApiConfig) {
+            if (gcpApiConfig.channelPool) {
+                const channelPool = gcpApiConfig.channelPool;
+                if (channelPool.maxSize)
+                    this.maxSize = channelPool.maxSize;
+                if (channelPool.maxConcurrentStreamsLowWatermark) {
+                    this.maxConcurrentStreamsLowWatermark =
+                        channelPool.maxConcurrentStreamsLowWatermark;
+                }
+            }
+            this.initMethodToAffinityMap(gcpApiConfig);
+        }
+        delete options.gcpApiConfig;
+        this.options = options;
+        this.target = address;
+        this.credentials = credentials;
+        // Initialize channel in the pool to avoid empty pool.
+        this.getChannelRef();
+    }
+    initMethodToAffinityMap(gcpApiConfig) {
+        const methodList = gcpApiConfig.method;
+        if (methodList) {
+            for (let i = 0; i < methodList.length; i++) {
+                const method = methodList[i];
+                const nameList = method.name;
+                if (nameList) {
+                    for (let j = 0; j < nameList.length; j++) {
+                        const methodName = nameList[j];
+                        if (method.affinity) {
+                            this.methodToAffinity[methodName] = method.affinity;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    /**
+     * Picks a grpc channel from the pool and wraps it with ChannelRef.
+     * @param affinityKey Affinity key to get the bound channel.
+     * @return Wrapper containing the grpc channel.
+     */
+    getChannelRef(affinityKey) {
+        if (affinityKey && this.affinityKeyToChannelRef[affinityKey]) {
+            // Chose an bound channel if affinityKey is specified.
+            return this.affinityKeyToChannelRef[affinityKey];
+        }
+        // Sort channel refs by active streams count.
+        this.channelRefs.sort((ref1, ref2) => {
+            return ref1.getActiveStreamsCount() - ref2.getActiveStreamsCount();
+        });
+        const size = this.channelRefs.length;
+        // Chose the channelRef that has the least busy channel.
+        if (size > 0 &&
+            this.channelRefs[0].getActiveStreamsCount() <
+                this.maxConcurrentStreamsLowWatermark) {
+            return this.channelRefs[0];
+        }
+        // If all existing channels are busy, and channel pool still has capacity,
+        // create a new channel in the pool.
+        if (size < this.maxSize) {
+            const channelOptions = Object.assign({ [CLIENT_CHANNEL_ID]: size }, this.options);
+            const grpcChannel = new grpc.Channel(this.target, this.credentials, channelOptions);
+            const channelRef = new channel_ref_1.ChannelRef(grpcChannel, size);
+            this.channelRefs.push(channelRef);
+            return channelRef;
+        }
+        else {
+            return this.channelRefs[0];
+        }
+    }
+    /**
+     * Get AffinityConfig associated with a certain method.
+     * @param methodName Method name of the request.
+     */
+    getAffinityConfig(methodName) {
+        return this.methodToAffinity[methodName];
+    }
+    /**
+     * Bind channel with affinity key.
+     * @param channelRef ChannelRef instance that contains the grpc channel.
+     * @param affinityKey The affinity key used for binding the channel.
+     */
+    bind(channelRef, affinityKey) {
+        if (!affinityKey || !channelRef)
+            return;
+        const existingChannelRef = this.affinityKeyToChannelRef[affinityKey];
+        if (!existingChannelRef) {
+            this.affinityKeyToChannelRef[affinityKey] = channelRef;
+        }
+        this.affinityKeyToChannelRef[affinityKey].affinityCountIncr();
+    }
+    /**
+     * Unbind channel with affinity key.
+     * @param boundKey Affinity key bound to a channel.
+     */
+    unbind(boundKey) {
+        if (!boundKey)
+            return;
+        const boundChannelRef = this.affinityKeyToChannelRef[boundKey];
+        if (boundChannelRef) {
+            boundChannelRef.affinityCountDecr();
+            if (boundChannelRef.getAffinityCount() <= 0) {
+                delete this.affinityKeyToChannelRef[boundKey];
+            }
+        }
+    }
+    /**
+     * Close all channels in the channel pool.
+     */
+    close() {
+        this.channelRefs.forEach(ref => {
+            ref.getChannel().close();
+        });
+    }
+    getTarget() {
+        return this.target;
+    }
+    /**
+     * Get the current connectivity state of the channel pool.
+     * @param tryToConnect If true, the channel will start connecting if it is
+     *     idle. Otherwise, idle channels will only start connecting when a
+     *     call starts.
+     * @return connectivity state of channel pool.
+     */
+    getConnectivityState(tryToConnect) {
+        let ready = 0;
+        let idle = 0;
+        let connecting = 0;
+        let transientFailure = 0;
+        let shutdown = 0;
+        for (let i = 0; i < this.channelRefs.length; i++) {
+            const grpcChannel = this.channelRefs[i].getChannel();
+            const state = grpcChannel.getConnectivityState(tryToConnect);
+            switch (state) {
+                case grpc.connectivityState.READY:
+                    ready++;
+                    break;
+                case grpc.connectivityState.SHUTDOWN:
+                    shutdown++;
+                    break;
+                case grpc.connectivityState.TRANSIENT_FAILURE:
+                    transientFailure++;
+                    break;
+                case grpc.connectivityState.CONNECTING:
+                    connecting++;
+                    break;
+                case grpc.connectivityState.IDLE:
+                    idle++;
+                    break;
+                default:
+                    break;
+            }
+        }
+        if (ready > 0) {
+            return grpc.connectivityState.READY;
+        }
+        else if (connecting > 0) {
+            return grpc.connectivityState.CONNECTING;
+        }
+        else if (transientFailure > 0) {
+            return grpc.connectivityState.TRANSIENT_FAILURE;
+        }
+        else if (idle > 0) {
+            return grpc.connectivityState.IDLE;
+        }
+        else if (shutdown > 0) {
+            return grpc.connectivityState.SHUTDOWN;
+        }
+        throw new Error('Cannot get connectivity state because no channel provides valid state.');
+    }
+    /**
+     * Watch for connectivity state changes. Currently This function will throw
+     * not implemented error because the implementation requires lot of work but
+     * has little use cases.
+     * @param currentState The state to watch for transitions from. This should
+     *     always be populated by calling getConnectivityState immediately before.
+     * @param deadline A deadline for waiting for a state change
+     * @param callback Called with no error when the state changes, or with an
+     *     error if the deadline passes without a state change
+     */
+    watchConnectivityState(currentState, deadline, callback) {
+        throw new Error('Function watchConnectivityState not implemented!');
+    }
+    /**
+     * Create a call object. This function will not be called when using
+     * grpc.Client class. But since it's a public function of grpc.Channel,
+     * It needs to be implemented for potential use cases.
+     * @param method The full method string to request.
+     * @param deadline The call deadline.
+     * @param host A host string override for making the request.
+     * @param parentCall A server call to propagate some information from.
+     * @param propagateFlags A bitwise combination of elements of
+     *     {@link grpc.propagate} that indicates what information to propagate
+     *     from parentCall.
+     * @return a grpc call object.
+     */
+    createCall(method, deadline, host, parentCall, propagateFlags) {
+        const grpcChannel = this.getChannelRef().getChannel();
+        return grpcChannel.createCall(method, deadline, host, parentCall, propagateFlags);
+    }
+}
+exports.GcpChannelFactory = GcpChannelFactory;
+//# sourceMappingURL=gcp_channel_factory.js.map
\ No newline at end of file