Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
blob_transport_stats.hpp
Go to the documentation of this file.
1/* Flow-IPC: Core
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
22#include <flow/util/stat/histo.hpp>
23#include <flow/util/stat/stat_set.hpp>
24#include <cstdint>
25#include <string>
26
28{
29
30// Types.
31
32/**
33 * Cumulative stats from the outgoing-direction (send) pipe of a Blob_sender or Native_handle_sender
34 * concept implementation. Applicable to any such implementation; also counts native-handle sends if applicable.
35 *
36 * @note While internally a payload-to-be-sent may have to be queued on would-block from the low-level transport
37 * (e.g., kernel send buffer full in `Native_socket_stream`), counters like #m_total_msgs and #m_total_bytes
38 * and #m_msgs_with_hndls count the full payload ASAP without waiting for all of it to be "really sent."
39 * Meanwhile #m_would_block_count and #m_snd_q_hi_wmark can give a sense of how often the internal queuing
40 * had to be invoked.
41 */
43{
44 // Constants.
45
46 /// Payload-size histogram bucket width (bytes). The last bucket isolates the max payload size.
47 static constexpr size_t S_PAYLOAD_SZ_HISTO_BUCKET_SZ = 1024;
48
49 // Data.
50
51 /// Total user messages successfully passed to the low-level send path via `send_*()`.
52 uint64_t m_total_msgs = 0;
53
54 /// Total user blob bytes sent (sum of blob sizes from `send_*()`).
55 uint64_t m_total_bytes = 0;
56
57 /// Total low-level bytes sent (user blob bytes plus protocol headers and framing).
59
60 /// Number of messages sent that carried at least one native handle. Currently at most 1 handle per message.
61 uint64_t m_msgs_with_hndls = 0;
62
63 /// Number of times a would-block condition required payload queueing (low-level transport's internal buffer full).
64 uint64_t m_would_block_count = 0;
65
66 /// Number of auto-pings sent (initial from `auto_ping()` plus periodic timer-fired pings).
67 uint64_t m_auto_pings = 0;
68
69 /// Current depth of the pending-payloads send queue (queue added-to when would-block occurs).
70 size_t m_snd_q_depth = 0;
71
72 /// Max of #m_snd_q_depth observed so far.
73 size_t m_snd_q_hi_wmark = 0;
74
75 /**
76 * Payload-size histogram for sent user messages. Maxed-out size gets its own bucket.
77 *
78 * @todo Consider replacing #m_histo_payload_sz's uniform low end with log-scale buckets (64, 128, ...,
79 * 1Ki), if field experience keeps wanting better resolution among small messages: bucket 0 currently
80 * swallows all sub-1Ki traffic. (The latter includes ~all outer messages of SHM-backed *structured* channels;
81 * conceivably it would be nice to capture those, for applications that use that feature; which to be clear
82 * means (1) using struc::Channel or struc::sync_io::Channel in ther first place; and given that also (2) using
83 * the SHM-backed variety as opposed to merely heap-backed.)
84 */
85 flow::util::stat::Histogram_counter m_histo_payload_sz;
86
87 // Constructors.
88
89 /**
90 * Constructs stats with all counters zeroed and a payload-size histogram sized for the given max payload.
91 * The last bucket isolates exactly `max_payload_size`. If `max_payload_size` is not divisible by
92 * #S_PAYLOAD_SZ_HISTO_BUCKET_SZ, bucket 0 absorbs the remainder so that subsequent bucket boundaries
93 * align and one falls exactly on `max_payload_size`.
94 *
95 * @param max_payload_size
96 * Maximum blob payload size for this transport (e.g., `Native_socket_stream_cfg::S_MAX_META_BLOB_LENGTH`).
97 * Must be >= 1.
98 */
99 explicit Blob_snd_stats(size_t max_payload_size);
100}; // struct Blob_snd_stats
101
102// Template implementations.
103
104template<typename Visitor>
105void declare_stats(const flow::util::stat::Stat_name& name_prefix,
106 const Blob_snd_stats* src_stats, Blob_snd_stats* target_stats,
107 Visitor&& visitor)
108{
109 FLOW_UTIL_STAT_DECLARE(m_total_msgs, ACCUMULATOR);
110 FLOW_UTIL_STAT_DECLARE(m_total_bytes, ACCUMULATOR);
111 FLOW_UTIL_STAT_DECLARE(m_total_low_lvl_bytes, ACCUMULATOR);
112 FLOW_UTIL_STAT_DECLARE(m_msgs_with_hndls, ACCUMULATOR);
113 FLOW_UTIL_STAT_DECLARE(m_would_block_count, ACCUMULATOR);
114 FLOW_UTIL_STAT_DECLARE(m_auto_pings, ACCUMULATOR);
115 FLOW_UTIL_STAT_DECLARE(m_snd_q_depth, GAUGE);
116 FLOW_UTIL_STAT_DECLARE_HI_WMARK(m_snd_q_hi_wmark, m_snd_q_depth);
117 FLOW_UTIL_STAT_DECLARE(m_histo_payload_sz, ACCUMULATOR);
118}
119
120template<typename Stats_t>
122{
123 return const_cast<Blob_snd_stats&>(blob_snd_stats(static_cast<const Stats_t&>(stats)));
124}
125
126// Types.
127
128/**
129 * Cumulative stats from the incoming-direction (receive) pipe of a Blob_receiver or Native_handle_receiver
130 * concept implementation. Applicable to any such implementation; also counts native-handle receives if applicable.
131 */
133{
134 // Constants.
135
136 /// Payload-size histogram bucket width (bytes). The last bucket isolates the max payload size.
137 static constexpr size_t S_PAYLOAD_SZ_HISTO_BUCKET_SZ = 1024;
138
139 // Data.
140
141 /// Total user messages fully received and delivered.
142 uint64_t m_total_msgs = 0;
143
144 /// Total user blob bytes received (sum of in-message blob sizes).
145 uint64_t m_total_bytes = 0;
146
147 /// Total low-level bytes received (user blob bytes plus protocol headers and framing).
149
150 /// Number of messages received that carried at least one native handle. Currently at most 1 handle per message.
151 uint64_t m_msgs_with_hndls = 0;
152
153 /// Number of auto-pings received from the opposing sender.
154 uint64_t m_auto_pings = 0;
155
156 /// Number of idle-timeout events. For a {Blob|Native}_handle_receiver as of this writing this cannot exceed 1.
157 uint64_t m_idle_timeouts = 0;
158
159 /**
160 * Payload-size histogram for received user messages. Maxed-out size gets its own bucket.
161 * The to-do on Blob_snd_stats::m_histo_payload_sz applies equally here.
162 */
163 flow::util::stat::Histogram_counter m_histo_payload_sz;
164
165 // Constructors.
166
167 /**
168 * Constructs stats with all counters zeroed and a payload-size histogram sized for the given max payload.
169 * The last bucket isolates exactly `max_payload_size`. If `max_payload_size` is not divisible by
170 * #S_PAYLOAD_SZ_HISTO_BUCKET_SZ, bucket 0 absorbs the remainder so that subsequent bucket boundaries
171 * align and one falls exactly on `max_payload_size`.
172 *
173 * @param max_payload_size
174 * Maximum blob payload size for this transport (e.g., `Native_socket_stream_cfg::S_MAX_META_BLOB_LENGTH`).
175 * Must be >= 1.
176 */
177 explicit Blob_rcv_stats(size_t max_payload_size);
178}; // struct Blob_rcv_stats
179
180// Template implementations.
181
182template<typename Visitor>
183void declare_stats(const flow::util::stat::Stat_name& name_prefix,
184 const Blob_rcv_stats* src_stats, Blob_rcv_stats* target_stats,
185 Visitor&& visitor)
186{
187 FLOW_UTIL_STAT_DECLARE(m_total_msgs, ACCUMULATOR);
188 FLOW_UTIL_STAT_DECLARE(m_total_bytes, ACCUMULATOR);
189 FLOW_UTIL_STAT_DECLARE(m_total_low_lvl_bytes, ACCUMULATOR);
190 FLOW_UTIL_STAT_DECLARE(m_msgs_with_hndls, ACCUMULATOR);
191 FLOW_UTIL_STAT_DECLARE(m_auto_pings, ACCUMULATOR);
192 FLOW_UTIL_STAT_DECLARE(m_idle_timeouts, ACCUMULATOR);
193 FLOW_UTIL_STAT_DECLARE(m_histo_payload_sz, ACCUMULATOR);
194}
195
196template<typename Stats_t>
198{
199 return const_cast<Blob_rcv_stats&>(blob_rcv_stats(static_cast<const Stats_t&>(stats)));
200}
201
202} // namespace ipc::transport::stat
Stats-related sub-namespace, for ADL segregation and general organization.
const Blob_rcv_stats & blob_rcv_stats(const Blob_rcv_stats &stats)
Maps a stats struct type to its core Blob_rcv_stats; identity for Blob_rcv_stats itself.
void declare_stats(const flow::util::stat::Stat_name &name_prefix, const Blob_snd_stats *src_stats, Blob_snd_stats *target_stats, Visitor &&visitor)
Declares the stats for Blob_snd_stats.
Blob_snd_stats & blob_snd_stats_mutable(Stats_t &stats)
Non-const wrapper around blob_snd_stats().
const Blob_snd_stats & blob_snd_stats(const Blob_snd_stats &stats)
Maps a stats struct type to its core Blob_snd_stats; identity for Blob_snd_stats itself.
Blob_rcv_stats & blob_rcv_stats_mutable(Stats_t &stats)
Non-const wrapper around blob_rcv_stats().
Cumulative stats from the incoming-direction (receive) pipe of a Blob_receiver or Native_handle_recei...
uint64_t m_total_bytes
Total user blob bytes received (sum of in-message blob sizes).
static constexpr size_t S_PAYLOAD_SZ_HISTO_BUCKET_SZ
Payload-size histogram bucket width (bytes). The last bucket isolates the max payload size.
uint64_t m_total_msgs
Total user messages fully received and delivered.
uint64_t m_idle_timeouts
Number of idle-timeout events. For a {Blob|Native}_handle_receiver as of this writing this cannot exc...
uint64_t m_total_low_lvl_bytes
Total low-level bytes received (user blob bytes plus protocol headers and framing).
Blob_rcv_stats(size_t max_payload_size)
Constructs stats with all counters zeroed and a payload-size histogram sized for the given max payloa...
uint64_t m_msgs_with_hndls
Number of messages received that carried at least one native handle. Currently at most 1 handle per m...
uint64_t m_auto_pings
Number of auto-pings received from the opposing sender.
flow::util::stat::Histogram_counter m_histo_payload_sz
Payload-size histogram for received user messages.
Cumulative stats from the outgoing-direction (send) pipe of a Blob_sender or Native_handle_sender con...
static constexpr size_t S_PAYLOAD_SZ_HISTO_BUCKET_SZ
Payload-size histogram bucket width (bytes). The last bucket isolates the max payload size.
uint64_t m_auto_pings
Number of auto-pings sent (initial from auto_ping() plus periodic timer-fired pings).
flow::util::stat::Histogram_counter m_histo_payload_sz
Payload-size histogram for sent user messages.
uint64_t m_msgs_with_hndls
Number of messages sent that carried at least one native handle. Currently at most 1 handle per messa...
uint64_t m_total_bytes
Total user blob bytes sent (sum of blob sizes from send_*()).
size_t m_snd_q_depth
Current depth of the pending-payloads send queue (queue added-to when would-block occurs).
uint64_t m_total_low_lvl_bytes
Total low-level bytes sent (user blob bytes plus protocol headers and framing).
uint64_t m_total_msgs
Total user messages successfully passed to the low-level send path via send_*().
uint64_t m_would_block_count
Number of times a would-block condition required payload queueing (low-level transport's internal buf...
Blob_snd_stats(size_t max_payload_size)
Constructs stats with all counters zeroed and a payload-size histogram sized for the given max payloa...
size_t m_snd_q_hi_wmark
Max of m_snd_q_depth observed so far.