Skip to content

grpc-js: Implement ORCA server-side per-call metrics #2978

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/grpc-js-xds/deps/xds
Submodule xds updated 71 files
+1 −1 .bazelversion
+34 −52 bazel/api_build_system.bzl
+64 −10 bazel/dependency_imports.bzl
+38 −0 bazel/external_proto_deps.bzl
+4 −0 bazel/repositories.bzl
+21 −13 bazel/repository_locations.bzl
+3 −1 ci/azure-pipelines.yml
+2 −7 go/udpa/annotations/migrate.pb.go
+2 −7 go/udpa/annotations/security.pb.go
+2 −7 go/udpa/annotations/sensitive.pb.go
+2 −7 go/udpa/annotations/status.pb.go
+2 −7 go/udpa/annotations/versioning.pb.go
+2 −7 go/udpa/data/orca/v1/orca_load_report.pb.go
+25 −33 go/udpa/service/orca/v1/orca.pb.go
+16 −23 go/udpa/type/v1/typed_struct.pb.go
+2 −7 go/xds/annotations/v3/migrate.pb.go
+2 −7 go/xds/annotations/v3/security.pb.go
+2 −7 go/xds/annotations/v3/sensitive.pb.go
+2 −7 go/xds/annotations/v3/status.pb.go
+2 −7 go/xds/annotations/v3/versioning.pb.go
+2 −7 go/xds/core/v3/authority.pb.go
+172 −0 go/xds/core/v3/cidr.pb.go
+116 −0 go/xds/core/v3/cidr.pb.validate.go
+9 −13 go/xds/core/v3/collection_entry.pb.go
+2 −7 go/xds/core/v3/context_params.pb.go
+7 −12 go/xds/core/v3/extension.pb.go
+6 −11 go/xds/core/v3/resource.pb.go
+4 −7 go/xds/core/v3/resource_locator.pb.go
+2 −7 go/xds/core/v3/resource_name.pb.go
+108 −58 go/xds/data/orca/v3/orca_load_report.pb.go
+25 −2 go/xds/data/orca/v3/orca_load_report.pb.validate.go
+26 −33 go/xds/service/orca/v3/orca.pb.go
+172 −0 go/xds/type/matcher/v3/cel.pb.go
+117 −0 go/xds/type/matcher/v3/cel.pb.validate.go
+242 −0 go/xds/type/matcher/v3/domain.pb.go
+201 −0 go/xds/type/matcher/v3/domain.pb.validate.go
+143 −0 go/xds/type/matcher/v3/http_inputs.pb.go
+102 −0 go/xds/type/matcher/v3/http_inputs.pb.validate.go
+256 −0 go/xds/type/matcher/v3/ip.pb.go
+214 −0 go/xds/type/matcher/v3/ip.pb.validate.go
+16 −16 go/xds/type/matcher/v3/matcher.pb.go
+0 −6 go/xds/type/matcher/v3/matcher.pb.validate.go
+539 −0 go/xds/type/matcher/v3/range.pb.go
+580 −0 go/xds/type/matcher/v3/range.pb.validate.go
+3 −7 go/xds/type/matcher/v3/regex.pb.go
+3 −7 go/xds/type/matcher/v3/string.pb.go
+294 −0 go/xds/type/v3/cel.pb.go
+225 −0 go/xds/type/v3/cel.pb.validate.go
+298 −0 go/xds/type/v3/range.pb.go
+239 −0 go/xds/type/v3/range.pb.validate.go
+16 −24 go/xds/type/v3/typed_struct.pb.go
+4 −19 proposals/TP1-xds-transport-next.md
+923 −0 proposals/TP2-dynamically-generated-cacheable-xds-resources.md
+0 −2 udpa/service/orca/v1/orca.proto
+0 −1 udpa/type/v1/typed_struct.proto
+25 −0 xds/core/v3/cidr.proto
+7 −5 xds/core/v3/collection_entry.proto
+1 −0 xds/core/v3/context_params.proto
+25 −3 xds/data/orca/v3/orca_load_report.proto
+0 −2 xds/service/orca/v3/orca.proto
+1 −0 xds/type/matcher/v3/BUILD
+42 −0 xds/type/matcher/v3/cel.proto
+46 −0 xds/type/matcher/v3/domain.proto
+27 −0 xds/type/matcher/v3/http_inputs.proto
+53 −0 xds/type/matcher/v3/ip.proto
+3 −6 xds/type/matcher/v3/matcher.proto
+69 −0 xds/type/matcher/v3/range.proto
+7 −1 xds/type/v3/BUILD
+54 −0 xds/type/v3/cel.proto
+40 −0 xds/type/v3/range.proto
+2 −1 xds/type/v3/typed_struct.proto
31 changes: 31 additions & 0 deletions packages/grpc-js/copy-protos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2025 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.
*
*/

/**
* Copy xDS protos that are needed for ORCA into this directory.
*/

const fs = require('fs');

fs.mkdirSync(__dirname + '/proto/protoc-gen-validate/validate', { recursive: true });
fs.mkdirSync(__dirname + '/proto/xds/xds/data/orca/v3', { recursive: true });
fs.mkdirSync(__dirname + '/proto/xds/xds/service/orca/v3', { recursive: true });
fs.copyFileSync(__dirname + '/../grpc-js-xds/deps/protoc-gen-validate/LICENSE', __dirname + '/proto/protoc-gen-validate/LICENSE');
fs.copyFileSync(__dirname + '/../grpc-js-xds/deps/protoc-gen-validate/validate/validate.proto', __dirname + '/proto/protoc-gen-validate/validate/validate.proto');
fs.copyFileSync(__dirname + '/../grpc-js-xds/deps/xds/LICENSE', __dirname + '/proto/xds/LICENSE')
fs.copyFileSync(__dirname + '/../grpc-js-xds/deps/xds/xds/data/orca/v3/orca_load_report.proto', __dirname + '/proto/xds/xds/data/orca/v3/orca_load_report.proto');
fs.copyFileSync(__dirname + '/../grpc-js-xds/deps/xds/xds/service/orca/v3/orca.proto', __dirname + '/proto/xds/xds/service/orca/v3/orca.proto');
12 changes: 7 additions & 5 deletions packages/grpc-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,25 @@
"compile": "tsc -p .",
"format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts",
"lint": "eslint src/*.ts test/*.ts",
"prepare": "npm run generate-types && npm run generate-test-types && npm run compile",
"prepare": "npm run copy-protos && npm run generate-types && npm run generate-test-types && npm run compile",
"test": "gulp test",
"check": "npm run lint",
"fix": "eslint --fix src/*.ts test/*.ts",
"pretest": "npm run generate-types && npm run generate-test-types && npm run compile",
"posttest": "npm run check && madge -c ./build/src",
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs test/fixtures/ -O src/generated/ --grpcLib ../index channelz.proto",
"generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto"
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs proto/ proto/xds/ proto/protoc-gen-validate/ -O src/generated/ --grpcLib ../index channelz.proto xds/service/orca/v3/orca.proto",
"generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto",
"copy-protos": "node ./copy-protos"
},
"dependencies": {
"@grpc/proto-loader": "^0.7.13",
"@grpc/proto-loader": "^0.8.0",
"@js-sdsl/ordered-map": "^4.4.2"
},
"files": [
"src/**/*.ts",
"build/src/**/*.{js,d.ts,js.map}",
"proto/*.proto",
"proto/**/*.proto",
"proto/**/LICENSE",
"LICENSE",
"deps/envoy-api/envoy/api/v2/**/*.proto",
"deps/envoy-api/envoy/config/**/*.proto",
Expand Down
2 changes: 2 additions & 0 deletions packages/grpc-js/src/channel-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface ChannelOptions {
'grpc.lb.ring_hash.ring_size_cap'?: number;
'grpc-node.retry_max_attempts_limit'?: number;
'grpc-node.flow_control_window'?: number;
'grpc.server_call_metric_recording'?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
Expand Down Expand Up @@ -103,6 +104,7 @@ export const recognizedOptions = {
'grpc.lb.ring_hash.ring_size_cap': true,
'grpc-node.retry_max_attempts_limit': true,
'grpc-node.flow_control_window': true,
'grpc.server_call_metric_recording': true
};

export function channelOptionsEqual(
Expand Down
59 changes: 59 additions & 0 deletions packages/grpc-js/src/generated/google/protobuf/DescriptorProto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Original file: null

import type { FieldDescriptorProto as _google_protobuf_FieldDescriptorProto, FieldDescriptorProto__Output as _google_protobuf_FieldDescriptorProto__Output } from '../../google/protobuf/FieldDescriptorProto';
import type { DescriptorProto as _google_protobuf_DescriptorProto, DescriptorProto__Output as _google_protobuf_DescriptorProto__Output } from '../../google/protobuf/DescriptorProto';
import type { EnumDescriptorProto as _google_protobuf_EnumDescriptorProto, EnumDescriptorProto__Output as _google_protobuf_EnumDescriptorProto__Output } from '../../google/protobuf/EnumDescriptorProto';
import type { MessageOptions as _google_protobuf_MessageOptions, MessageOptions__Output as _google_protobuf_MessageOptions__Output } from '../../google/protobuf/MessageOptions';
import type { OneofDescriptorProto as _google_protobuf_OneofDescriptorProto, OneofDescriptorProto__Output as _google_protobuf_OneofDescriptorProto__Output } from '../../google/protobuf/OneofDescriptorProto';
import type { SymbolVisibility as _google_protobuf_SymbolVisibility, SymbolVisibility__Output as _google_protobuf_SymbolVisibility__Output } from '../../google/protobuf/SymbolVisibility';
import type { ExtensionRangeOptions as _google_protobuf_ExtensionRangeOptions, ExtensionRangeOptions__Output as _google_protobuf_ExtensionRangeOptions__Output } from '../../google/protobuf/ExtensionRangeOptions';

export interface _google_protobuf_DescriptorProto_ExtensionRange {
'start'?: (number);
'end'?: (number);
'options'?: (_google_protobuf_ExtensionRangeOptions | null);
}

export interface _google_protobuf_DescriptorProto_ExtensionRange__Output {
'start': (number);
'end': (number);
'options': (_google_protobuf_ExtensionRangeOptions__Output | null);
}

export interface _google_protobuf_DescriptorProto_ReservedRange {
'start'?: (number);
'end'?: (number);
}

export interface _google_protobuf_DescriptorProto_ReservedRange__Output {
'start': (number);
'end': (number);
}

export interface DescriptorProto {
'name'?: (string);
'field'?: (_google_protobuf_FieldDescriptorProto)[];
'nestedType'?: (_google_protobuf_DescriptorProto)[];
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[];
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
'options'?: (_google_protobuf_MessageOptions | null);
'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[];
'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[];
'reservedName'?: (string)[];
'visibility'?: (_google_protobuf_SymbolVisibility);
}

export interface DescriptorProto__Output {
'name': (string);
'field': (_google_protobuf_FieldDescriptorProto__Output)[];
'nestedType': (_google_protobuf_DescriptorProto__Output)[];
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[];
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
'options': (_google_protobuf_MessageOptions__Output | null);
'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[];
'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[];
'reservedName': (string)[];
'visibility': (_google_protobuf_SymbolVisibility__Output);
}
44 changes: 44 additions & 0 deletions packages/grpc-js/src/generated/google/protobuf/Edition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Original file: null

export const Edition = {
EDITION_UNKNOWN: 'EDITION_UNKNOWN',
EDITION_LEGACY: 'EDITION_LEGACY',
EDITION_PROTO2: 'EDITION_PROTO2',
EDITION_PROTO3: 'EDITION_PROTO3',
EDITION_2023: 'EDITION_2023',
EDITION_2024: 'EDITION_2024',
EDITION_1_TEST_ONLY: 'EDITION_1_TEST_ONLY',
EDITION_2_TEST_ONLY: 'EDITION_2_TEST_ONLY',
EDITION_99997_TEST_ONLY: 'EDITION_99997_TEST_ONLY',
EDITION_99998_TEST_ONLY: 'EDITION_99998_TEST_ONLY',
EDITION_99999_TEST_ONLY: 'EDITION_99999_TEST_ONLY',
EDITION_MAX: 'EDITION_MAX',
} as const;

export type Edition =
| 'EDITION_UNKNOWN'
| 0
| 'EDITION_LEGACY'
| 900
| 'EDITION_PROTO2'
| 998
| 'EDITION_PROTO3'
| 999
| 'EDITION_2023'
| 1000
| 'EDITION_2024'
| 1001
| 'EDITION_1_TEST_ONLY'
| 1
| 'EDITION_2_TEST_ONLY'
| 2
| 'EDITION_99997_TEST_ONLY'
| 99997
| 'EDITION_99998_TEST_ONLY'
| 99998
| 'EDITION_99999_TEST_ONLY'
| 99999
| 'EDITION_MAX'
| 2147483647

export type Edition__Output = typeof Edition[keyof typeof Edition]
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Original file: null

import type { EnumValueDescriptorProto as _google_protobuf_EnumValueDescriptorProto, EnumValueDescriptorProto__Output as _google_protobuf_EnumValueDescriptorProto__Output } from '../../google/protobuf/EnumValueDescriptorProto';
import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output as _google_protobuf_EnumOptions__Output } from '../../google/protobuf/EnumOptions';
import type { SymbolVisibility as _google_protobuf_SymbolVisibility, SymbolVisibility__Output as _google_protobuf_SymbolVisibility__Output } from '../../google/protobuf/SymbolVisibility';

export interface _google_protobuf_EnumDescriptorProto_EnumReservedRange {
'start'?: (number);
'end'?: (number);
}

export interface _google_protobuf_EnumDescriptorProto_EnumReservedRange__Output {
'start': (number);
'end': (number);
}

export interface EnumDescriptorProto {
'name'?: (string);
'value'?: (_google_protobuf_EnumValueDescriptorProto)[];
'options'?: (_google_protobuf_EnumOptions | null);
'reservedRange'?: (_google_protobuf_EnumDescriptorProto_EnumReservedRange)[];
'reservedName'?: (string)[];
'visibility'?: (_google_protobuf_SymbolVisibility);
}

export interface EnumDescriptorProto__Output {
'name': (string);
'value': (_google_protobuf_EnumValueDescriptorProto__Output)[];
'options': (_google_protobuf_EnumOptions__Output | null);
'reservedRange': (_google_protobuf_EnumDescriptorProto_EnumReservedRange__Output)[];
'reservedName': (string)[];
'visibility': (_google_protobuf_SymbolVisibility__Output);
}
26 changes: 26 additions & 0 deletions packages/grpc-js/src/generated/google/protobuf/EnumOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Original file: null

import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';

export interface EnumOptions {
'allowAlias'?: (boolean);
'deprecated'?: (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}

export interface EnumOptions__Output {
'allowAlias': (boolean);
'deprecated': (boolean);
/**
* @deprecated
*/
'deprecatedLegacyJsonFieldConflicts': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Original file: null

import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOptions__Output as _google_protobuf_EnumValueOptions__Output } from '../../google/protobuf/EnumValueOptions';

export interface EnumValueDescriptorProto {
'name'?: (string);
'number'?: (number);
'options'?: (_google_protobuf_EnumValueOptions | null);
}

export interface EnumValueDescriptorProto__Output {
'name': (string);
'number': (number);
'options': (_google_protobuf_EnumValueOptions__Output | null);
}
21 changes: 21 additions & 0 deletions packages/grpc-js/src/generated/google/protobuf/EnumValueOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Original file: null

import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { _google_protobuf_FieldOptions_FeatureSupport, _google_protobuf_FieldOptions_FeatureSupport__Output } from '../../google/protobuf/FieldOptions';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';

export interface EnumValueOptions {
'deprecated'?: (boolean);
'features'?: (_google_protobuf_FeatureSet | null);
'debugRedact'?: (boolean);
'featureSupport'?: (_google_protobuf_FieldOptions_FeatureSupport | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}

export interface EnumValueOptions__Output {
'deprecated': (boolean);
'features': (_google_protobuf_FeatureSet__Output | null);
'debugRedact': (boolean);
'featureSupport': (_google_protobuf_FieldOptions_FeatureSupport__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Original file: null

import type { FeatureSet as _google_protobuf_FeatureSet, FeatureSet__Output as _google_protobuf_FeatureSet__Output } from '../../google/protobuf/FeatureSet';
import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption';

export interface _google_protobuf_ExtensionRangeOptions_Declaration {
'number'?: (number);
'fullName'?: (string);
'type'?: (string);
'reserved'?: (boolean);
'repeated'?: (boolean);
}

export interface _google_protobuf_ExtensionRangeOptions_Declaration__Output {
'number': (number);
'fullName': (string);
'type': (string);
'reserved': (boolean);
'repeated': (boolean);
}

// Original file: null

export const _google_protobuf_ExtensionRangeOptions_VerificationState = {
DECLARATION: 'DECLARATION',
UNVERIFIED: 'UNVERIFIED',
} as const;

export type _google_protobuf_ExtensionRangeOptions_VerificationState =
| 'DECLARATION'
| 0
| 'UNVERIFIED'
| 1

export type _google_protobuf_ExtensionRangeOptions_VerificationState__Output = typeof _google_protobuf_ExtensionRangeOptions_VerificationState[keyof typeof _google_protobuf_ExtensionRangeOptions_VerificationState]

export interface ExtensionRangeOptions {
'declaration'?: (_google_protobuf_ExtensionRangeOptions_Declaration)[];
'verification'?: (_google_protobuf_ExtensionRangeOptions_VerificationState);
'features'?: (_google_protobuf_FeatureSet | null);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
}

export interface ExtensionRangeOptions__Output {
'declaration': (_google_protobuf_ExtensionRangeOptions_Declaration__Output)[];
'verification': (_google_protobuf_ExtensionRangeOptions_VerificationState__Output);
'features': (_google_protobuf_FeatureSet__Output | null);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
}
Loading
Loading