| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { StatusObject } from './call-interface'; |
| import { Metadata } from './metadata'; |
| import { Status } from './constants'; |
| import { LoadBalancer } from './load-balancer'; |
| import { SubchannelInterface } from './subchannel-interface'; |
|
|
| export enum PickResultType { |
| COMPLETE, |
| QUEUE, |
| TRANSIENT_FAILURE, |
| DROP, |
| } |
|
|
| export interface PickResult { |
| pickResultType: PickResultType; |
| |
| |
| |
| |
| |
| subchannel: SubchannelInterface | null; |
| |
| |
| |
| |
| status: StatusObject | null; |
| onCallStarted: (() => void) | null; |
| onCallEnded: ((statusCode: Status) => void) | null; |
| } |
|
|
| export interface CompletePickResult extends PickResult { |
| pickResultType: PickResultType.COMPLETE; |
| subchannel: SubchannelInterface | null; |
| status: null; |
| onCallStarted: (() => void) | null; |
| onCallEnded: ((statusCode: Status) => void) | null; |
| } |
|
|
| export interface QueuePickResult extends PickResult { |
| pickResultType: PickResultType.QUEUE; |
| subchannel: null; |
| status: null; |
| onCallStarted: null; |
| onCallEnded: null; |
| } |
|
|
| export interface TransientFailurePickResult extends PickResult { |
| pickResultType: PickResultType.TRANSIENT_FAILURE; |
| subchannel: null; |
| status: StatusObject; |
| onCallStarted: null; |
| onCallEnded: null; |
| } |
|
|
| export interface DropCallPickResult extends PickResult { |
| pickResultType: PickResultType.DROP; |
| subchannel: null; |
| status: StatusObject; |
| onCallStarted: null; |
| onCallEnded: null; |
| } |
|
|
| export interface PickArgs { |
| metadata: Metadata; |
| extraPickInfo: { [key: string]: string }; |
| } |
|
|
| |
| |
| |
| |
| |
| export interface Picker { |
| pick(pickArgs: PickArgs): PickResult; |
| } |
|
|
| |
| |
| |
| |
| export class UnavailablePicker implements Picker { |
| private status: StatusObject; |
| constructor(status?: Partial<StatusObject>) { |
| this.status = { |
| code: Status.UNAVAILABLE, |
| details: 'No connection established', |
| metadata: new Metadata(), |
| ...status, |
| }; |
| } |
| pick(pickArgs: PickArgs): TransientFailurePickResult { |
| return { |
| pickResultType: PickResultType.TRANSIENT_FAILURE, |
| subchannel: null, |
| status: this.status, |
| onCallStarted: null, |
| onCallEnded: null, |
| }; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export class QueuePicker { |
| private calledExitIdle = false; |
| |
| constructor( |
| private loadBalancer: LoadBalancer, |
| private childPicker?: Picker |
| ) {} |
|
|
| pick(pickArgs: PickArgs): PickResult { |
| if (!this.calledExitIdle) { |
| process.nextTick(() => { |
| this.loadBalancer.exitIdle(); |
| }); |
| this.calledExitIdle = true; |
| } |
| if (this.childPicker) { |
| return this.childPicker.pick(pickArgs); |
| } else { |
| return { |
| pickResultType: PickResultType.QUEUE, |
| subchannel: null, |
| status: null, |
| onCallStarted: null, |
| onCallEnded: null, |
| }; |
| } |
| } |
| } |
|
|