1515 *
1616 */
1717
18- import { OrcaLoadReport } from "./generated/xds/data/orca/v3/OrcaLoadReport" ;
18+ import { OrcaLoadReport , OrcaLoadReport__Output } from "./generated/xds/data/orca/v3/OrcaLoadReport" ;
1919
2020import type { loadSync } from '@grpc/proto-loader' ;
2121import { ProtoGrpcType as OrcaProtoGrpcType } from "./generated/orca" ;
@@ -25,6 +25,7 @@ import { durationMessageToDuration, durationToMs } from "./duration";
2525import { Server } from "./server" ;
2626import { ChannelCredentials } from "./channel-credentials" ;
2727import { Channel } from "./channel" ;
28+ import { OnCallEnded } from "./picker" ;
2829
2930const loadedOrcaProto : OrcaProtoGrpcType | null = null ;
3031function loadOrcaProto ( ) : OrcaProtoGrpcType {
@@ -213,3 +214,35 @@ export function createOrcaClient(channel: Channel): OpenRcaServiceClient {
213214 const ClientClass = loadOrcaProto ( ) . xds . service . orca . v3 . OpenRcaService ;
214215 return new ClientClass ( 'unused' , ChannelCredentials . createInsecure ( ) , { channelOverride : channel } ) ;
215216}
217+
218+ export type MetricsListener = ( loadReport : OrcaLoadReport__Output ) => void ;
219+
220+ export const GRPC_METRICS_HEADER = 'endpoint-load-metrics-bin' ;
221+ const PARSED_LOAD_REPORT_KEY = 'grpc_orca_load_report' ;
222+
223+ /**
224+ * Create an onCallEnded callback for use in a picker.
225+ * @param listener The listener to handle metrics, whenever they are provided.
226+ * @param previousOnCallEnded The previous onCallEnded callback to propagate
227+ * to, if applicable.
228+ * @returns
229+ */
230+ export function createMetricsReader ( listener : MetricsListener , previousOnCallEnded : OnCallEnded | null ) : OnCallEnded {
231+ return ( code , details , metadata ) => {
232+ let parsedLoadReport = metadata . getOpaque ( PARSED_LOAD_REPORT_KEY ) as ( OrcaLoadReport__Output | undefined ) ;
233+ if ( parsedLoadReport ) {
234+ listener ( parsedLoadReport ) ;
235+ } else {
236+ const serializedLoadReport = metadata . get ( GRPC_METRICS_HEADER ) ;
237+ if ( serializedLoadReport . length > 0 ) {
238+ const orcaProto = loadOrcaProto ( ) ;
239+ parsedLoadReport = orcaProto . xds . data . orca . v3 . OrcaLoadReport . deserialize ( serializedLoadReport [ 0 ] as Buffer ) ;
240+ listener ( parsedLoadReport ) ;
241+ metadata . setOpaque ( PARSED_LOAD_REPORT_KEY , parsedLoadReport ) ;
242+ }
243+ }
244+ if ( previousOnCallEnded ) {
245+ previousOnCallEnded ( code , details , metadata ) ;
246+ }
247+ }
248+ }
0 commit comments