UNPKG

4.33 kBPlain TextView Raw
1/*
2 * Copyright 2019 gRPC authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18import { StatusObject } from './call-interface';
19import { Metadata } from './metadata';
20import { Status } from './constants';
21import { LoadBalancer } from './load-balancer';
22import { SubchannelInterface } from './subchannel-interface';
23
24export enum PickResultType {
25 COMPLETE,
26 QUEUE,
27 TRANSIENT_FAILURE,
28 DROP,
29}
30
31export interface PickResult {
32 pickResultType: PickResultType;
33 /**
34 * The subchannel to use as the transport for the call. Only meaningful if
35 * `pickResultType` is COMPLETE. If null, indicates that the call should be
36 * dropped.
37 */
38 subchannel: SubchannelInterface | null;
39 /**
40 * The status object to end the call with. Populated if and only if
41 * `pickResultType` is TRANSIENT_FAILURE.
42 */
43 status: StatusObject | null;
44 onCallStarted: (() => void) | null;
45 onCallEnded: ((statusCode: Status) => void) | null;
46}
47
48export interface CompletePickResult extends PickResult {
49 pickResultType: PickResultType.COMPLETE;
50 subchannel: SubchannelInterface | null;
51 status: null;
52 onCallStarted: (() => void) | null;
53 onCallEnded: ((statusCode: Status) => void) | null;
54}
55
56export interface QueuePickResult extends PickResult {
57 pickResultType: PickResultType.QUEUE;
58 subchannel: null;
59 status: null;
60 onCallStarted: null;
61 onCallEnded: null;
62}
63
64export interface TransientFailurePickResult extends PickResult {
65 pickResultType: PickResultType.TRANSIENT_FAILURE;
66 subchannel: null;
67 status: StatusObject;
68 onCallStarted: null;
69 onCallEnded: null;
70}
71
72export interface DropCallPickResult extends PickResult {
73 pickResultType: PickResultType.DROP;
74 subchannel: null;
75 status: StatusObject;
76 onCallStarted: null;
77 onCallEnded: null;
78}
79
80export interface PickArgs {
81 metadata: Metadata;
82 extraPickInfo: { [key: string]: string };
83}
84
85/**
86 * A proxy object representing the momentary state of a load balancer. Picks
87 * subchannels or returns other information based on that state. Should be
88 * replaced every time the load balancer changes state.
89 */
90export interface Picker {
91 pick(pickArgs: PickArgs): PickResult;
92}
93
94/**
95 * A standard picker representing a load balancer in the TRANSIENT_FAILURE
96 * state. Always responds to every pick request with an UNAVAILABLE status.
97 */
98export class UnavailablePicker implements Picker {
99 private status: StatusObject;
100 constructor(status?: StatusObject) {
101 if (status !== undefined) {
102 this.status = status;
103 } else {
104 this.status = {
105 code: Status.UNAVAILABLE,
106 details: 'No connection established',
107 metadata: new Metadata(),
108 };
109 }
110 }
111 pick(pickArgs: PickArgs): TransientFailurePickResult {
112 return {
113 pickResultType: PickResultType.TRANSIENT_FAILURE,
114 subchannel: null,
115 status: this.status,
116 onCallStarted: null,
117 onCallEnded: null,
118 };
119 }
120}
121
122/**
123 * A standard picker representing a load balancer in the IDLE or CONNECTING
124 * state. Always responds to every pick request with a QUEUE pick result
125 * indicating that the pick should be tried again with the next `Picker`. Also
126 * reports back to the load balancer that a connection should be established
127 * once any pick is attempted.
128 */
129export class QueuePicker {
130 private calledExitIdle = false;
131 // Constructed with a load balancer. Calls exitIdle on it the first time pick is called
132 constructor(private loadBalancer: LoadBalancer) {}
133
134 pick(pickArgs: PickArgs): QueuePickResult {
135 if (!this.calledExitIdle) {
136 process.nextTick(() => {
137 this.loadBalancer.exitIdle();
138 });
139 this.calledExitIdle = true;
140 }
141 return {
142 pickResultType: PickResultType.QUEUE,
143 subchannel: null,
144 status: null,
145 onCallStarted: null,
146 onCallEnded: null,
147 };
148 }
149}
150
\No newline at end of file