1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use serde::{Deserialize, Serialize};
/// The discovery read request (`AGDX_GET_CLIENTS_METADATA`). Filtered and
/// paginated, because a busy server may hold thousands of connections and a
/// caller must not have to pull them all at once. The server orders connections
/// by `client_id`, applies the filters, skips past `after_client_id`, and returns
/// up to `limit` entries plus a cursor when more remain.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientMetadataQuery {
pub v: u32,
/// Only return connections that advertised metadata. The common case for
/// discovery, where unannounced connections are noise.
#[serde(default, skip_serializing_if = "is_false")]
pub with_metadata_only: bool,
/// Only return connections authenticated as this principal.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_id: Option<u32>,
/// Pagination cursor: return only connections whose `client_id` is strictly
/// greater than this. `None` starts from the beginning.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub after_client_id: Option<u32>,
/// Max entries to return. Clamped server-side to the page cap.
pub limit: u32,
}
fn is_false(value: &bool) -> bool {
!*value
}
/// One connection's discovery record: the connection identity the streaming
/// server holds plus the opaque metadata the client advertised. A LaserData-owned
/// type, deliberately distinct from the upstream Apache Iggy `ClientInfo` (which
/// stays byte-identical so an Apache Iggy SDK keeps working against LaserData
/// Cloud). The metadata is opaque: an agent advertises its card, a regular app
/// sets any blob the consumer interprets.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientMetadata {
pub client_id: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub user_id: Option<u32>,
/// Transport code (1 Tcp, 2 Quic, 3 Http, 4 WebSocket), the same dictionary
/// the upstream binding uses.
pub transport: u8,
pub address: String,
pub consumer_groups_count: u32,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "crate::encoding::opt_bin_bytes"
)]
pub metadata: Option<Vec<u8>>,
}
/// The reply to `AGDX_GET_CLIENTS_METADATA`: one page of connections with their
/// advertised metadata, plus `next_cursor` (the last `client_id` in the page) when
/// more connections remain, so the caller pages by passing it as the next
/// `after_client_id`. `None` means the last page.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientMetadataList {
pub clients: Vec<ClientMetadata>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<u32>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProducerPresence {
pub producer_presence_version: u32,
pub observed_at_millis: u64,
pub expires_after_millis: u64,
pub producers: Vec<ProducerStatistics>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProducerStatistics {
pub instance_id: String,
pub stream: String,
pub topic: String,
pub first_activity_millis: u64,
pub last_activity_millis: u64,
pub submitted_records: u64,
pub submitted_payload_bytes: u64,
pub confirmed_records: Option<u64>,
pub confirmed_payload_bytes: Option<u64>,
pub retries: Option<u64>,
pub failed_calls: u64,
pub last_success_millis: Option<u64>,
pub latency: ProducerLatency,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProducerLatency {
pub samples: u64,
pub p50_micros: Option<u64>,
pub p99_micros: Option<u64>,
pub p999_micros: Option<u64>,
}