Skip to content

Rust::com Rust APIs Example app Optimize#556

Open
bharatGoswami8 wants to merge 3 commits into
eclipse-score:mainfrom
bharatGoswami8:rust_example_update
Open

Rust::com Rust APIs Example app Optimize#556
bharatGoswami8 wants to merge 3 commits into
eclipse-score:mainfrom
bharatGoswami8:rust_example_update

Conversation

@bharatGoswami8

@bharatGoswami8 bharatGoswami8 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
  • Created Example app which can run based on CLI argument like only Producer / Consumer or Both and different Async APIs of Consumer.
  • Independent a test unit kept which use tokio runtime for async testing.

#489

@bharatGoswami8 bharatGoswami8 force-pushed the rust_example_update branch 2 times, most recently from 9e5470a to c4a5d19 Compare June 25, 2026 07:19
* Updated example binary with proper structure
* Kept only async test cases using tokio

@rpreddyhv rpreddyhv left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

few comments & queries to clarify.

Comment thread score/mw/com/example/com-api-example/BUILD
Comment thread score/mw/com/example/com-api-example/main.rs Outdated
Comment thread score/mw/com/example/com-api-example/tests_using_tokio_runtime.rs
Comment thread score/mw/com/example/com-api-example/src/consumer.rs
Comment thread score/mw/com/example/com-api-example/main.rs
Comment thread score/mw/com/example/com-api-example/tests_using_tokio_runtime.rs Outdated
Comment thread score/mw/com/example/com-api-example/tests_using_tokio_runtime.rs Outdated
- **Consumer Thread**: Receives and processes data independently

### Async Operations
- Uses `futures::executor::block_on()` for async operations

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.

Sloppy - block_on is synchronous. AI should elaborate more about the execution model instead of making obvious but inaccurate statements like here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rephrased the statement.


A separate test target (`tests_using_tokio_runtime.rs`) provides comprehensive integration tests using the **Tokio async runtime**. These tests are independent of the main application and use the `com-api-gen` generated types together with the `com_api` runtime, service discovery, and subscription APIs directly.

**Why Separate?**

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.

I don't get how the points below answer this question.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It was added to give impression why we have iteration test separately with tokio, so the simple reason for that is we do not want to use tokio in application and as we have already existing test case with tokio which can be used for quick and async runtime related testing.

/// All execution modes supported by the example application.
/// Used by clap for CLI argument parsing and by the consumer/producer to select behaviour.
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum ExampleType {

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.

Why is this here? Imo that's clearly something that does not belong in a library but to the main CLI crate.

@bharatGoswami8 bharatGoswami8 Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes in first iteration of implementation, it was in main file and we were having different functions for each operation, but as it was calling separate function for each APIs so i thought to generalize and keep minimum function call from main and parsing can be done on library,
But I agree in that case sync execution is done with async function which is not proper way.

I have moved to the first iteration design.

load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")

rust_library(

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.

Please choose the 2024 edition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added.

Err(e) => eprintln!("[SENDER] Failed to send sample: {:?}", e),
}
println!("[SENDER] Sent sample with pressure: {}", 1.0 + i as f32);
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;

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.

Magic number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

created const

let mut buffer = SampleContainer::new(5);
for _ in 0..3 {
let (returned_buf, result) = if is_timeout {
let timeout = tokio::time::sleep(Duration::from_millis(1000));

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.

Magic number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

created const

/// Polling interval between iterations in synchronous receive loops.
const SYNC_RECEIVE_POLL_INTERVAL_MS: u64 = 1000;

impl<R: Runtime> VehicleMonitorConsumer<R> {

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.

Is there a reason why the impl block is separate from the type definition. Imo this only makes it harder to comprehend the logic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was thinking to keep vehicleMonitor on separate module for better modularity but agreed to your point moved type into same file and removed vehicle_monitor file.

let consumer_discovery =
runtime.find_service::<VehicleInterface>(FindServiceSpecifier::Specific(service_id));
let instances = match mode {
ExampleType::Sync => consumer_discovery

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.

Using a parameter to distinguish between sync and async doesn't make sense imo, as the call is enclosed in an async function in any case. I think you should split this into a sync and an async create function instead.

Now thinking about it, the definition of get_available_instances_async is odd: What's the async part of this method actually waiting for? Presence of at least one instance? If yes, then this behavior should be documented.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved async and sync APIs in separate function and behavior is documented.

///
/// Takes `&self` to support all receive modes including streaming,
/// which requires exclusive access to the subscriber.
pub async fn read_tire_data(&self, mode: &ExampleType) -> Result<String> {

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.

Same comment as in the new case: Having a sync code path in an async function isn't wrong (as log as it's nonblocking, which is the case), but kinda pointless: Why have the burden of an async function without any benefit?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, it may give wrong impression to user as well, so moved async and sync function separately.

Err(e) => Err(e),
}
}
_ => unreachable!(

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.

Another code smell that reveals the non-ideal design here: This method isn't defined for all modes, which leads to mixing static and dynamic properties in this regard.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As enum moved to main so now design is purely based on each APIs function call.

@bharatGoswami8 bharatGoswami8 force-pushed the rust_example_update branch 2 times, most recently from ec2bd21 to 3fbbbd6 Compare July 1, 2026 08:26
* Optimize the application
* Remove VehicleMonitor and keep only lib
* Keep enum parsing on main
* Updated integration test

@rpreddyhv rpreddyhv left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks okay to me!

@bharatGoswami8 bharatGoswami8 requested a review from rpreddyhv July 1, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

3 participants