Skip to content

feat(clp-rust-utils): Add ClpIoConfig and related inner configuration structs with Brotli-compressed MessagePack serialization support.#1523

Merged
LinZhihao-723 merged 14 commits into
y-scope:mainfrom
LinZhihao-723:clp-io-config
Oct 31, 2025

Conversation

@LinZhihao-723

@LinZhihao-723 LinZhihao-723 commented Oct 29, 2025

Copy link
Copy Markdown
Member

Description

As required by CLP's compression job database, compression jobs must be submitted with ClpIoConfig to specify the input/output specification. This PR mirrors this config from clp-py-utils, with related inner configs defined. Since the config is serialized using msgpack and compressed using brotli, such a serialization method is implemented to support submission.

Notice that for inner configs, not all options are implemented. For example, the input type now only supports S3 as this Rust implementation will only be used for S3 compression for now. However, it is designed in a way so that other input types can be easily added. Same as S3 authentication configs.

The implementation should also support deserializing configs using Rust's serde framework. This feature can be added in future PRs (with validations added).

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • Ensure all workflows pass.
  • Add unit tests to ensure the serialized results match expectations.

Summary by CodeRabbit

  • New Features

    • Added S3 bucket and AWS credential configuration support.
    • Implemented Brotli-compressed MessagePack serialization for improved performance.
    • Extended configuration framework with comprehensive job input and output parameters.
  • Tests

    • Added serialization tests validating Brotli+MessagePack output and JSON representation.
  • Bug Fixes

    • Improved error reporting for serialization and I/O operations.

@LinZhihao-723 LinZhihao-723 requested a review from a team as a code owner October 29, 2025 21:40
@coderabbitai

coderabbitai Bot commented Oct 29, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds dependencies and implements new CLP Rust utilities: S3 configuration types, CLP IO job configuration, error enum, Brotli + MessagePack serialization helper, library module wiring, and a test validating serialization outputs.

Changes

Cohort / File(s) Summary
Manifest / Dependencies
components/clp-rust-utils/Cargo.toml
Added runtime deps: brotli, rmp-serde, serde (with derive), thiserror; added dev-deps: hex, serde_json.
Library root & wiring
components/clp-rust-utils/src/lib.rs
Declared pub mod clp_config;, pub mod job_config;, pub mod serde;, added mod error; and re-exported Error.
Error module
components/clp-rust-utils/src/error.rs
New Error enum with MsgpackEncodeError(#[from] rmp_serde::encode::Error) and IoError(#[from] std::io::Error) using thiserror.
S3 config
components/clp-rust-utils/src/clp_config.rs, components/clp-rust-utils/src/clp_config/s3_config.rs
Added mod s3_config; and pub use s3_config::*;. New S3Config, AwsAuthentication (serde tagged), and AwsCredentials types (derive Serialize, Debug, Clone, Eq, PartialEq).
Job config
components/clp-rust-utils/src/job_config.rs, components/clp-rust-utils/src/job_config/clp_io_config.rs
New clp_io_config submodule exported. Added ClpIoConfig, InputConfig (serde tagged), S3InputConfig (with flattened S3Config), and OutputConfig types (derive Serialize, Debug, Clone, Eq, PartialEq).
Serialization utilities
components/clp-rust-utils/src/serde.rs, components/clp-rust-utils/src/serde/brotli_msgpack.rs
Declared mod brotli_msgpack; and re-export. Implemented BrotliMsgpack::serialize<T: Serialize + ?Sized>(&T) -> Result<Vec<u8>, Error>: MessagePack via rmp_serde::to_vec_named then Brotli compress with CompressorWriter.
Tests
components/clp-rust-utils/tests/clp_config_test.rs
Added test test_clp_io_config_serialization that constructs CLP config, serializes with BrotliMsgpack (asserts hex output) and compares pretty JSON to expected structure.

Sequence Diagram(s)

sequenceDiagram
  participant Test as Test (clp_config_test)
  participant Config as ClpIoConfig
  participant Ser as BrotliMsgpack::serialize
  participant Rmp as rmp_serde::to_vec_named
  participant Brotli as brotli::CompressorWriter
  participant IO as Vec<u8> (output)

  Note over Test,Config: Build ClpIoConfig (includes S3Config + AwsCredentials)
  Test->>Ser: call serialize(&Config)
  Ser->>Rmp: rmp_serde::to_vec_named(&Config)
  Rmp-->>Ser: msgpack_bytes
  Ser->>Brotli: write_all(msgpack_bytes)
  Brotli-->>Ser: compressed_bytes
  Ser-->>Test: Ok(compressed_bytes)
  Test->>IO: hex::encode(compressed_bytes) / compare expected
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to serde attributes (#[serde(tag = "type")], #[serde(flatten)]) in clp_io_config.rs and s3_config.rs.
  • Verify BrotliMsgpack::serialize error propagation aligns with Error enum (rmp_serde::encode::Error and std::io::Error).
  • Confirm test expectations (hex string and JSON structure) correctly match serialization outputs and applied serde renames.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Add ClpIoConfig and related inner configuration structs with Brotli-compressed MessagePack serialization support" directly and accurately summarizes the main changes in the changeset. The title specifically references ClpIoConfig (the primary new public struct in clp_io_config.rs), the related configuration types (InputConfig, OutputConfig, S3InputConfig, S3Config, AwsAuthentication, AwsCredentials), and the new serialization capability (BrotliMsgpack). The title is concise, clear, uses conventional commit formatting, and provides sufficient specificity that a teammate reviewing the commit history would immediately understand the primary objective of the changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56ebca1 and d1c924f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • components/clp-rust-utils/Cargo.toml (1 hunks)
  • components/clp-rust-utils/src/clp_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/aws_authentication.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/s3_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/output_config.rs (1 hunks)
  • components/clp-rust-utils/src/lib.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
PR: y-scope/clp#1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/clp-package-utils/clp_package_utils/scripts/compress.py:0-0
Timestamp: 2025-01-16T16:58:43.190Z
Learning: In the clp-package compression flow, path validation and error handling is performed at the scheduler level rather than in the compress.py script to maintain simplicity and avoid code duplication.
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/job-orchestration/job_orchestration/scheduler/job_config.py:29-39
Timestamp: 2025-01-15T16:36:48.932Z
Learning: The S3 service in the clp codebase only supports AWS S3, where region_code is mandatory. Other S3-like services are not supported.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/src/lib.rs
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
  • components/clp-rust-utils/Cargo.toml
📚 Learning: 2025-01-15T16:36:48.932Z
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/job-orchestration/job_orchestration/scheduler/job_config.py:29-39
Timestamp: 2025-01-15T16:36:48.932Z
Learning: The S3 service in the clp codebase only supports AWS S3, where region_code is mandatory. Other S3-like services are not supported.

Applied to files:

  • components/clp-rust-utils/src/clp_config/s3_config.rs
📚 Learning: 2025-10-22T21:01:31.391Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.

Applied to files:

  • components/clp-rust-utils/Cargo.toml
📚 Learning: 2025-10-20T22:20:45.733Z
Learnt from: LinZhihao-723
PR: y-scope/clp#1448
File: components/clp-rust-utils/Cargo.toml:4-4
Timestamp: 2025-10-20T22:20:45.733Z
Learning: Rust edition 2024 is a valid edition value in Cargo.toml files. It was released with Rust 1.85 on February 20, 2025.

Applied to files:

  • components/clp-rust-utils/Cargo.toml
🧬 Code graph analysis (5)
components/clp-rust-utils/src/clp_config/s3_config.rs (1)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • OutputConfig (47-53)
  • ClpIoConfig (56-58)
  • S3InputConfig (32-44)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (2)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (1)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/clp_config/scheduler/output_config.rs (1)
components/job-orchestration/job_orchestration/scheduler/job_config.py (1)
  • OutputConfig (47-53)
components/clp-rust-utils/src/clp_config/aws_authentication.rs (1)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • AwsAuthentication (386-416)
⏰ 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). (6)
  • GitHub Check: package-image
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: rust-checks (macos-15)
  • GitHub Check: rust-checks (ubuntu-24.04)
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (5)
components/clp-rust-utils/src/lib.rs (1)

1-3: LGTM!

The module declaration follows the existing pattern and correctly exposes the new clp_config module.

components/clp-rust-utils/src/clp_config/scheduler.rs (1)

1-7: LGTM!

The module structure and re-exports follow Rust conventions and provide a clean public API for scheduler-related configuration types.

components/clp-rust-utils/src/clp_config.rs (1)

1-7: LGTM!

The module organization provides a clean separation between public scheduler components and internal configuration details, with controlled re-exports for the public API.

components/clp-rust-utils/src/clp_config/scheduler/output_config.rs (1)

1-12: LGTM!

The OutputConfig struct matches the Python implementation's fields and uses appropriate types. Field order differences are fine with named serialization.

components/clp-rust-utils/Cargo.toml (1)

7-18: Dependency versions verified as current and secure.

All versions are current: brotli 8.0.2, rmp-serde 1.3.0, and anyhow 1.0.100. No critical vulnerabilities detected. A historical MODERATE-severity vulnerability in rmp-serde affects versions below 1.1.1; the version used (1.3.0) is well after the patch.

Comment thread components/clp-rust-utils/src/clp_config/aws_authentication.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/aws_authentication.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/s3_config.rs
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/input_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/input_config.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (1)

22-22: Add TODO comment for deferred keys validation.

The keys field lacks validation to prevent an empty vector, which is invalid according to the Python implementation (components/job-orchestration/job_orchestration/scheduler/job_config.py lines 38-42). Since the PR summary indicates that validation will be added in subsequent PRs, consider adding a TODO comment to track this requirement:

+    // TODO: Add validation to reject empty keys list when deserialization support is added
+    // (matches Python implementation's validate_keys validator)
     pub keys: Option<Vec<String>>,
components/clp-rust-utils/src/clp_config/aws_authentication.rs (1)

11-16: Security risk: Debug trait exposes secret credentials.

The AwsCredentials struct derives Debug (line 12), which will print secret_access_key in plain text. This creates a security risk where secrets could be exposed in logs, error messages, or debug output.

Either remove the Debug derivation or implement a custom Debug that redacts the secret:

-#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
+#[derive(Clone, PartialEq, Eq, Serialize)]
 pub struct AwsCredentials {
     pub access_key_id: String,
     pub secret_access_key: String,
 }
+
+impl std::fmt::Debug for AwsCredentials {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("AwsCredentials")
+            .field("access_key_id", &self.access_key_id)
+            .field("secret_access_key", &"[REDACTED]")
+            .finish()
+    }
+}

Alternatively, consider using the secrecy crate for handling sensitive data.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1c924f and b62c32c.

📒 Files selected for processing (4)
  • components/clp-rust-utils/src/clp_config/aws_authentication.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/s3_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
PR: y-scope/clp#1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
  • components/clp-rust-utils/src/clp_config/scheduler/input_config.rs
📚 Learning: 2024-11-01T03:26:26.386Z
Learnt from: LinZhihao-723
PR: y-scope/clp#570
File: components/core/tests/test-ir_encoding_methods.cpp:376-399
Timestamp: 2024-11-01T03:26:26.386Z
Learning: In the test code (`components/core/tests/test-ir_encoding_methods.cpp`), exception handling for `msgpack::unpack` can be omitted because the Catch2 testing framework captures exceptions if they occur.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-10-13T09:27:43.408Z
Learnt from: LinZhihao-723
PR: y-scope/clp#557
File: components/core/tests/test-ir_encoding_methods.cpp:1216-1286
Timestamp: 2024-10-13T09:27:43.408Z
Learning: In the unit test case `ffi_ir_stream_serialize_schema_tree_node_id` in `test-ir_encoding_methods.cpp`, suppressing the `readability-function-cognitive-complexity` warning is acceptable due to the expansion of Catch2 macros in C++ tests, and such test cases may not have readability issues.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2025-10-22T21:01:31.391Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/input_config.rs
📚 Learning: 2025-01-15T16:36:48.932Z
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/job-orchestration/job_orchestration/scheduler/job_config.py:29-39
Timestamp: 2025-01-15T16:36:48.932Z
Learning: The S3 service in the clp codebase only supports AWS S3, where region_code is mandatory. Other S3-like services are not supported.

Applied to files:

  • components/clp-rust-utils/src/clp_config/s3_config.rs
🧬 Code graph analysis (4)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • OutputConfig (47-53)
  • ClpIoConfig (56-58)
  • S3InputConfig (32-44)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (2)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (1)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/clp_config/aws_authentication.rs (1)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • AwsAuthentication (386-416)
components/clp-rust-utils/src/clp_config/s3_config.rs (1)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
⏰ 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). (6)
  • GitHub Check: package-image
  • GitHub Check: rust-checks (macos-15)
  • GitHub Check: rust-checks (ubuntu-24.04)
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (4)
components/clp-rust-utils/src/clp_config/s3_config.rs (1)

5-12: LGTM! Field names now match the Python implementation.

The struct correctly uses region_code and key_prefix to match the Python implementation in clp_py_utils/clp_config.py, ensuring MessagePack serialization compatibility between Rust and Python components.

components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)

9-14: LGTM! Struct definition is correct.

The ClpIoConfig structure properly encapsulates input and output configurations with appropriate derives for serialization and comparison.


80-90: Test uses hardcoded compressed bytes; consider documenting brittleness.

The test compares against a hardcoded hex-encoded Brotli-compressed MessagePack blob (lines 83-90). This will break if the Brotli or MessagePack library implementations change, even though the logical output remains correct.

Since deserialization support is deferred to a subsequent PR, consider adding a comment documenting that this is a snapshot test that may require updating if compression details change. Once deserialization is implemented, a round-trip test would be more robust.

components/clp-rust-utils/src/clp_config/scheduler/input_config.rs (1)

5-14: LGTM! InputConfig enum structure is correct.

The tagged enum with flattened S3InputConfig correctly mirrors the Python implementation's discriminated union pattern for input configurations.

Comment on lines +29 to +34
pub fn to_brotli_compressed_msgpack(&self) -> Result<Vec<u8>> {
let msgpack_data = rmp_serde::to_vec_named(self)?;
let mut brotli_compressor = CompressorWriter::new(Vec::new(), 4096, 5, 22);
brotli_compressor.write_all(&msgpack_data)?;
Ok(brotli_compressor.into_inner())
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider documenting Brotli compression parameters.

The hardcoded values 4096, 5, 22 in CompressorWriter::new lack documentation. While the implementation is correct, adding constants or inline comments would improve maintainability:

  • 4096: buffer size
  • 5: quality/compression level (0-11 scale)
  • 22: log window size

Example with constants:

const BROTLI_BUFFER_SIZE: usize = 4096;
const BROTLI_QUALITY: u32 = 5;
const BROTLI_WINDOW_SIZE: u32 = 22;

pub fn to_brotli_compressed_msgpack(&self) -> Result<Vec<u8>> {
    let msgpack_data = rmp_serde::to_vec_named(self)?;
    let mut brotli_compressor = CompressorWriter::new(
        Vec::new(),
        BROTLI_BUFFER_SIZE,
        BROTLI_QUALITY,
        BROTLI_WINDOW_SIZE,
    );
    brotli_compressor.write_all(&msgpack_data)?;
    Ok(brotli_compressor.into_inner())
}
🤖 Prompt for AI Agents
In components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs around
lines 29 to 34, the Brotli CompressorWriter parameters are hardcoded (4096, 5,
22) without explanation; replace these magic numbers with well-named constants
(e.g., BROTLI_BUFFER_SIZE, BROTLI_QUALITY, BROTLI_WINDOW_SIZE) declared near the
top of the file and use them in CompressorWriter::new, and add a brief inline
comment documenting each constant meaning and valid ranges.

@hoophalab hoophalab left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me in general. Some comments.

Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated
…ig.rs

Co-authored-by: hoophalab <200652805+hoophalab@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (4)

3-3: Library should use custom error types instead of anyhow.

As noted in previous reviews, using anyhow::Result in library code prevents users from handling specific error types distinctly (e.g., retrying on network errors vs. panicking on serialization errors).


29-34: Serialization logic is correct, but magic numbers remain undocumented.

The implementation correctly serializes to MessagePack and compresses with Brotli. However, the hardcoded parameters 4096, 5, 22 in CompressorWriter::new lack documentation, as noted in previous reviews.


80-89: Brittle test design with hardcoded compressed output.

As noted in previous reviews, this test compares against a hardcoded Brotli-compressed hex string, which will break if the Brotli or MessagePack library implementations change.


91-121: JSON string comparison should use Value comparison.

As discussed in previous reviews, comparing serialized JSON strings is fragile due to potential key ordering differences. Using serde_json::Value comparison would be more robust, and this change was already agreed upon.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b62c32c and ac2b52a.

📒 Files selected for processing (1)
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
PR: y-scope/clp#1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-11-01T03:26:26.386Z
Learnt from: LinZhihao-723
PR: y-scope/clp#570
File: components/core/tests/test-ir_encoding_methods.cpp:376-399
Timestamp: 2024-11-01T03:26:26.386Z
Learning: In the test code (`components/core/tests/test-ir_encoding_methods.cpp`), exception handling for `msgpack::unpack` can be omitted because the Catch2 testing framework captures exceptions if they occur.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-10-13T09:27:43.408Z
Learnt from: LinZhihao-723
PR: y-scope/clp#557
File: components/core/tests/test-ir_encoding_methods.cpp:1216-1286
Timestamp: 2024-10-13T09:27:43.408Z
Learning: In the unit test case `ffi_ir_stream_serialize_schema_tree_node_id` in `test-ir_encoding_methods.cpp`, suppressing the `readability-function-cognitive-complexity` warning is acceptable due to the expansion of Catch2 macros in C++ tests, and such test cases may not have readability issues.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-10-08T15:52:50.753Z
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/src/clp/ffi/ir_stream/Deserializer.hpp:209-210
Timestamp: 2024-10-08T15:52:50.753Z
Learning: Until #486 is merged with customized error code support, introducing a layer from `IRErrorCode` to `std::errc` is unnecessary.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
🧬 Code graph analysis (1)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • OutputConfig (47-53)
  • ClpIoConfig (56-58)
  • S3InputConfig (32-44)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
⏰ 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). (6)
  • GitHub Check: package-image
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: rust-checks (macos-15)
  • GitHub Check: rust-checks (ubuntu-24.04)
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
🔇 Additional comments (2)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)

9-14: Struct definition looks good.

The struct is appropriately derived and documented. The absence of Deserialize aligns with the PR's stated plan to add deserialization support in future work.


47-78: Test setup is comprehensive.

The test properly constructs a realistic ClpIoConfig with appropriate test data covering S3 authentication, optional fields, and reasonable size parameters.

Comment thread components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/clp-rust-utils/Cargo.toml (1)

4-4: Fix invalid Rust edition.

The edition "2024" is invalid. Valid Rust editions are "2015", "2018", and "2021". This will cause a compilation error.

Apply this diff to fix the edition:

-edition = "2024"
+edition = "2021"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac2b52a and b391eb3.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • components/clp-rust-utils/Cargo.toml (1 hunks)
  • components/clp-rust-utils/src/clp_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/s3_config.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler.rs (1 hunks)
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (1 hunks)
  • components/clp-rust-utils/src/error.rs (1 hunks)
  • components/clp-rust-utils/src/lib.rs (1 hunks)
  • components/clp-rust-utils/src/utils.rs (1 hunks)
  • components/clp-rust-utils/src/utils/brotli_msgpack.rs (1 hunks)
  • components/clp-rust-utils/tests/clp_config_test.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
PR: y-scope/clp#1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: AVMatthews
PR: y-scope/clp#543
File: components/core/src/clp_s/clp-s.cpp:196-265
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In `clp-s.cpp`, the `run_serializer` function interleaves serialization and writing of IR files, making it difficult to restructure it into separate functions.
Learnt from: AVMatthews
PR: y-scope/clp#543
File: components/core/src/clp_s/clp-s.cpp:196-265
Timestamp: 2024-10-07T20:10:08.254Z
Learning: In `clp-s.cpp`, the `run_serializer` function interleaves serialization and writing of IR files, making it difficult to restructure it into separate functions.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/src/clp_config.rs
  • components/clp-rust-utils/src/lib.rs
  • components/clp-rust-utils/tests/clp_config_test.rs
  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
  • components/clp-rust-utils/Cargo.toml
📚 Learning: 2025-10-22T21:01:31.391Z
Learnt from: junhaoliao
PR: y-scope/clp#0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
  • components/clp-rust-utils/Cargo.toml
📚 Learning: 2024-11-01T03:26:26.386Z
Learnt from: LinZhihao-723
PR: y-scope/clp#570
File: components/core/tests/test-ir_encoding_methods.cpp:376-399
Timestamp: 2024-11-01T03:26:26.386Z
Learning: In the test code (`components/core/tests/test-ir_encoding_methods.cpp`), exception handling for `msgpack::unpack` can be omitted because the Catch2 testing framework captures exceptions if they occur.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-10-13T09:27:43.408Z
Learnt from: LinZhihao-723
PR: y-scope/clp#557
File: components/core/tests/test-ir_encoding_methods.cpp:1216-1286
Timestamp: 2024-10-13T09:27:43.408Z
Learning: In the unit test case `ffi_ir_stream_serialize_schema_tree_node_id` in `test-ir_encoding_methods.cpp`, suppressing the `readability-function-cognitive-complexity` warning is acceptable due to the expansion of Catch2 macros in C++ tests, and such test cases may not have readability issues.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-10-08T15:52:50.753Z
Learnt from: LinZhihao-723
PR: y-scope/clp#549
File: components/core/src/clp/ffi/ir_stream/Deserializer.hpp:209-210
Timestamp: 2024-10-08T15:52:50.753Z
Learning: Until #486 is merged with customized error code support, introducing a layer from `IRErrorCode` to `std::errc` is unnecessary.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
📚 Learning: 2024-11-15T03:15:45.919Z
Learnt from: LinZhihao-723
PR: y-scope/clp#593
File: components/core/tests/test-NetworkReader.cpp:216-219
Timestamp: 2024-11-15T03:15:45.919Z
Learning: In the `network_reader_with_valid_http_header_kv_pairs` test case in `components/core/tests/test-NetworkReader.cpp`, additional error handling for JSON parsing failures is not necessary, as the current error message is considered sufficient.

Applied to files:

  • components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs
🧬 Code graph analysis (3)
components/clp-rust-utils/tests/clp_config_test.rs (3)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/utils/brotli_msgpack.rs (1)
  • serialize (23-28)
components/clp-rust-utils/src/clp_config/scheduler/clp_io_config.rs (2)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/clp_config/s3_config.rs (1)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • S3Config (419-423)
  • AwsAuthentication (386-416)
⏰ 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). (6)
  • GitHub Check: package-image
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: rust-checks (macos-15)
  • GitHub Check: rust-checks (ubuntu-24.04)
🔇 Additional comments (8)
components/clp-rust-utils/src/clp_config/scheduler.rs (1)

1-3: LGTM!

The module declaration and re-export pattern is clean and idiomatic.

components/clp-rust-utils/src/clp_config.rs (1)

1-5: LGTM!

The module organization is clean: scheduler is publicly exposed as a module, while s3_config implementation details are encapsulated but its public items are re-exported for external use.

components/clp-rust-utils/src/utils.rs (1)

1-3: LGTM!

The module declaration and re-export pattern is consistent with the crate's organizational style.

components/clp-rust-utils/tests/clp_config_test.rs (1)

56-90: LGTM!

The JSON serialization test provides good validation of the structure and is more maintainable than the hex comparison since it parses both actual and expected JSON for structural equality.

components/clp-rust-utils/src/lib.rs (1)

1-7: LGTM!

The module organization is clean and follows Rust conventions: new public modules (clp_config, utils) are exposed, the error module is kept private while re-exporting the public Error type, and existing modules remain unchanged.

components/clp-rust-utils/src/error.rs (1)

1-10: LGTM!

The error type is well-designed using thiserror for idiomatic Rust error handling. It covers the necessary error cases (MessagePack encoding and IO) with automatic conversions via #[from] and clear display messages.

components/clp-rust-utils/src/utils/brotli_msgpack.rs (1)

23-28: LGTM!

The serialization implementation is correct: MessagePack encoding followed by Brotli compression with proper error propagation. The function signature is appropriately generic with ?Sized to accept DST references.

components/clp-rust-utils/Cargo.toml (1)

10-14: Dependencies are already at latest stable versions with no known security vulnerabilities.

Verification confirms all four dependencies (brotli, rmp-serde, serde, thiserror) are pinned to their latest stable releases. No security advisories were detected for any of these packages.

Comment thread components/clp-rust-utils/src/clp_config/s3_config.rs
Comment thread components/clp-rust-utils/src/serde/brotli_msgpack.rs
Comment thread components/clp-rust-utils/tests/clp_config_test.rs
hoophalab
hoophalab previously approved these changes Oct 30, 2025

@hoophalab hoophalab left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Approved. There are some nitpicks. Feel free to keep them as-is.

Comment thread components/clp-rust-utils/src/job_config/clp_io_config.rs
Comment thread components/clp-rust-utils/src/serde.rs
Comment thread components/clp-rust-utils/tests/clp_config_test.rs Outdated
Co-authored-by: hoophalab <200652805+hoophalab@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b391eb3 and 5207d06.

📒 Files selected for processing (1)
  • components/clp-rust-utils/tests/clp_config_test.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2025-10-22T21:01:31.391Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-11-19T17:30:04.970Z
Learnt from: AVMatthews
Repo: y-scope/clp PR: 595
File: components/core/tests/test-end_to_end.cpp:59-65
Timestamp: 2024-11-19T17:30:04.970Z
Learning: In 'components/core/tests/test-end_to_end.cpp', during the 'clp-s_compression_and_extraction_no_floats' test, files and directories are intentionally removed at the beginning of the test to ensure that any existing content doesn't influence the test results.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-10-13T09:27:43.408Z
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 557
File: components/core/tests/test-ir_encoding_methods.cpp:1216-1286
Timestamp: 2024-10-13T09:27:43.408Z
Learning: In the unit test case `ffi_ir_stream_serialize_schema_tree_node_id` in `test-ir_encoding_methods.cpp`, suppressing the `readability-function-cognitive-complexity` warning is acceptable due to the expansion of Catch2 macros in C++ tests, and such test cases may not have readability issues.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-11-01T03:26:26.386Z
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 570
File: components/core/tests/test-ir_encoding_methods.cpp:376-399
Timestamp: 2024-11-01T03:26:26.386Z
Learning: In the test code (`components/core/tests/test-ir_encoding_methods.cpp`), exception handling for `msgpack::unpack` can be omitted because the Catch2 testing framework captures exceptions if they occur.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
🧬 Code graph analysis (1)
components/clp-rust-utils/tests/clp_config_test.rs (3)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/utils/brotli_msgpack.rs (1)
  • serialize (23-28)
🪛 GitHub Actions: clp-rust-checks
components/clp-rust-utils/tests/clp_config_test.rs

[error] 57-57: Rust fmt check failed (lint:rust-workspace-fmt). Proposed fix: run 'cargo +nightly fmt --all -- --check' or 'cargo +nightly fmt --all' to auto-format.

⏰ 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). (3)
  • GitHub Check: package-image
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: rust-checks (macos-15)
🔇 Additional comments (1)
components/clp-rust-utils/tests/clp_config_test.rs (1)

59-88: Good implementation of JSON validation test.

The use of serde_json::json! macro for constructing the expected JSON structure makes the test more readable and maintainable compared to string literals. The approach of parsing both expected and actual JSON to Value for comparison is robust and handles formatting differences well.

Comment thread components/clp-rust-utils/tests/clp_config_test.rs
Comment thread components/clp-rust-utils/tests/clp_config_test.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
components/clp-rust-utils/src/serde/brotli_msgpack.rs (1)

23-28: Document Brotli compression parameter choices.

The hardcoded Brotli parameters (buffer: 4096, quality: 5, lgwin: 22) lack explanation. Please add a comment documenting why these values were selected, especially whether they must match the Python implementation for compatibility, and any trade-offs considered (compression ratio vs CPU/memory usage).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2ff1e1 and 59e6627.

📒 Files selected for processing (7)
  • components/clp-rust-utils/src/clp_config.rs (1 hunks)
  • components/clp-rust-utils/src/job_config.rs (1 hunks)
  • components/clp-rust-utils/src/job_config/clp_io_config.rs (1 hunks)
  • components/clp-rust-utils/src/lib.rs (1 hunks)
  • components/clp-rust-utils/src/serde.rs (1 hunks)
  • components/clp-rust-utils/src/serde/brotli_msgpack.rs (1 hunks)
  • components/clp-rust-utils/tests/clp_config_test.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
  • components/clp-rust-utils/src/lib.rs
  • components/clp-rust-utils/src/clp_config.rs
📚 Learning: 2025-10-22T21:01:31.391Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-10-13T09:27:43.408Z
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 557
File: components/core/tests/test-ir_encoding_methods.cpp:1216-1286
Timestamp: 2024-10-13T09:27:43.408Z
Learning: In the unit test case `ffi_ir_stream_serialize_schema_tree_node_id` in `test-ir_encoding_methods.cpp`, suppressing the `readability-function-cognitive-complexity` warning is acceptable due to the expansion of Catch2 macros in C++ tests, and such test cases may not have readability issues.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-11-01T03:26:26.386Z
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 570
File: components/core/tests/test-ir_encoding_methods.cpp:376-399
Timestamp: 2024-11-01T03:26:26.386Z
Learning: In the test code (`components/core/tests/test-ir_encoding_methods.cpp`), exception handling for `msgpack::unpack` can be omitted because the Catch2 testing framework captures exceptions if they occur.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-11-15T03:15:45.919Z
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 593
File: components/core/tests/test-NetworkReader.cpp:216-219
Timestamp: 2024-11-15T03:15:45.919Z
Learning: In the `network_reader_with_valid_http_header_kv_pairs` test case in `components/core/tests/test-NetworkReader.cpp`, additional error handling for JSON parsing failures is not necessary, as the current error message is considered sufficient.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-10-07T21:35:04.362Z
Learnt from: AVMatthews
Repo: y-scope/clp PR: 543
File: components/core/src/clp_s/JsonParser.cpp:735-794
Timestamp: 2024-10-07T21:35:04.362Z
Learning: In `components/core/src/clp_s/JsonParser.cpp`, within the `parse_from_ir` method, encountering errors from `kv_log_event_result.error()` aside from `std::errc::no_message_available` and `std::errc::result_out_of_range` is anticipated behavior and does not require additional error handling or logging.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-10-07T21:16:41.660Z
Learnt from: AVMatthews
Repo: y-scope/clp PR: 543
File: components/core/src/clp_s/JsonParser.cpp:769-779
Timestamp: 2024-10-07T21:16:41.660Z
Learning: In `components/core/src/clp_s/JsonParser.cpp`, when handling errors in `parse_from_ir`, prefer to maintain the current mix of try-catch and if-statements because specific messages are returned back up in some cases.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2024-11-18T16:49:20.248Z
Learnt from: haiqi96
Repo: y-scope/clp PR: 594
File: components/clp-package-utils/clp_package_utils/scripts/del_archives.py:56-65
Timestamp: 2024-11-18T16:49:20.248Z
Learning: When reviewing wrapper scripts in `components/clp-package-utils/clp_package_utils/scripts/`, note that it's preferred to keep error handling simple without adding extra complexity.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2025-10-22T21:14:12.225Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1466
File: .github/workflows/clp-rust-checks.yaml:14-15
Timestamp: 2025-10-22T21:14:12.225Z
Learning: Repository y-scope/clp: In GitHub Actions workflows (e.g., .github/workflows/clp-rust-checks.yaml), YAML anchors/aliases are acceptable and preferred to avoid duplication; if actionlint flags an alias node (e.g., on push.paths) as an error, treat it as a tool limitation and do not require inlining unless the team asks to silence the warning.

Applied to files:

  • components/clp-rust-utils/tests/clp_config_test.rs
📚 Learning: 2025-07-23T09:54:45.185Z
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.

Applied to files:

  • components/clp-rust-utils/src/serde/brotli_msgpack.rs
🧬 Code graph analysis (2)
components/clp-rust-utils/tests/clp_config_test.rs (3)
components/clp-py-utils/clp_py_utils/clp_config.py (2)
  • AwsAuthentication (386-416)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
components/clp-rust-utils/src/serde/brotli_msgpack.rs (1)
  • serialize (23-28)
components/clp-rust-utils/src/job_config/clp_io_config.rs (2)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
⏰ 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). (7)
  • GitHub Check: package-image
  • GitHub Check: rust-checks (ubuntu-24.04)
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: antlr-code-committed (macos-15)
  • GitHub Check: lint-check (macos-15)
  • GitHub Check: lint-check (ubuntu-24.04)
  • GitHub Check: build (macos-15)
🔇 Additional comments (7)
components/clp-rust-utils/src/clp_config.rs (1)

1-3: LGTM!

The module declaration and re-export follow standard Rust conventions and provide a clean public API for S3 configuration types.

components/clp-rust-utils/src/serde.rs (1)

1-3: LGTM!

The module declaration and re-export follow standard Rust conventions and expose the BrotliMsgpack serialization utility through a clean public API.

components/clp-rust-utils/src/job_config.rs (1)

1-3: LGTM!

The module declaration and re-export follow standard Rust conventions and expose CLP IO configuration types through a clean public API.

components/clp-rust-utils/tests/clp_config_test.rs (1)

8-84: Comprehensive serialization test coverage.

The test effectively validates both Brotli-compressed MessagePack and JSON serialization formats. The JSON test using serde_json::json! macro provides clear, maintainable validation of the expected structure.

components/clp-rust-utils/src/lib.rs (1)

1-8: LGTM!

The module organization is clean and follows Rust conventions. New modules are properly exposed through the public API, and the Error type re-export provides convenient access for crate consumers.

components/clp-rust-utils/src/job_config/clp_io_config.rs (2)

24-33: Note: Keys validation deferred to future PR.

The Python equivalent includes validation that keys cannot be an empty list when non-null. The PR description indicates validations will be added later, so this is tracked accordingly.

For future implementation, consider validating that keys, when present, is non-empty to match Python behaviour.


1-44: Well-structured configuration types with proper serialization support.

The implementation correctly mirrors the Python configuration model with appropriate serde attributes. The use of #[serde(flatten)] and #[serde(tag = "type")] will produce the expected JSON structure as validated by the tests.

Comment thread components/clp-rust-utils/src/job_config/clp_io_config.rs Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59e6627 and 1547cfe.

📒 Files selected for processing (1)
  • components/clp-rust-utils/src/job_config/clp_io_config.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Bill-hbrhbr
Repo: y-scope/clp PR: 1122
File: components/core/src/clp/clp/CMakeLists.txt:175-195
Timestamp: 2025-07-23T09:54:45.185Z
Learning: In the CLP project, when reviewing CMakeLists.txt changes that introduce new compression library dependencies (BZip2, LibLZMA, LZ4, ZLIB), the team prefers to address conditional linking improvements in separate PRs rather than expanding the scope of focused migration PRs like the LibArchive task-based installation migration.
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).
Learnt from: junhaoliao
Repo: y-scope/clp PR: 1152
File: components/clp-package-utils/clp_package_utils/scripts/start_clp.py:613-613
Timestamp: 2025-08-08T06:59:42.436Z
Learning: In components/clp-package-utils/clp_package_utils/scripts/start_clp.py, generic_start_scheduler sets CLP_LOGGING_LEVEL using clp_config.query_scheduler.logging_level for both schedulers; compression scheduler should use its own logging level. Tracking via an issue created from PR #1152 discussion.
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:01:31.391Z
Learning: In y-scope/clp, for the clp-rust-checks workflow (GitHub Actions) and the Taskfile target deps:lock:check-rust, we should verify Rust Cargo.lock is in sync with Cargo.toml using a non-mutating method (e.g., cargo metadata --locked / cargo check --locked) to keep CI deterministic and avoid updating dependencies during validation.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-01T07:59:11.208Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
Learnt from: LinZhihao-723
Repo: y-scope/clp PR: 549
File: components/core/tests/test-ir_encoding_methods.cpp:1180-1186
Timestamp: 2024-10-08T15:52:50.753Z
Learning: In the context of loop constructs, LinZhihao-723 prefers using `while (true)` loops and does not consider alternative loop constructs necessarily more readable.
📚 Learning: 2025-10-22T21:02:31.113Z
Learnt from: junhaoliao
Repo: y-scope/clp PR: 0
File: :0-0
Timestamp: 2025-10-22T21:02:31.113Z
Learning: Repository y-scope/clp: Maintain deterministic CI/builds for Rust; add a check to verify Cargo.lock is in sync with Cargo.toml without updating dependencies (non-mutating verification in clp-rust-checks workflow).

Applied to files:

  • components/clp-rust-utils/src/job_config/clp_io_config.rs
🧬 Code graph analysis (1)
components/clp-rust-utils/src/job_config/clp_io_config.rs (2)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • S3Config (419-423)
components/job-orchestration/job_orchestration/scheduler/job_config.py (3)
  • ClpIoConfig (56-58)
  • OutputConfig (47-53)
  • S3InputConfig (32-44)
⏰ 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). (4)
  • GitHub Check: rust-checks (ubuntu-24.04)
  • GitHub Check: rust-checks (ubuntu-22.04)
  • GitHub Check: rust-checks (macos-15)
  • GitHub Check: package-image
🔇 Additional comments (5)
components/clp-rust-utils/src/job_config/clp_io_config.rs (5)

1-3: LGTM!

The imports are appropriate and minimal. The serde Serialize trait and S3Config dependency are correctly imported.


5-10: LGTM!

The ClpIoConfig struct properly mirrors the Python implementation with appropriate derives for a serializable configuration type.


12-21: LGTM!

The enum correctly uses serde tagging and flattening to produce the expected serialization format that mirrors the Python implementation where S3InputConfig has a type field and inherits from S3Config.


32-32: Consider adding #[serde(default)] when deserialization support is added.

The Python implementation defaults unstructured to False, but the Rust version has no default. When deserialization support is added in future PRs, consider adding #[serde(default)] to this field so it defaults to false when absent during deserialization, maintaining parity with the Python behaviour.


43-43: Compression level u8 type is appropriate.

Verification confirms that all compression algorithms used in CLP (Zstd: 1-19, LZMA: 0-9) have levels well within the u8 range (0-255). The type change from Python's int is a safe narrowing that matches the actual compression level ranges used throughout the codebase.

Comment thread components/clp-rust-utils/src/job_config/clp_io_config.rs
@LinZhihao-723 LinZhihao-723 merged commit e81dbfc into y-scope:main Oct 31, 2025
23 checks passed
junhaoliao pushed a commit to junhaoliao/clp that referenced this pull request May 17, 2026
…on structs with Brotli-compressed MessagePack serialization support. (y-scope#1523)

Co-authored-by: hoophalab <200652805+hoophalab@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants