Skip to content

feat(cpp): add functions related to system#3102

Open
slbotbm wants to merge 5 commits into
apache:masterfrom
slbotbm:cpp-system-functions
Open

feat(cpp): add functions related to system#3102
slbotbm wants to merge 5 commits into
apache:masterfrom
slbotbm:cpp-system-functions

Conversation

@slbotbm
Copy link
Copy Markdown
Contributor

@slbotbm slbotbm commented Apr 12, 2026

Which issue does this PR close?

Works toward completion of #2100

Rationale

This PR adds functions related to the system, and tests for previously untested functions.

What changed?

This PR adds:

  • The following functions and their tests:
    • get_stats
    • get_me
    • get_client
    • get_clients
    • ping
    • heartbeat_interval
    • snapshot

The places labelled TODO will be completed after merging of #3046.

Local Execution

  • Passed
  • Pre-commit hooks ran

AI Usage

If AI tools were used, please answer:

  1. Which tools? (e.g., GitHub Copilot, Claude, ChatGPT) codex
  2. Scope of usage? (e.g., autocomplete, generated functions, entire implementation) code generation based on explicit instructions given by me.
  3. How did you verify the generated code works correctly? ran the tests, read through and understood the generated code
  4. Can you explain every line of the code if asked? yes

@slbotbm slbotbm marked this pull request as draft April 12, 2026 14:29
@slbotbm slbotbm changed the title feata(cpp): add functions related to system, tests for purge_* functions, and consumer group functions (WIP) feat(cpp): add functions related to system, tests for purge_* functions, and consumer group functions (WIP) Apr 12, 2026
@slbotbm slbotbm marked this pull request as ready for review April 22, 2026 11:19
@slbotbm
Copy link
Copy Markdown
Contributor Author

slbotbm commented Apr 22, 2026

This PR is ready for review

@slbotbm slbotbm changed the title feat(cpp): add functions related to system, tests for purge_* functions, and consumer group functions (WIP) feat(cpp): add functions related to system Apr 25, 2026
Comment thread foreign/cpp/src/client.rs Outdated
Comment thread foreign/cpp/src/client.rs Outdated
Comment thread foreign/cpp/src/lib.rs
Comment thread foreign/cpp/src/lib.rs
Comment thread foreign/cpp/src/lib.rs
Comment thread foreign/cpp/tests/client/low_level_e2e.cpp Outdated
Comment thread foreign/cpp/tests/client/low_level_e2e.cpp
Comment thread foreign/cpp/tests/client/low_level_e2e.cpp
Comment thread foreign/cpp/tests/client/low_level_e2e.cpp Outdated
Comment thread foreign/cpp/build.rs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs.

If you need a review, please ensure CI is green and the PR is rebased on the latest master. Don't hesitate to ping the maintainers - either @core on Discord or by mentioning them directly here on the PR.

Thank you for your contribution!

@github-actions github-actions Bot added the S-stale Inactive issue or pull request label May 8, 2026
@slbotbm slbotbm marked this pull request as draft May 10, 2026 14:39
@slbotbm slbotbm force-pushed the cpp-system-functions branch from c6be262 to 4e2082a Compare May 11, 2026 13:23
@hubcio
Copy link
Copy Markdown
Contributor

hubcio commented May 14, 2026

/ready

@github-actions github-actions Bot added the S-waiting-on-review PR is waiting on a reviewer label May 14, 2026
@slbotbm
Copy link
Copy Markdown
Contributor Author

slbotbm commented May 14, 2026

@hubcio i still need to completely address the review for this pr

maybe /author is better?

@hubcio
Copy link
Copy Markdown
Contributor

hubcio commented May 14, 2026

@slbotbm I know. /ready is me marking the PR ready for review. see CONTRIBUTING.md - i added simple triage bot. this PR was created before the bot, so I'm marking manually all existing PRs.

EDIT: you are right! this should be /author...

@hubcio
Copy link
Copy Markdown
Contributor

hubcio commented May 14, 2026

/author

@github-actions github-actions Bot added S-waiting-on-author PR is waiting on author response and removed S-waiting-on-review PR is waiting on a reviewer labels May 14, 2026
@slbotbm slbotbm marked this pull request as ready for review May 16, 2026 08:01
@slbotbm
Copy link
Copy Markdown
Contributor Author

slbotbm commented May 16, 2026

/ready

@github-actions github-actions Bot added S-waiting-on-review PR is waiting on a reviewer and removed S-waiting-on-author PR is waiting on author response S-stale Inactive issue or pull request labels May 16, 2026
Comment thread foreign/cpp/src/client.rs
RUNTIME.block_on(async { self.inner.heartbeat_interval().await.as_micros() })
}

pub fn snapshot(
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.

empty snapshot_types vec → server loops zero times in core/server/src/shard/system/snapshot/mod.rs:71 and returns an empty zip with Ok(()). silent no-op. duplicate types collide on the {snapshot_type}.txt filename at line 80, so the second entry quietly overwrites the first. reject empty vec at the ffi boundary and dedup before passing to the sdk.

/// Internally, each selected value is passed across the Rust FFI as a string.
/// Values outside the supported set are rejected by the Rust client.
/// Some Rust-side aliases may also be accepted for compatibility.
class SnapshotType final : private detail::StringTag<SnapshotType> {
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.

rust calls this SystemSnapshotType (core/common/src/types/snapshot/mod.rs:36) and c# preserves the prefix in foreign/csharp/Iggy_SDK/Enums/SystemSnapshotType.cs. c++ binding drops System. rename to SystemSnapshotType while pre-release to stop the divergence.

///
/// Internally, this value is passed across the Rust FFI as a string.
/// Values outside the supported set are rejected by the Rust client.
/// Some Rust-side aliases may also be accepted for compatibility.
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.

this "Some Rust-side aliases may also be accepted for compatibility." line is repeated on SnapshotCompression at line 78 and SnapshotType at line 107. only MaxTopicSize::from_str accepts genuine token aliases ("0""server_default"). the other three only do s.to_lowercase() then exact-match (core/common/src/types/compression/compression_algorithm.rs:45-51, core/common/src/types/snapshot/mod.rs:129-141, 171-181). drop the alias claim from the three inaccurate docs, keep on MaxTopicSize only.

@@ -67,14 +67,14 @@ impl TryFrom<ffi::Identifier> for RustIdentifier {
// preserves the C++ ABI used by every test and downstream binding.
#[allow(clippy::wrong_self_convention)]
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.

follow-up on the earlier rename thread: from_stringset_string and from_numericset_numeric landed but the #[allow(clippy::wrong_self_convention)] here is now dead (set_* doesn't trigger that lint) and the comment above about "keeping the names preserves the C++ ABI used by every test and downstream binding" directly contradicts the rename in this same pr. delete both.

Comment thread foreign/cpp/src/lib.rs
memory_usage: u64,
total_memory: u64,
available_memory: u64,
run_time: u64,
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.

run_time and start_time are both bare u64 but carry different semantics - client.rs:107-108 fills them as stats.run_time.as_micros() (IggyDuration, micros since boot) and stats.start_time.as_micros() (IggyTimestamp, unix-epoch micros). consumers cannot tell them apart without reading the rust source. rename to run_time_micros and start_time_epoch_micros, or doc-comment the bridge struct.

Comment thread foreign/cpp/src/client.rs
ffi::ClientInfo {
client_id: client.client_id,
has_user_id,
user_id: client.user_id.unwrap_or(0),
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.

follow-up on the earlier unwrap_or(u32::MAX) thread: switching to unwrap_or(0) here and at line 60 trades one collision for another - root user has id 0 (core/common/src/http/users/defaults.rs:26, applied at core/server/src/streaming/users/user.rs:96), so (has_user_id=true, user_id=0) for a root login is indistinguishable from (has_user_id=false, user_id=0) for an unauthenticated session whenever a consumer reads user_id without first checking the bool. wire encoding already uses u32::MAX as the none sentinel (core/server/src/binary/handlers/system/get_me_handler.rs:64, decoder at core/common/src/wire_conversions.rs:258-261). either doc the has_user_id contract on the bridge structs (lib.rs:123-130, 132-140), or align ffi to the wire sentinel with unwrap_or(u32::MAX).


// TODO(slbotbmR): add a test to create some streams, topics, partitions, and segments, send messages, and create
// consumer groups and verify it.
TEST(LowLevelE2E_Client, GetStatsReturnsServerStats) {
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.

tests/common/test_helpers.hpp:18 already has a TODO(slbotbm): create fixture for setup/teardown covering the broader cleanup story, but this specific test has two extra fragilities not implicit in that todo: (1) fixed stream/topic/group names (cpp-get-stats-stream-1 etc) - any failing ASSERT_NO_THROW before the inline cleanup at lines 266-272 leaks streams and the next run collides on create_stream; (2) clients_count == empty + 2u (line 260) compares deltas against empty_stats taken seconds earlier on a shared server - any other client connecting in between invalidates the assertion. once the fixture lands, randomize names and switch the count assertions to EXPECT_GE so this test stops being order-dependent. add a TODO here if the fix isn't landing in this pr.

EXPECT_FALSE(static_cast<std::string>(empty_stats.os_version).empty());
EXPECT_FALSE(static_cast<std::string>(empty_stats.kernel_version).empty());
EXPECT_FALSE(static_cast<std::string>(empty_stats.iggy_server_version).empty());
EXPECT_TRUE(!empty_stats.has_server_semver || empty_stats.iggy_server_semver > 0u);
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.

!has_server_semver || iggy_server_semver > 0u is unfalsifiable. wire decoder at core/binary_protocol/src/responses/system/get_stats.rs:204 sets Some(raw) iff raw != 0, so has_server_semver=true already implies iggy_server_semver > 0. use EXPECT_EQ(empty_stats.has_server_semver, empty_stats.iggy_server_semver != 0u) or drop the assertion.

Comment thread foreign/cpp/src/client.rs
kernel_version: stats.kernel_version,
iggy_server_version: stats.iggy_server_version,
has_server_semver,
iggy_server_semver: stats.iggy_server_semver.unwrap_or(0),
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 unwrap_or(0) shape as the user_id follow-up. wire decoder at core/binary_protocol/src/responses/system/get_stats.rs:204 forbids Some(0) from a conforming server so the collision is unreachable today, but the pattern is fragile - if anyone ever changes the wire format to allow Some(0), this silently degrades to the same shape as None. doc the invariant on the bridge struct, or align to a sentinel that cannot collide.

Comment thread foreign/cpp/src/client.rs
format!(
"Could not get consumer group '{}' for topic '{}' on stream '{}': {error}",
rust_group_id, rust_topic_id, rust_stream_id
"Could not get consumer group '{rust_group_id}' for topic '{rust_topic_id}' on stream '{rust_stream_id}': {error}"
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.

follow-up on the earlier clippy::uninlined_format_args thread: the sweep landed here and at line 627, but missed two callers - join_consumer_group at lines 656-657 and leave_consumer_group at 741-742 still use the old positional {} style with separate args. unify to named captures.

@github-actions github-actions Bot added S-waiting-on-author PR is waiting on author response and removed S-waiting-on-review PR is waiting on a reviewer labels May 20, 2026
Comment on lines +39 to +48
template <typename Tag>
class StringTag {
protected:
explicit StringTag(std::string value) : value_(std::move(value)) {}

std::string_view value() const { return value_; }

private:
std::string value_;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

StringTag should be marked final and have a destructor to satisfy the C++ ABI.

Comment on lines +83 to +95
static SnapshotCompression stored() { return SnapshotCompression("stored"); }
/// Use standard deflate compression.
static SnapshotCompression deflated() { return SnapshotCompression("deflated"); }
/// Use bzip2 for a higher compression ratio at the cost of slower processing.
static SnapshotCompression bzip2() { return SnapshotCompression("bzip2"); }
/// Use Zstandard for fast compression and decompression.
static SnapshotCompression zstd() { return SnapshotCompression("zstd"); }
/// Use LZMA for high compression, especially for larger files.
static SnapshotCompression lzma() { return SnapshotCompression("lzma"); }
/// Use XZ, which is similar to LZMA and often faster to decompress.
static SnapshotCompression xz() { return SnapshotCompression("xz"); }

std::string_view snapshot_compression_value() const { return value(); }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shouldn't this be in a trait type instead?

Copy link
Copy Markdown

@amlel-el-mahrouss amlel-el-mahrouss left a comment

Choose a reason for hiding this comment

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

Requesting the following changes for:

  • StringType
  • SnapshotCompression

See the comments for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author PR is waiting on author response

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants