[cluster telemetry] Internal service conversions#7631
Conversation
11472e0 to
7038300
Compare
dc482ed to
2477dc0
Compare
2477dc0 to
d3b27aa
Compare
0af693e to
a412db6
Compare
a412db6 to
94c4271
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
lib/storage/src/content_manager/conversions.rs (1)
267-295: Prefer explicit type conversions over.into()and.try_into().Lines 273-275 and 291 use implicit conversions. As per coding guidelines, prefer explicit conversions for better code clarity:
match action { - Some(grpc::alias_operations::Action::CreateAlias(create)) => Ok(create.into()), - Some(grpc::alias_operations::Action::DeleteAlias(delete)) => Ok(delete.into()), - Some(grpc::alias_operations::Action::RenameAlias(rename)) => Ok(rename.into()), + Some(grpc::alias_operations::Action::CreateAlias(create)) => Ok(AliasOperations::from(create)), + Some(grpc::alias_operations::Action::DeleteAlias(delete)) => Ok(AliasOperations::from(delete)), + Some(grpc::alias_operations::Action::RenameAlias(rename)) => Ok(AliasOperations::from(rename)), _ => Err(Status::invalid_argument("Malformed AliasOperation type")), }And in
ChangeAliasesconversion:let actions: Vec<AliasOperations> = actions .into_iter() - .map(|a| a.try_into()) + .map(|a| AliasOperations::try_from(a)) .collect::<Result<_, _>>()?;Based on coding guidelines: Prefer explicit
SomeType::from(x)over implicitx.into()in Rust.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
docs/redoc/master/openapi.json(3 hunks)lib/api/src/grpc/proto/telemetry_internal.proto(4 hunks)lib/api/src/grpc/qdrant.rs(4 hunks)lib/collection/src/collection/telemetry.rs(1 hunks)lib/collection/src/operations/conversions.rs(3 hunks)lib/collection/src/operations/types.rs(2 hunks)lib/collection/src/shards/resharding.rs(3 hunks)lib/collection/src/shards/shard_holder/mod.rs(4 hunks)lib/collection/src/shards/shard_holder/resharding.rs(10 hunks)lib/collection/src/telemetry.rs(2 hunks)lib/storage/src/content_manager/conversions.rs(10 hunks)src/common/metrics.rs(1 hunks)src/common/telemetry.rs(5 hunks)src/common/telemetry_ops/conversions.rs(1 hunks)src/common/telemetry_ops/mod.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- src/common/metrics.rs
- lib/collection/src/operations/types.rs
- src/common/telemetry_ops/conversions.rs
- lib/collection/src/shards/shard_holder/mod.rs
- lib/collection/src/shards/shard_holder/resharding.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/review-rules.md)
**/*.rs: Prefer explicitSomeType::from(x)over implicitx.into()in Rust
In new code, don't usetransmute_from_u8,transmute_to_u8,transmute_from_u8_to_slice,transmute_from_u8_to_mut_slice,transmute_to_u8_slice- usebytemuckorzerocopycrates instead
Prefer explicit exhaustive matches over catch-all_arm in Rust match expressions, so we don't miss handling new enum variants when they are added later (exceptions: tests and benchmarks, or when sure new variants won't affect logic)
Prefer explicit field ignoring using: _over using..in Rust struct destructuring (exceptions: tests and benchmarks, or when sure new fields won't affect logic)
Files:
lib/collection/src/operations/conversions.rslib/collection/src/collection/telemetry.rslib/collection/src/shards/resharding.rssrc/common/telemetry_ops/mod.rslib/collection/src/telemetry.rslib/api/src/grpc/qdrant.rssrc/common/telemetry.rslib/storage/src/content_manager/conversions.rs
🧠 Learnings (5)
📚 Learning: 2025-09-16T19:14:17.614Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7183
File: lib/api/src/grpc/qdrant.rs:4263-4273
Timestamp: 2025-09-16T19:14:17.614Z
Learning: In qdrant, lib/api/src/grpc/qdrant.rs is auto-generated by prost-build; do not edit it directly. Make changes in lib/api/src/grpc/proto/points.proto (e.g., add [deprecated=true], doc comments, or encoding options), then regenerate the Rust code.
Applied to files:
lib/collection/src/operations/conversions.rslib/api/src/grpc/qdrant.rslib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-09-08T08:47:43.795Z
Learnt from: timvisee
Repo: qdrant/qdrant PR: 7188
File: lib/collection/src/update_handler.rs:810-813
Timestamp: 2025-09-08T08:47:43.795Z
Learning: In the Qdrant codebase, CollectionId implements traits that allow &CollectionId to convert Into<String>, so passing &collection_name to functions requiring Into<String> works correctly without needing .clone() or .to_string().
Applied to files:
lib/collection/src/operations/conversions.rslib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:30:02.986Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: lib/collection/src/operations/verification/update.rs:158-174
Timestamp: 2025-08-10T18:30:02.986Z
Learning: In Qdrant's strict mode verification code (lib/collection/src/operations/verification/update.rs), exhaustive pattern matching without `..` is intentionally used for structs like PointsBatch and PointsList. This design pattern ensures compilation fails when new fields are added, forcing developers to explicitly consider how new fields should be handled in the indexed_filter_write method. This provides visibility and compile-time safety for struct evolution.
Applied to files:
lib/collection/src/operations/conversions.rssrc/common/telemetry.rs
📚 Learning: 2025-08-15T15:56:36.821Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7065
File: lib/collection/src/operations/universal_query/shard_query.rs:0-0
Timestamp: 2025-08-15T15:56:36.821Z
Learning: Internal gRPC APIs in Qdrant don't require additional runtime validation when proto-level validation is already configured via build.rs range constraints.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:25:16.206Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:10626-10634
Timestamp: 2025-08-10T18:25:16.206Z
Learning: In Qdrant, docs/redoc/master/openapi.json is autogenerated from the Rust REST schema definitions (e.g., lib/api/src/rest/schema.rs). To change OpenAPI descriptions, update the Rust struct field doc comments/attributes rather than editing the JSON directly.
Applied to files:
lib/storage/src/content_manager/conversions.rs
🧬 Code graph analysis (3)
lib/collection/src/collection/telemetry.rs (1)
lib/collection/src/telemetry.rs (7)
from(162-183)from(222-232)from(236-246)from(250-260)from(288-297)from(331-351)from(417-448)
src/common/telemetry.rs (4)
lib/collection/src/operations/verification/mod.rs (1)
new_unchecked_verification_pass(26-28)src/common/telemetry_ops/app_telemetry.rs (1)
collect(76-100)lib/collection/src/telemetry.rs (11)
try_from(200-218)try_from(266-284)try_from(303-327)try_from(357-413)from(162-183)from(222-232)from(236-246)from(250-260)from(288-297)from(331-351)from(417-448)lib/common/common/src/types.rs (1)
new(40-42)
lib/storage/src/content_manager/conversions.rs (1)
lib/api/src/grpc/conversions.rs (16)
from(132-147)from(151-162)from(166-177)from(181-188)from(192-204)from(208-224)from(228-240)from(244-249)from(253-286)from(290-295)from(299-311)from(315-327)from(331-342)from(346-357)from(361-372)from(376-402)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: e2e-tests
- GitHub Check: test-shard-snapshot-api-s3-minio
- GitHub Check: rust-tests (macos-latest)
- GitHub Check: test-consistency
- GitHub Check: rust-tests (windows-latest)
- GitHub Check: test-consensus-compose
- GitHub Check: rust-tests (ubuntu-latest)
- GitHub Check: integration-tests
- GitHub Check: integration-tests-consensus
- GitHub Check: Build Qdrant Edge Python bindings
- GitHub Check: lint
🔇 Additional comments (29)
lib/collection/src/shards/resharding.rs (1)
65-70: The match expressions in the codebase already handle the newWriteHashRingCommittedvariant exhaustively. No issues found.The only match expression on
ReshardingStage(inlib/collection/src/shards/shard_holder/resharding.rs:632) explicitly handles all three variants without catch-all patterns:
MigratingPoints | ReadHashRingCommittedWriteHashRingCommittedNoneThe conversion functions in telemetry.rs and grpc/qdrant.rs also handle all variants. No verification is required.
Likely an incorrect or invalid review comment.
src/common/telemetry_ops/mod.rs (1)
4-4: LGTM!The private module declaration for telemetry conversions is appropriate and follows standard Rust module organization patterns.
lib/collection/src/collection/telemetry.rs (1)
40-47: LGTM!The changes correctly wrap telemetry fields in
Some(...)to align with the updated optional field signatures. The use of explicitCollectionConfigTelemetry::from(...)follows the coding guidelines, and the.then_some()pattern for conditionalshard_clean_tasksis idiomatic Rust.src/common/telemetry.rs (3)
49-51: LGTM!The field visibility and optionality changes align with the gRPC telemetry schema updates. Making
appoptional withskip_serializing_ifis appropriate for fields that may not be present in internal service telemetry.
186-222: LGTM!The reverse conversion from
TelemetryDatatogrpc::PeerTelemetryis well-structured:
- Uses explicit field destructuring with
: _following coding guidelines- Properly handles the
CollectionTelemetryEnum::Aggregatedvariant with a clear error message- Applies explicit type conversions (
grpc::CollectionTelemetry::from,grpc::ClusterTelemetry::from)
149-184: The emptyidassignment is intentional and correct.The
grpc::PeerTelemetrymessage reserves fields 1 (id) and 2 (app) in the proto definition, so peer telemetry from remote nodes never includes process-specific identifiers. Settingid: "".to_string()is the appropriate placeholder for converting peer telemetry intoTelemetryData, whereidis a non-optionalStringfield. This aligns with the bidirectional conversion logic: when converting back to gRPC (line 191), these fields are explicitly ignored since they don't belong in peer telemetry messages. The conversion correctly handles all other optional fields.lib/collection/src/operations/conversions.rs (3)
1419-1419: LGTM!Explicitly ignoring the
stagefield with a clear comment is good practice. The comment explains thatstageis only communicated forReshardingTelemetryin the internal service, making the intent clear for future maintainers.
1439-1446: LGTM!The bidirectional conversion between gRPC and internal
ReshardingDirectiontypes uses exhaustive pattern matching without a catch-all_arm, following the coding guidelines. This ensures that any new enum variants added in the future will be caught at compile time.
1590-1603: LGTM!The conversion from internal to gRPC
ShardTransferMethoduses exhaustive pattern matching, ensuring all variants are explicitly handled. This follows the coding guidelines and provides compile-time safety when new transfer methods are added.lib/api/src/grpc/proto/telemetry_internal.proto (3)
13-26: LGTM!The new
GetPeerTelemetryResponseandPeerTelemetrymessages are well-structured. The use of reserved fields (1: id, 2: app, 5-7: requests/memory/hardware) appropriately documents fields that are not communicated in the internal service but exist in other telemetry contexts.
104-104: LGTM!The schema changes improve telemetry flexibility:
- Adding
map<uint64, PeerInfo> peersinClusterTelemetryenables per-peer metadata- Making
roleandpeer_idoptional inClusterStatusTelemetryis appropriate, as these fields may not always be available depending on cluster stateAlso applies to: 114-116
139-141: LGTM!The new
PeerInfomessage andPRE_CANDIDATEstate addition are appropriate:
PeerInfowith aurifield provides basic peer connectivity informationPRE_CANDIDATEaligns with Raft consensus protocol states for pre-votingAlso applies to: 147-147
lib/collection/src/telemetry.rs (8)
24-28: LGTM!Making
init_time_msandconfigoptional withskip_serializing_ifis appropriate for telemetry data that may not always be available, particularly when converting from the internal service gRPC representation.
186-219: LGTM!The
ShardTransferInfoconversion from gRPC handles all fields appropriately:
- Uses explicit
ShardTransferMethod::from(...)following coding guidelines- Properly handles empty strings for optional
commentfield- Error messages are clear and specific
221-247: LGTM!The bidirectional
ReshardingStageconversions use exhaustive pattern matching without catch-all_arms, following the coding guidelines. This ensures compile-time verification when new stages are added.
249-261: LGTM!The conversion from internal to gRPC
ShardTransferTelemetrycorrectly:
- Uses explicit
grpc::ShardTransferMethod::from(...)following guidelines- Handles optional fields with
unwrap_or_default()for gRPC representation
263-298: LGTM!The bidirectional
ReshardingInfo↔grpc::ReshardingTelemetryconversions are well-implemented:
- Uses explicit type conversions throughout (following coding guidelines)
- Proper error handling with descriptive messages
- UUID parsing with appropriate error handling
300-352: LGTM!The
ShardCleanStatusTelemetryconversions use exhaustive pattern matching for all enum variants (Started, Progress, Done, Failed, Cancelled), following the coding guidelines. This ensures new variants will be caught at compile time.
354-414: LGTM!The
CollectionTelemetryconversion from gRPC is thorough and well-documented:
- Explicit field destructuring follows coding guidelines
- Clear comments explain fields not provided in internal service (lines 406-408)
- Proper handling of empty collections with
Option<Vec<...>>pattern- Error handling is comprehensive
416-449: LGTM!The reverse conversion from internal to gRPC
CollectionTelemetrycorrectly:
- Uses explicit field destructuring with
: _for ignored fields (follows coding guidelines)- Flattens optional vectors with
into_iter().flatten()pattern- Applies explicit
grpc::*::from()conversions throughoutdocs/redoc/master/openapi.json (2)
12032-12036: Required set relaxed to only “id” — double‑check API compatibility.
CollectionTelemetryno longer requiresconfigorinit_time_ms. Ensure this is a deliberate, versioned change and client SDKs relying on previous required fields won’t break. Consider documenting behavior when these fields are absent.
12040-12045: Nullable numeric with constraints — verify generator handling.
init_time_msis now nullable withminimum: 0. Most tools ignoreminimumwhen value is null, but some generators misinterpret. Please validate with your OpenAPI linter/CI.lib/api/src/grpc/qdrant.rs (3)
12332-12350: Peer telemetry response/message shape looks consistent and well-scoped
GetPeerTelemetryResponsewithresult: Option<PeerTelemetry>andtime: f64, plusPeerTelemetryaggregating per‑collection and cluster telemetry, aligns with existing response patterns in this file and keeps peer telemetry nicely encapsulated.
12470-12496: New peers map and optional role/peer_id: OK, but note API surface change
- Adding
ClusterTelemetry.peers: HashMap<u64, PeerInfo>is straightforward and correctly typed for peer IDs → URIs.- Changing
ClusterStatusTelemetry.roleandpeer_idfrom plain values toOption<…>is wire‑compatible but changes the generated client API (Rust and other languages) from required to optional fields.If the gRPC/proto surface is considered public and semver‑stable, double‑check that this behavioral/API change is intentional and documented in release notes.
12540-12545: PeerInfo message is minimal and coherent with new peers map
PeerInfo { uri: String }is a simple, focused message type and matches the usage inClusterTelemetry.peerswithout colliding with the existingPeer { uri, id }raft type.lib/storage/src/content_manager/conversions.rs (4)
5-6: LGTM!The new imports are appropriate for the conversions implemented in this file. The
grpcalias improves readability throughout the conversion implementations.Also applies to: 23-23
68-226: LGTM!The collection operation conversions are well-structured:
- Exhaustive destructuring without
..catch-all (per coding guidelines)- Proper error handling with
?operator- Consistent use of
grpc::prefix- The
strict_mode_from_apihelper correctly maps all configuration fields
297-317: LGTM!The bidirectional
StateRoleconversions are well-implemented:
- Exhaustive pattern matching without
_catch-all (per coding guidelines)- Both directions handle all variants consistently (Follower, Candidate, Leader, PreCandidate)
- Infallible conversions using
Fromtrait appropriately
319-373: LGTM!The bidirectional
ConsensusThreadStatusconversions are correctly implemented:
- Exhaustive pattern matching for all variants (Working, Stopped, StoppedWithErr)
- Proper timestamp validation when converting from milliseconds (line 328) with clear error message
- The
Nonecase (line 343) reasonably defaults toStoppedas a fallback for unset protobuf fields- Reverse conversion (lines 348-373) correctly converts
DateTimeto millisecondsThe error handling and type safety are appropriate for these conversions.
| config: None, // Not provided in gRPC | ||
| peers: (!peers.is_empty()).then_some(peers), | ||
| peer_metadata: None, // Not provided in gRPC | ||
| metadata: None, // Not provided in gRPC |
There was a problem hiding this comment.
I don't like these Nones here so much. It may not be obvious in code that these will always be empty for some code paths.
At the same time I don't have any better suggestion.
I don't like duplicating all types another time just to remove those fields. And having reserved in the gRPC variants makes a lot of sense.
There was a problem hiding this comment.
I think this conversion + reserved fields is the best we can do. Unless there is another suggestion to evaluate
| let cluster = cluster.map(ClusterTelemetry::try_from).transpose()?; | ||
|
|
||
| Ok(TelemetryData { | ||
| id: "".to_string(), |
There was a problem hiding this comment.
Don't we need a collection name here?
There was a problem hiding this comment.
No no, this is the telemetry collector ID, which we don't care about in internal service
756b4e8 to
063c5c3
Compare
timvisee
left a comment
There was a problem hiding this comment.
Question about shard method defaulting:
📝 WalkthroughWalkthroughThis PR updates telemetry schemas, protobufs, and conversion code: it introduces PeerTelemetry and PeerInfo in protobufs, makes several telemetry fields optional (app, CollectionTelemetry.config, init_time_ms, role, peer_id, and ShardTransferTelemetry.method), renames/extends resharding enums (ReshardStage → ReshardingStage with added variants), adds new conversion TryFrom/From implementations between gRPC and internal types, emits Option-wrapped telemetry fields and shard_clean_tasks, and updates code paths to use the renamed ReshardingStage and new peers map. Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/api/src/grpc/qdrant.rs (1)
12505-12516: Minor doc typo: transfer method name in commentThe comment for
to_shard_idsaysReshardStreamRecords, but the enum variant isReshardingStreamRecords. Consider fixing the wording in the.protoso generated docs stay accurate.As this file is prost-generated, this should be changed in the corresponding proto (
telemetry_internal.proto) and regenerated. Based on learnings, ...
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
docs/redoc/master/openapi.jsonlib/api/src/grpc/proto/telemetry_internal.protolib/api/src/grpc/qdrant.rslib/collection/src/collection/telemetry.rslib/collection/src/operations/conversions.rslib/collection/src/operations/types.rslib/collection/src/shards/resharding.rslib/collection/src/shards/shard_holder/mod.rslib/collection/src/shards/shard_holder/resharding.rslib/collection/src/telemetry.rslib/storage/src/content_manager/conversions.rssrc/common/metrics.rssrc/common/telemetry.rssrc/common/telemetry_ops/conversions.rssrc/common/telemetry_ops/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/review-rules.md)
**/*.rs: Prefer explicitSomeType::from(x)over implicitx.into()in Rust
In new code, don't usetransmute_from_u8,transmute_to_u8,transmute_from_u8_to_slice,transmute_from_u8_to_mut_slice,transmute_to_u8_slice- usebytemuckorzerocopycrates instead
Prefer explicit exhaustive matches over catch-all_arm in Rust match expressions, so we don't miss handling new enum variants when they are added later (exceptions: tests and benchmarks, or when sure new variants won't affect logic)
Prefer explicit field ignoring using: _over using..in Rust struct destructuring (exceptions: tests and benchmarks, or when sure new fields won't affect logic)
Files:
src/common/telemetry_ops/mod.rslib/collection/src/operations/types.rssrc/common/telemetry_ops/conversions.rslib/collection/src/collection/telemetry.rslib/collection/src/operations/conversions.rssrc/common/metrics.rslib/collection/src/shards/shard_holder/resharding.rslib/storage/src/content_manager/conversions.rslib/collection/src/shards/resharding.rssrc/common/telemetry.rslib/collection/src/shards/shard_holder/mod.rslib/collection/src/telemetry.rslib/api/src/grpc/qdrant.rs
🧠 Learnings (9)
📚 Learning: 2025-09-16T19:14:17.614Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7183
File: lib/api/src/grpc/qdrant.rs:4263-4273
Timestamp: 2025-09-16T19:14:17.614Z
Learning: In qdrant, lib/api/src/grpc/qdrant.rs is auto-generated by prost-build; do not edit it directly. Make changes in lib/api/src/grpc/proto/points.proto (e.g., add [deprecated=true], doc comments, or encoding options), then regenerate the Rust code.
Applied to files:
lib/collection/src/operations/conversions.rslib/storage/src/content_manager/conversions.rslib/api/src/grpc/qdrant.rs
📚 Learning: 2025-08-15T15:56:36.821Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7065
File: lib/collection/src/operations/universal_query/shard_query.rs:0-0
Timestamp: 2025-08-15T15:56:36.821Z
Learning: Internal gRPC APIs in Qdrant don't require additional runtime validation when proto-level validation is already configured via build.rs range constraints.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:26:33.017Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:10393-10401
Timestamp: 2025-08-10T18:26:33.017Z
Learning: In qdrant, docs/redoc/master/openapi.json is auto-generated. Any description changes must be made in the source (e.g., lib/api/src/rest/schema.rs and/or lib/api/src/grpc/proto/points.proto), not edited directly in the JSON.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-11-25T11:56:33.176Z
Learnt from: CR
Repo: qdrant/qdrant PR: 0
File: .github/review-rules.md:0-0
Timestamp: 2025-11-25T11:56:33.176Z
Learning: Applies to **/*.rs : In new code, don't use `transmute_from_u8`, `transmute_to_u8`, `transmute_from_u8_to_slice`, `transmute_from_u8_to_mut_slice`, `transmute_to_u8_slice` - use `bytemuck` or `zerocopy` crates instead
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:25:16.206Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:10626-10634
Timestamp: 2025-08-10T18:25:16.206Z
Learning: In Qdrant, docs/redoc/master/openapi.json is autogenerated from the Rust REST schema definitions (e.g., lib/api/src/rest/schema.rs). To change OpenAPI descriptions, update the Rust struct field doc comments/attributes rather than editing the JSON directly.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-09-08T08:47:43.795Z
Learnt from: timvisee
Repo: qdrant/qdrant PR: 7188
File: lib/collection/src/update_handler.rs:810-813
Timestamp: 2025-09-08T08:47:43.795Z
Learning: In the Qdrant codebase, CollectionId implements traits that allow &CollectionId to convert Into<String>, so passing &collection_name to functions requiring Into<String> works correctly without needing .clone() or .to_string().
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-11-10T14:50:02.722Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7474
File: src/common/health.rs:328-330
Timestamp: 2025-11-10T14:50:02.722Z
Learning: In Qdrant's `ReplicaState`, the `ActiveRead` variant is intentionally considered unhealthy (returns `false` from `is_healthy()`) because it requires a shard transfer operation to finish. This is the correct behavior for health checks.
Applied to files:
lib/collection/src/shards/shard_holder/mod.rs
📚 Learning: 2025-12-22T16:30:28.630Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7631
File: docs/redoc/master/openapi.json:11774-11781
Timestamp: 2025-12-22T16:30:28.630Z
Learning: Qdrant’s OpenAPI (docs/redoc/master/openapi.json) is generated via schemars, and the project accepts the pattern anyOf: [ { "$ref": ... }, { "nullable": true } ] for nullable references because their autogenerated clients handle it. Prefer treating suggestions to switch to allOf + nullable as optional/non-blocking.
Applied to files:
docs/redoc/master/openapi.json
📚 Learning: 2025-08-23T22:24:44.276Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7100
File: tests/openapi/test_fts.py:255-263
Timestamp: 2025-08-23T22:24:44.276Z
Learning: In Qdrant's OpenAPI schema, the `filter.must` field accepts either a single Condition object or an array of Condition objects, not just arrays. The schema uses `anyOf` to allow both formats.
Applied to files:
docs/redoc/master/openapi.json
🧬 Code graph analysis (4)
lib/collection/src/collection/telemetry.rs (1)
lib/collection/src/telemetry.rs (7)
from(162-183)from(221-231)from(235-245)from(249-261)from(289-298)from(332-352)from(406-437)
lib/storage/src/content_manager/conversions.rs (1)
lib/api/src/grpc/conversions.rs (32)
try_from(97-128)try_from(426-436)try_from(456-463)try_from(468-482)try_from(487-497)try_from(502-508)try_from(514-541)try_from(546-587)try_from(593-607)try_from(612-618)try_from(623-633)try_from(638-645)try_from(651-678)try_from(684-725)try_from(751-773)try_from(912-938)from(132-147)from(151-162)from(166-177)from(181-188)from(192-204)from(208-224)from(228-240)from(244-249)from(253-286)from(290-295)from(299-311)from(315-327)from(331-342)from(346-357)from(361-372)from(376-402)
lib/collection/src/shards/shard_holder/mod.rs (2)
lib/collection/src/shards/shard_holder/resharding.rs (1)
resharding_state(22-24)lib/collection/src/collection/resharding.rs (1)
resharding_state(15-22)
lib/collection/src/telemetry.rs (1)
lib/api/src/grpc/conversions.rs (2)
convert_shard_key_from_grpc_opt(87-94)convert_shard_key_to_grpc(68-77)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: test-shard-snapshot-api-s3-minio
- GitHub Check: e2e-tests
- GitHub Check: Test Python bindings
- GitHub Check: test-consensus-compose
- GitHub Check: integration-tests
- GitHub Check: test-consistency
- GitHub Check: lint
- GitHub Check: rust-tests (ubuntu-latest)
- GitHub Check: rust-tests (windows-latest)
- GitHub Check: integration-tests-consensus
- GitHub Check: rust-tests (macos-latest)
🔇 Additional comments (48)
docs/redoc/master/openapi.json (2)
11764-11826: TelemetryData.app optional/nullable schema looks consistent with telemetry refactorMaking
appnon-required and representing it asanyOf[AppBuildTelemetry, { "nullable": true }]aligns with the move to optional app telemetry and matches the established nullable-reference pattern in this OpenAPI file and the schemars-generated output. No changes needed here. Based on learnings, this anyOf + nullable pattern is expected in this repo.
12111-12135: CollectionTelemetry.init_time_ms/config now optional – ensure callers handle null/missing
CollectionTelemetrynow only requiresid, withinit_time_msnullable andconfigexpressed asanyOf [CollectionConfigTelemetry, { "nullable": true }]. This matches the new internal/grpc telemetry where these fields can be absent, but it does mean previously non-null fields may now be missing/null in generated clients or downstream analytics. Please double-check that any consumers assuming these fields are always present have been updated to treat them as optional.Based on learnings, the anyOf + nullable shape here is consistent with how nullable references are modeled throughout this OpenAPI.
lib/collection/src/shards/resharding.rs (1)
58-70: LGTM!The rename from
ReshardStagetoReshardingStageis consistent and the newWriteHashRingCommittedvariant extends the ordered enum properly. The derives (Ord,PartialOrd) are correctly maintained for stage comparison logic used elsewhere.src/common/telemetry_ops/mod.rs (1)
4-4: LGTM!The private
conversionsmodule is appropriately scoped for internal telemetry type conversions.src/common/metrics.rs (1)
131-133: LGTM!The conditional handling of
self.appcorrectly adapts to the optionalAppBuildTelemetryfield, gracefully skipping app metrics when not present while preserving the remaining metrics collection flow.lib/collection/src/operations/types.rs (1)
349-354: LGTM!The
stagefield is correctly added with#[serde(skip)]to exclude it from public API serialization while making it available for internal peer telemetry. The documentation clearly indicates its intended use.lib/collection/src/operations/conversions.rs (3)
1411-1428: LGTM!The
stage: _pattern correctly ignores the telemetry-only field per the coding guidelines for explicit field ignoring. The inline comment clearly documents why the stage is discarded (only communicated for internal telemetry service).
1439-1446: LGTM!The reverse conversion from gRPC
ReshardingDirectionto internalReshardingDirectionuses explicit match arms, which aligns with the coding guidelines. This ensures compile-time errors if new variants are added to the gRPC enum.
1590-1603: LGTM!The reverse conversion from internal
ShardTransferMethodto gRPC type uses explicit match arms for all variants (StreamRecords,Snapshot,WalDelta,ReshardingStreamRecords), ensuring new variants will require explicit handling. As per coding guidelines, this prevents silently missing new enum variants.lib/collection/src/shards/shard_holder/resharding.rs (3)
18-18: LGTM!The import correctly reflects the renamed
ReshardingStageenum.
627-660: Explicit match patterns correctly handle allReshardingStagevariants.The match on
state.stageexplicitly handles:
MigratingPoints | ReadHashRingCommitted(grouped, as both expect resharding hashring)WriteHashRingCommitted(expects non-resharding hashring)None(no resharding in progress)This covers all three
ReshardingStagevariants exhaustively. As per coding guidelines, this ensures compile-time errors if new variants are added, requiring explicit handling decisions.
662-673: LGTM!The
check_stagefunction signature correctly usesReshardingStageand the closure logic is unchanged.lib/collection/src/collection/telemetry.rs (1)
40-47: LGTM!The changes correctly wrap
init_time_msandconfiginSome()to match their updatedOptiontypes, and the conditional population ofshard_clean_tasksusingthen_someis idiomatic.src/common/telemetry_ops/conversions.rs (5)
10-17: LGTM!The helper function correctly handles the optional role conversion with proper error mapping. Using
.transpose()to convertOption<Result<_, _>>toResult<Option<_>, _>is idiomatic.
19-52: LGTM!Explicit field destructuring is used correctly, and the required
consensus_thread_statusfield is properly validated before conversion. As per coding guidelines, explicit field ignoring is followed.
54-80: LGTM!The conversion is symmetric with the
TryFromimplementation and correctly maps all fields including the optionalrole.
82-102: Acknowledged: None values for fields not provided in gRPC.The defaulting of
enabledtotrueand setting unprovided fields toNoneis intentional per prior discussion. This is acceptable given the internal telemetry service context.
104-126: LGTM!Explicit field ignoring with
: _is used correctly per coding guidelines, andunwrap_or_default()safely handles the optional peers field.lib/collection/src/shards/shard_holder/mod.rs (4)
33-33: LGTM!Import updated to reflect the renamed
ReshardingStageenum.
317-319: LGTM!Stage comparison updated to use
ReshardingStage::WriteHashRingCommitted, consistent with the enum rename.
550-557: LGTM!The
stagefield is now included inReshardingInfo, providing visibility into the resharding progress in telemetry data.
597-602: LGTM!Stage comparison updated to use
ReshardingStage::ReadHashRingCommitted, consistent with the enum rename.lib/collection/src/telemetry.rs (5)
24-28: LGTM!The
init_time_msandconfigfields are now correctly declared asOptiontypes with appropriateskip_serializing_ifattributes to omit them whenNone.
301-353: LGTM!The
ShardCleanStatusTelemetryconversions exhaustively match all five variants (Started,Progress,Done,Failed,Cancelled) in both directions with proper error handling for the missing variant case.
355-438: LGTM!The
CollectionTelemetryconversions use explicit field destructuring and ignoring per coding guidelines. Fields not provided by the internal service (init_time_ms,config,shards) are correctly set toNoneor ignored with clear comments explaining the rationale.
197-218: LGTM!The conversion correctly handles optional fields including the
methodandcommenttransformations. The pattern for filtering empty comments is appropriate.
220-246: TheReshardingStageconversions are correctly exhaustive. Both enums have exactly three variants (MigratingPoints,ReadHashRingCommitted,WriteHashRingCommitted), and bothFromimplementations explicitly match all three variants without using a catch-all arm. No changes needed.src/common/telemetry.rs (4)
50-52: LGTM!The
appfield is now correctly anOption<AppBuildTelemetry>withskip_serializing_ifto omit it whenNone, aligning with the internal telemetry service requirements.
129-133: LGTM!
appis correctly wrapped inSome()to match the updatedOptiontype.
150-185: LGTM!The conversion correctly transforms
grpc::PeerTelemetrytoTelemetryData, wrapping collections inCollectionTelemetryEnum::Full. Settingidto empty andapptoNoneis intentional for internal service telemetry as confirmed in past review discussion.
187-223: LGTM!Explicit field ignoring with
: _follows coding guidelines. The explicit error forCollectionTelemetryEnum::Aggregatedis appropriate since this conversion expectsdetails_level >= 2. This provides a clear error message rather than silently failing.lib/api/src/grpc/proto/telemetry_internal.proto (7)
15-18: LGTM - Response structure follows established patterns.The nesting of telemetry data into
resultis consistent with REST API conventions and other gRPC endpoints in the codebase, as previously discussed.
20-30: Good use of reserved fields for schema evolution.The
reserveddeclarations with comments documenting the original field purposes (id, app, requests, memory, hardware) follow protobuf best practices for backward-compatible schema evolution. This prevents accidental reuse of field numbers.
63-63: Makingmethodoptional is appropriate.This change allows flexibility for cases where the transfer method may not be known or applicable. Ensure downstream conversion code handles the
Nonecase gracefully.
113-119: ClusterTelemetry structure is clean.Reserved fields are properly documented. The
peersmap usinguint64keys (peer IDs) toPeerInfovalues is a sensible design for exposing peer endpoint information.
126-128: Optionalroleandpeer_idfields are appropriate.Making these optional handles edge cases where consensus state may not be fully initialized or available. This is consistent with the PR's goal of handling optional telemetry data gracefully.
152-154: PeerInfo is minimal but sufficient for current needs.The message currently only contains
uri. If additional peer metadata is needed in the future (e.g., health status, version), the structure is extensible.
77-81: Verify enum value semantics for default case.In proto3, unset enum fields default to the first value (0). Here
MIGRATING_POINTS = 0will be the default. Confirm this is the intended initial/default stage for resharding operations, or consider adding an explicitUNKNOWN = 0sentinel if the absence of a stage should be distinguishable.lib/api/src/grpc/qdrant.rs (5)
12463-12482: New GetPeerTelemetryResponse/PeerTelemetry shape looks consistent
GetPeerTelemetryResponse { result: Option<PeerTelemetry>, time }plusPeerTelemetry { collections, cluster }is a clean, explicit API; tags starting at 3/4 correctly avoid reusing removed fields. No functional issues spotted here.
12503-12527: Optional ShardTransferTelemetry.method is fine; ensure callers handleNoneMaking
methodanOption<i32>matches proto3optionalsemantics and is appropriate for telemetry, but any conversion/aggregation code must treatNoneas “unknown/unspecified” rather than assuming a concrete method.
12602-12628: ClusterTelemetry/ClusterStatusTelemetry changes are reasonable but relax invariants
- Adding
peers: HashMap<u64, PeerInfo>toClusterTelemetryis a nice structured view of peer metadata.- Making
ClusterStatusTelemetry.roleandpeer_idoptional is ABI-safe on the wire but changes invariants; downstream code must be ready forNonein both fields and treat it as “status unknown / not yet initialized”.No structural issues, just ensure all conversions and UI paths handle the newly-optional fields.
12671-12677: PeerInfo message is minimal and consistent
PeerInfo { uri }is straightforward and matches how other peer metadata is represented elsewhere; no issues from the wire-format perspective.
12679-12707: ReshardingStage enum definition and string mappings look correctVariants, numeric values, and
as_str_name/from_str_namemappings match typical proto enum patterns and are internally consistent; nothing to fix here.lib/storage/src/content_manager/conversions.rs (5)
297-317: LGTM!Both
StateRoleconversions use exhaustive matching, which aligns with the coding guidelines and ensures compile-time errors if new variants are added to either enum.
343-343: Verify that treatingNonestatus asStoppedis intentional.When
statusisNone, this defaults toConsensusThreadStatus::Stopped. This may be intentional for backwards compatibility or default behavior, but could also mask cases where the status field wasn't properly set. Consider whether returning an error or a distinct state would be more appropriate.
348-373: LGTM!The conversion uses exhaustive matching on all
ConsensusThreadStatusvariants and correctly converts theDateTime<Utc>to milliseconds timestamp. The implementation is symmetric with theTryFromimplementation above.
68-122: Changes look good overall.The
TryFrom<grpc::CreateCollection>implementation correctly destructures all fields explicitly and handles the various optional configurations appropriately. The error handling and metadata conversion are properly implemented.
124-167: Well-structured configuration mapping.The
strict_mode_from_apifunction uses explicit field destructuring for all fields and properly maps the gRPC config to the internalStrictModeConfigtype. The explicit use ofStrictModeMultivectorConfig::fromandStrictModeSparseConfig::fromon lines 163-164 follows the coding guidelines.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
lib/api/src/grpc/proto/telemetry_internal.proto (1)
116-116: Remove redundant inline comment.The inline comment
// peersis redundant since the field is already namedpeers.🔎 Suggested cleanup
- map<uint64, PeerInfo> peers = 3; // peers + map<uint64, PeerInfo> peers = 3;
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
lib/api/src/grpc/proto/telemetry_internal.protolib/api/src/grpc/qdrant.rslib/collection/src/operations/types.rslib/collection/src/shards/transfer/mod.rs
✅ Files skipped from review due to trivial changes (1)
- lib/collection/src/shards/transfer/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/review-rules.md)
**/*.rs: Prefer explicitSomeType::from(x)over implicitx.into()in Rust
In new code, don't usetransmute_from_u8,transmute_to_u8,transmute_from_u8_to_slice,transmute_from_u8_to_mut_slice,transmute_to_u8_slice- usebytemuckorzerocopycrates instead
Prefer explicit exhaustive matches over catch-all_arm in Rust match expressions, so we don't miss handling new enum variants when they are added later (exceptions: tests and benchmarks, or when sure new variants won't affect logic)
Prefer explicit field ignoring using: _over using..in Rust struct destructuring (exceptions: tests and benchmarks, or when sure new fields won't affect logic)
Files:
lib/collection/src/operations/types.rslib/api/src/grpc/qdrant.rs
🧠 Learnings (1)
📚 Learning: 2025-09-16T19:14:17.614Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7183
File: lib/api/src/grpc/qdrant.rs:4263-4273
Timestamp: 2025-09-16T19:14:17.614Z
Learning: In qdrant, lib/api/src/grpc/qdrant.rs is auto-generated by prost-build; do not edit it directly. Make changes in lib/api/src/grpc/proto/points.proto (e.g., add [deprecated=true], doc comments, or encoding options), then regenerate the Rust code.
Applied to files:
lib/api/src/grpc/qdrant.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: test-consistency
- GitHub Check: test-shard-snapshot-api-s3-minio
- GitHub Check: integration-tests
- GitHub Check: test-consensus-compose
- GitHub Check: e2e-tests
- GitHub Check: integration-tests-consensus
- GitHub Check: rust-tests (ubuntu-latest)
- GitHub Check: lint
- GitHub Check: rust-tests (macos-latest)
- GitHub Check: rust-tests (windows-latest)
- GitHub Check: Test Python bindings
🔇 Additional comments (12)
lib/collection/src/operations/types.rs (3)
56-56: LGTM! Import added for new field.The import of
ReshardingStageis correctly added to support the newstagefield inReshardingInfo.
306-306: LGTM! Documentation updated to reflect correct method name.The comment correctly references
ReshardingStreamRecordstransfer method.
349-353: All construction sites have been properly updated with the newstagefield.The verification confirms:
- TryFrom implementation in telemetry.rs constructs the
stagefield by converting fromgrpc::ReshardingStage- Direct construction in shard_holder/mod.rs provides
stagefromresharding_state.stage- Pattern matching in conversions.rs uses exhaustive destructuring with explicit
stage: _,to indicate the field is intentionally excluded from the gRPC conversionThe design is sound: the
stagefield is properly initialized at all construction sites, and the exhaustive pattern matching ensures compile-time safety if additional fields are added in the future.lib/api/src/grpc/proto/telemetry_internal.proto (5)
152-161: LGTM!The new
PeerInfomessage and expandedStateRoleenum look good. The additions are backward compatible and serve clear purposes.
20-30: No actionable changes needed. ThePeerTelemetrymessage correctly uses protobuf'sreservedkeyword to preserve field numbers (id, app, requests, memory, hardware) for forward compatibility, which is standard practice and intentional design.
63-63: No action needed. The conversion code forShardTransferTelemetry.methodcorrectly handles the optional field using idiomatic Rust patterns (.map()and.transpose()), with proper error handling. The implementation safely manages theNonecase without unsafe unwraps.
53-53: The comment correctly referencesReshardingStreamRecordsas the transfer method name—this matches the actual enum value defined inShardTransferMethodin collections.proto.
126-128: The conversion code properly handles the optionalroleandpeer_idfields. TheTryFromimplementation uses a dedicated helper function for safe enum conversion and.map()for field mapping, while theFromimplementation correctly converts optional values. Metrics code checks forSomebefore usingpeer_id, androleis not directly accessed without None checks. All downstream field accesses are defensive.lib/api/src/grpc/qdrant.rs (4)
12464-12468: GetPeerTelemetryResponse / PeerTelemetry shape looks consistent with other APIs
GetPeerTelemetryResponsenow wraps a singlePeerTelemetryresult plustime: f64, which matches the pattern used by other responses in this file, and thePeerTelemetrypayload groups collection and cluster telemetry cleanly. Just make sure this file is regenerated from the updatedtelemetry_internal.protorather than hand-edited, so future codegen doesn’t drop these changes.Based on learnings, this file is expected to be prost-generated rather than maintained manually.
12505-12523: Optionalmethodin ShardTransferTelemetry requires callers to handleNoneChanging
methodtoOption<i32>is wire‑compatible but changes the Rust API: telemetry consumers and conversion code must now handlemethod == None(e.g. for older peers that don’t send it, or where the method is unknown). Please double‑check that all conversion implementations and any display/logging paths treatNonesensibly instead of unconditionally unwrapping. The updatedto_shard_idcomment referencingReshardingStreamRecordsalso looks accurate with the currentShardTransferMethodenum.
12602-12607: ClusterTelemetry.peers + PeerInfo look reasonable and extensibleAdding
ClusterTelemetry.peers: HashMap<u64, PeerInfo>keyed by peer ID withPeerInfo { uri }gives a clear, minimal structure for peer metadata and can be extended later with more fields if needed. The field number (tag = 3) avoids conflicts and should be safe for rollout across mixed versions.Also applies to: 12672-12677
12612-12628: Makingroleandpeer_idoptional in ClusterStatusTelemetry changes Rust semantics
roleandpeer_idmoving toOption<i32>/Option<u64>is wire‑compatible with older messages, but any existing Rust code that previously assumed these fields were always present must now handleNone(e.g. on telemetry from partially initialized nodes or during upgrades). Please review the new conversion code to ensure it either provides a sensible default when mapping to internal types or propagatesNonesafely without panics.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/storage/src/content_manager/conversions.rs (1)
92-101: Use explicit conversions instead of implicittry_into()/into().Lines 93, 100, and 101 use implicit conversions, which violates the coding guideline. Prefer explicit
Type::from()orType::try_from()forms.🔎 Proposed fix
vectors: match vectors_config.and_then(|config| config.config) { - Some(vector_config) => vector_config.try_into()?, + Some(vector_config) => VectorsConfig::try_from(vector_config)?, // TODO(sparse): sparse or dense vectors config is required None => Default::default(), }, sparse_vectors: sparse_vectors_config .map(|v| SparseVectorsConfig::try_from(v).map(|SparseVectorsConfig(x)| x)) .transpose()?, - hnsw_config: hnsw_config.map(|v| v.into()), - wal_config: wal_config.map(|v| v.into()), + hnsw_config: hnsw_config.map(HnswConfig::from), + wal_config: wal_config.map(WalConfig::from),As per coding guidelines, explicit conversions improve code clarity and make type transformations more discoverable.
🧹 Nitpick comments (1)
docs/redoc/master/openapi.json (1)
11672-11678: Optional: alignto_shard_iddoc wording with enum valueThe description now mentions the
ReshardingStreamRecordstransfer method, while the correspondingShardTransferMethodenum value exposed in the API isresharding_stream_records. If these are meant to be the same concept, consider adjusting the wording to reference the public enum string (or clarify both) so OpenAPI readers don’t see two slightly different names. Update the Rust doc comment rather than this JSON so the change survives regeneration.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/redoc/master/openapi.jsonlib/api/src/grpc/proto/telemetry_internal.protolib/api/src/grpc/qdrant.rslib/storage/src/content_manager/conversions.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/review-rules.md)
**/*.rs: Prefer explicitSomeType::from(x)over implicitx.into()in Rust
In new code, don't usetransmute_from_u8,transmute_to_u8,transmute_from_u8_to_slice,transmute_from_u8_to_mut_slice,transmute_to_u8_slice- usebytemuckorzerocopycrates instead
Prefer explicit exhaustive matches over catch-all_arm in Rust match expressions, so we don't miss handling new enum variants when they are added later (exceptions: tests and benchmarks, or when sure new variants won't affect logic)
Prefer explicit field ignoring using: _over using..in Rust struct destructuring (exceptions: tests and benchmarks, or when sure new fields won't affect logic)
Files:
lib/storage/src/content_manager/conversions.rslib/api/src/grpc/qdrant.rs
🧠 Learnings (16)
📚 Learning: 2025-09-16T19:14:17.614Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7183
File: lib/api/src/grpc/qdrant.rs:4263-4273
Timestamp: 2025-09-16T19:14:17.614Z
Learning: In qdrant, lib/api/src/grpc/qdrant.rs is auto-generated by prost-build; do not edit it directly. Make changes in lib/api/src/grpc/proto/points.proto (e.g., add [deprecated=true], doc comments, or encoding options), then regenerate the Rust code.
Applied to files:
lib/storage/src/content_manager/conversions.rslib/api/src/grpc/qdrant.rs
📚 Learning: 2025-11-25T11:56:33.176Z
Learnt from: CR
Repo: qdrant/qdrant PR: 0
File: .github/review-rules.md:0-0
Timestamp: 2025-11-25T11:56:33.176Z
Learning: Applies to **/*.rs : Prefer explicit exhaustive matches over catch-all `_` arm in Rust match expressions, so we don't miss handling new enum variants when they are added later (exceptions: tests and benchmarks, or when sure new variants won't affect logic)
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-11-25T11:56:33.176Z
Learnt from: CR
Repo: qdrant/qdrant PR: 0
File: .github/review-rules.md:0-0
Timestamp: 2025-11-25T11:56:33.176Z
Learning: Applies to **/*.rs : Prefer explicit field ignoring using `: _` over using `..` in Rust struct destructuring (exceptions: tests and benchmarks, or when sure new fields won't affect logic)
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-04-22T23:17:41.734Z
Learnt from: xzfc
Repo: qdrant/qdrant PR: 6245
File: lib/segment/src/index/hnsw_index/point_scorer.rs:116-121
Timestamp: 2025-04-22T23:17:41.734Z
Learning: The method `is_none_or` exists in the Qdrant codebase and compiles correctly, despite not being part of standard Rust's Option type. Code reviews should verify compilation issues before reporting them.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-11-25T11:56:33.176Z
Learnt from: CR
Repo: qdrant/qdrant PR: 0
File: .github/review-rules.md:0-0
Timestamp: 2025-11-25T11:56:33.176Z
Learning: For Rust code review, checking whether code compiles is out of scope, including: missing imports for `size_of` or `align_of` (included in Rust 1.80+ prelude), methods not implemented for types, different method names across `rand` crate versions (e.g., `random_range` vs `gen_range`), and other compiler errors or warnings
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:30:02.986Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: lib/collection/src/operations/verification/update.rs:158-174
Timestamp: 2025-08-10T18:30:02.986Z
Learning: In Qdrant's strict mode verification code (lib/collection/src/operations/verification/update.rs), exhaustive pattern matching without `..` is intentionally used for structs like PointsBatch and PointsList. This design pattern ensures compilation fails when new fields are added, forcing developers to explicitly consider how new fields should be handled in the indexed_filter_write method. This provides visibility and compile-time safety for struct evolution.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-10-08T13:36:02.791Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7359
File: lib/segment/src/vector_storage/query/feedback_query.rs:111-125
Timestamp: 2025-10-08T13:36:02.791Z
Learning: When reviewing Rust code, do not flag compile-time bugs such as type errors, incorrect destructuring patterns, or syntax issues that would be caught by the Rust compiler. If the code compiles, focus reviews on logic, design patterns, runtime behavior, and semantic correctness instead of syntax-level concerns.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-10-16T13:00:46.809Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7368
File: lib/shard/src/query/mod.rs:313-341
Timestamp: 2025-10-16T13:00:46.809Z
Learning: In the Qdrant codebase, for the `Feedback` query variant in `lib/shard/src/query/mod.rs`, validation for sparse vectors should happen down the line rather than early in the `query_enum_from_grpc_raw_query` function. The `Nearest` variant is treated as a special case where early validation with better error messages is acceptable.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-11-02T19:16:42.527Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7474
File: lib/collection/src/shards/transfer/stream_records.rs:46-55
Timestamp: 2025-11-02T19:16:42.527Z
Learning: In the Qdrant repository, do not flag compilation errors such as partial-move errors, type errors, or any syntax issues that would be caught by the Rust compiler during the build process.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-15T15:56:36.821Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7065
File: lib/collection/src/operations/universal_query/shard_query.rs:0-0
Timestamp: 2025-08-15T15:56:36.821Z
Learning: Internal gRPC APIs in Qdrant don't require additional runtime validation when proto-level validation is already configured via build.rs range constraints.
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:25:16.206Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:10626-10634
Timestamp: 2025-08-10T18:25:16.206Z
Learning: In Qdrant, docs/redoc/master/openapi.json is autogenerated from the Rust REST schema definitions (e.g., lib/api/src/rest/schema.rs). To change OpenAPI descriptions, update the Rust struct field doc comments/attributes rather than editing the JSON directly.
Applied to files:
lib/storage/src/content_manager/conversions.rsdocs/redoc/master/openapi.json
📚 Learning: 2025-09-08T08:47:43.795Z
Learnt from: timvisee
Repo: qdrant/qdrant PR: 7188
File: lib/collection/src/update_handler.rs:810-813
Timestamp: 2025-09-08T08:47:43.795Z
Learning: In the Qdrant codebase, CollectionId implements traits that allow &CollectionId to convert Into<String>, so passing &collection_name to functions requiring Into<String> works correctly without needing .clone() or .to_string().
Applied to files:
lib/storage/src/content_manager/conversions.rs
📚 Learning: 2025-08-10T18:26:33.017Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:10393-10401
Timestamp: 2025-08-10T18:26:33.017Z
Learning: In qdrant, docs/redoc/master/openapi.json is auto-generated. Any description changes must be made in the source (e.g., lib/api/src/rest/schema.rs and/or lib/api/src/grpc/proto/points.proto), not edited directly in the JSON.
Applied to files:
docs/redoc/master/openapi.json
📚 Learning: 2025-08-10T18:26:12.443Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7006
File: docs/redoc/master/openapi.json:13645-13652
Timestamp: 2025-08-10T18:26:12.443Z
Learning: In qdrant, docs/redoc/master/openapi.json is auto-generated from the REST schemas. To change field docs, edit lib/api/src/rest/schema.rs (e.g., add doc comments or #[schemars(description = ...)]). Specifically, UpdateVectors.update_filter lacked a description and should state: "If specified, only update vectors for points that match this filter; points not matching the filter are left unchanged."
Applied to files:
docs/redoc/master/openapi.json
📚 Learning: 2025-12-22T16:30:28.630Z
Learnt from: coszio
Repo: qdrant/qdrant PR: 7631
File: docs/redoc/master/openapi.json:11774-11781
Timestamp: 2025-12-22T16:30:28.630Z
Learning: Qdrant’s OpenAPI (docs/redoc/master/openapi.json) is generated via schemars, and the project accepts the pattern anyOf: [ { "$ref": ... }, { "nullable": true } ] for nullable references because their autogenerated clients handle it. Prefer treating suggestions to switch to allOf + nullable as optional/non-blocking.
Applied to files:
docs/redoc/master/openapi.json
📚 Learning: 2025-08-23T22:24:44.276Z
Learnt from: generall
Repo: qdrant/qdrant PR: 7100
File: tests/openapi/test_fts.py:255-263
Timestamp: 2025-08-23T22:24:44.276Z
Learning: In Qdrant's OpenAPI schema, the `filter.must` field accepts either a single Condition object or an array of Condition objects, not just arrays. The schema uses `anyOf` to allow both formats.
Applied to files:
docs/redoc/master/openapi.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: test-consensus-compose
- GitHub Check: test-consistency
- GitHub Check: integration-tests-consensus
- GitHub Check: e2e-tests
- GitHub Check: test-shard-snapshot-api-s3-minio
- GitHub Check: integration-tests
- GitHub Check: rust-tests (macos-latest)
- GitHub Check: rust-tests (windows-latest)
- GitHub Check: rust-tests (ubuntu-latest)
- GitHub Check: Test Python bindings
- GitHub Check: lint
🔇 Additional comments (13)
docs/redoc/master/openapi.json (2)
11773-11781: TelemetryData.app nullability change looks consistentMaking
appan optional/nullable field viaanyOfaligns the schema with the new optional internal telemetry field and matches the existing nullable‑reference pattern used elsewhere in this OpenAPI. No further changes needed here.
12112-12135: CollectionTelemetry:config/init_time_msnow optional & nullable—check client impact
CollectionTelemetryno longer requiresconfigorinit_time_ms, and both fields can now be null/absent. This matches the internal telemetry changes (making these fields optional), but it does change the OpenAPI contract: previously generated clients may have treated these as non‑null required properties.If external SDKs or integrations were generated against the old schema, please double‑check they tolerate missing/null
configandinit_time_msvalues. Any further tweaks should be done in the Rust schema definitions that feed schemars, not by editing this JSON directly.lib/storage/src/content_manager/conversions.rs (5)
124-167: LGTM! Explicit conversions and field destructuring.The function correctly uses explicit field destructuring and explicit conversions throughout (
as usize,f64::from(),StrictModeMultivectorConfig::from()).
169-212: LGTM! Follows coding guidelines.The implementation uses explicit field destructuring and explicit conversion functions throughout.
214-295: LGTM! Clean alias operation conversions.All implementations use explicit field destructuring and the match statement correctly uses explicit
Noneinstead of a catch-all_arm, as addressed in the previous review.
297-317: LGTM! Exhaustive bidirectional StateRole conversions.Both conversion directions use exhaustive pattern matches covering all four variants (Follower, Candidate, Leader, PreCandidate), ensuring compile-time safety when new variants are added.
319-373: LGTM! Well-implemented bidirectional ConsensusThreadStatus conversions.The implementations correctly:
- Use exhaustive pattern matches
- Handle timestamp conversion between
DateTime<Utc>and milliseconds with proper error handling- Default
NonetoStoppedstate (reasonable for proto oneofs)- Preserve all error information in
StoppedWithErrvariantThe timestamp conversion is invertible at millisecond precision, which is appropriate for this use case.
lib/api/src/grpc/proto/telemetry_internal.proto (5)
15-30: LGTM! Clean telemetry response structure.The refactoring into a nested
PeerTelemetrymessage withresultandtimefields aligns with the existing API patterns (as noted in past review). The use of reserved fields for future expansion is a good proto design practice.
113-119: LGTM! Peer tracking in cluster telemetry.The new
peersmap enables tracking peer information by ID. The reserved fields maintain proto evolution flexibility. The structure is consistent with the newPeerInfomessage definition.
152-161: LGTM! Clean message and enum definitions.
PeerInfoprovides a simple, extensible structure for peer URIs. TheStateRoleenum correctly defines all standard Raft consensus roles and aligns with the bidirectional conversions implemented inlib/storage/src/content_manager/conversions.rs.
63-63: The optionalmethodfield is intentional and properly handled. TheNonecase has semantic meaning—it directs the system to automatically choose the transfer method. Conversions inlib/collection/src/telemetry.rscorrectly handle the optional field using.map(), and the internalShardTransferInfoexplicitly documents this behavior: "Method to transfer shard with.Noneto choose automatically." All code paths safely handle theOptiontype.Likely an incorrect or invalid review comment.
126-128: This change is appropriate. Theroleandpeer_idfields are legitimately optional inClusterStatusTelemetrysince they only exist when the cluster is enabled. The Rust struct correctly models both asOptiontypes, conversions properly handle them, andpeer_idis always wrapped inSome()during construction when the cluster status is enabled. A helper methodthis_peer_id()safely extracts the value when needed.lib/api/src/grpc/qdrant.rs (1)
12463-12706: Telemetry schema changes look consistent; please verify downstream conversions and remember this file is generated.
GetPeerTelemetryResponseandPeerTelemetryfollow the sameresult + timeand nested-telemetry patterns used elsewhere in this file, so the new RPC surface is structurally sound.- Making
ShardTransferTelemetry.method,ClusterStatusTelemetry.role, andClusterStatusTelemetry.peer_idoptional is a reasonable way to support partial/older telemetry, but it does require all conversion code and consumers to handleNoneexplicitly rather than assuming defaults.- Adding
ClusterTelemetry.peers: HashMap<u64, PeerInfo>aligns with the rest of the API (peer IDs asu64, URIs asString) and gives a clean place to attach per-peer info without changing existing messages.- The new
ReshardingStageenum (withMigratingPoints,ReadHashRingCommitted, andWriteHashRingCommitted) is well-formed and consistent with other enums here; just ensure all producers/consumers of resharding telemetry are updated to use the renamed/extended stages.Given this file is auto-generated by
prost-build, any further tweaks should come from the corresponding.protodefinitions (e.g.telemetry_internal.proto) and then be regenerated rather than edited here directly. Based on learnings, lib/api/src/grpc/qdrant.rs is treated as generated output.
* implement conversions * clippy * rename `ReshardStage` -> `ReshardingStage` * impl conversions to grpc * upd response in proto * convert TelemetryData * add peer info * upd openapi * add conversion from TelemetryData to PeerTelemetry * review nit * re-style * make `method` optional * change comments to reference `ReshardingStreamRecords` * missing nits
Depends on #7599
Implements conversions between internal telemetry service and existing types.
Tasks