Skip to content
This repository was archived by the owner on Aug 11, 2020. It is now read-only.

Commit 57af916

Browse files
committed
quic: additional session stats
1 parent 7d5277f commit 57af916

File tree

4 files changed

+120
-11
lines changed

4 files changed

+120
-11
lines changed

lib/internal/quic/core.js

+37-9
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ const {
139139
IDX_QUIC_SESSION_STATE_KEYLOG_ENABLED,
140140
IDX_QUIC_SESSION_STATE_MAX_STREAMS_BIDI,
141141
IDX_QUIC_SESSION_STATE_MAX_STREAMS_UNI,
142+
IDX_QUIC_SESSION_STATE_MAX_DATA_LEFT,
143+
IDX_QUIC_SESSION_STATE_BYTES_IN_FLIGHT,
144+
IDX_QUIC_SESSION_STATS_CREATED_AT,
145+
IDX_QUIC_SESSION_STATS_HANDSHAKE_START_AT,
146+
IDX_QUIC_SESSION_STATS_BYTES_RECEIVED,
147+
IDX_QUIC_SESSION_STATS_BYTES_SENT,
148+
IDX_QUIC_SESSION_STATS_BIDI_STREAM_COUNT,
149+
IDX_QUIC_SESSION_STATS_UNI_STREAM_COUNT,
150+
IDX_QUIC_SESSION_STATS_STREAMS_IN_COUNT,
151+
IDX_QUIC_SESSION_STATS_STREAMS_OUT_COUNT,
152+
IDX_QUIC_SESSION_STATS_KEYUPDATE_COUNT,
153+
IDX_QUIC_SESSION_STATS_MAX_BYTES_IN_FLIGHT,
142154
ERR_INVALID_REMOTE_TRANSPORT_PARAMS,
143155
ERR_INVALID_TLS_SESSION_TICKET,
144156
NGTCP2_PATH_VALIDATION_RESULT_FAILURE,
@@ -1678,6 +1690,16 @@ class QuicSession extends EventEmitter {
16781690
return this.#socket ? this.#socket.address : {};
16791691
}
16801692

1693+
get maxDataLeft() {
1694+
return this[kHandle] ?
1695+
this[kHandle].state[IDX_QUIC_SESSION_STATE_MAX_DATA_LEFT] : 0;
1696+
}
1697+
1698+
get bytesInFlight() {
1699+
return this[kHandle] ?
1700+
this[kHandle].state[IDX_QUIC_SESSION_STATE_BYTES_IN_FLIGHT] : 0;
1701+
}
1702+
16811703
get authenticated() {
16821704
// Specifically check for null. Undefined means the check has not
16831705
// been performed yet, another other value other than null means
@@ -1753,6 +1775,7 @@ class QuicSession extends EventEmitter {
17531775
};
17541776
}
17551777

1778+
17561779
get socket() {
17571780
return this.#socket;
17581781
}
@@ -1805,50 +1828,55 @@ class QuicSession extends EventEmitter {
18051828
get duration() {
18061829
const now = process.hrtime.bigint();
18071830
const stats = this.#stats || this[kHandle].stats;
1808-
return now - stats[0];
1831+
return now - stats[IDX_QUIC_SESSION_STATS_CREATED_AT];
18091832
}
18101833

18111834
get handshakeDuration() {
18121835
const stats = this.#stats || this[kHandle].stats;
18131836
const end =
18141837
this.handshakeComplete ?
18151838
stats[4] : process.hrtime.bigint();
1816-
return end - stats[1];
1839+
return end - stats[IDX_QUIC_SESSION_STATS_HANDSHAKE_START_AT];
18171840
}
18181841

18191842
get bytesReceived() {
18201843
const stats = this.#stats || this[kHandle].stats;
1821-
return stats[8];
1844+
return stats[IDX_QUIC_SESSION_STATS_BYTES_RECEIVED];
18221845
}
18231846

18241847
get bytesSent() {
18251848
const stats = this.#stats || this[kHandle].stats;
1826-
return stats[9];
1849+
return stats[IDX_QUIC_SESSION_STATS_BYTES_SENT];
18271850
}
18281851

18291852
get bidiStreamCount() {
18301853
const stats = this.#stats || this[kHandle].stats;
1831-
return stats[10];
1854+
return stats[IDX_QUIC_SESSION_STATS_BIDI_STREAM_COUNT];
18321855
}
18331856

18341857
get uniStreamCount() {
18351858
const stats = this.#stats || this[kHandle].stats;
1836-
return stats[11];
1859+
return stats[IDX_QUIC_SESSION_STATS_UNI_STREAM_COUNT];
1860+
}
1861+
1862+
get maxInFlightBytes() {
1863+
const stats = this.#stats || this[kHandle].stats;
1864+
return stats[IDX_QUIC_SESSION_STATS_MAX_BYTES_IN_FLIGHT];
18371865
}
18381866

18391867
get peerInitiatedStreamCount() {
18401868
const stats = this.#stats || this[kHandle].stats;
1841-
return stats[12];
1869+
return stats[IDX_QUIC_SESSION_STATS_STREAMS_IN_COUNT];
18421870
}
18431871

18441872
get selfInitiatedStreamCount() {
18451873
const stats = this.#stats || this[kHandle].stats;
1846-
return stats[13];
1874+
return stats[IDX_QUIC_SESSION_STATS_STREAMS_OUT_COUNT];
18471875
}
18481876

18491877
get keyUpdateCount() {
18501878
const stats = this.#stats || this[kHandle].stats;
1851-
return stats[14];
1879+
return stats[IDX_QUIC_SESSION_STATS_KEYUPDATE_COUNT];
18521880
}
18531881

18541882
get minRTT() {

src/node_quic.cc

+29
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ void Initialize(Local<Object> target,
146146
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATE_KEYLOG_ENABLED);
147147
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATE_MAX_STREAMS_BIDI);
148148
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATE_MAX_STREAMS_UNI);
149+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATE_MAX_DATA_LEFT);
150+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATE_BYTES_IN_FLIGHT);
149151
NODE_DEFINE_CONSTANT(constants, MAX_RETRYTOKEN_EXPIRATION);
150152
NODE_DEFINE_CONSTANT(constants, MIN_RETRYTOKEN_EXPIRATION);
151153
NODE_DEFINE_CONSTANT(constants, NGTCP2_MAX_CIDLEN);
@@ -183,6 +185,33 @@ void Initialize(Local<Object> target,
183185
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_MAX_CRYPTO_BUFFER);
184186
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_CONFIG_COUNT);
185187

188+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_CREATED_AT);
189+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_HANDSHAKE_START_AT);
190+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_HANDSHAKE_SEND_AT);
191+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_HANDSHAKE_CONTINUE_AT);
192+
NODE_DEFINE_CONSTANT(constants,
193+
IDX_QUIC_SESSION_STATS_HANDSHAKE_COMPLETED_AT);
194+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_HANDSHAKE_ACKED_AT);
195+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_SENT_AT);
196+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_RECEIVED_AT);
197+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_CLOSING_AT);
198+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_BYTES_RECEIVED);
199+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_BYTES_SENT);
200+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_BIDI_STREAM_COUNT);
201+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_UNI_STREAM_COUNT);
202+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_STREAMS_IN_COUNT);
203+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_STREAMS_OUT_COUNT);
204+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_KEYUPDATE_COUNT);
205+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_RETRY_COUNT);
206+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_LOSS_RETRANSMIT_COUNT);
207+
NODE_DEFINE_CONSTANT(constants,
208+
IDX_QUIC_SESSION_STATS_ACK_DELAY_RETRANSMIT_COUNT);
209+
NODE_DEFINE_CONSTANT(constants,
210+
IDX_QUIC_SESSION_STATS_PATH_VALIDATION_SUCCESS_COUNT);
211+
NODE_DEFINE_CONSTANT(constants,
212+
IDX_QUIC_SESSION_STATS_PATH_VALIDATION_FAILURE_COUNT);
213+
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_MAX_BYTES_IN_FLIGHT);
214+
186215
NODE_DEFINE_CONSTANT(constants, IDX_HTTP3_QPACK_MAX_TABLE_CAPACITY);
187216
NODE_DEFINE_CONSTANT(constants, IDX_HTTP3_QPACK_BLOCKED_STREAMS);
188217
NODE_DEFINE_CONSTANT(constants, IDX_HTTP3_MAX_HEADER_LIST_SIZE);

src/node_quic_session.cc

+20-2
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,8 @@ QuicSession::~QuicSession() {
13021302
" Streams Out Count: %" PRIu64 "\n"
13031303
" Remaining sendbuf_: %" PRIu64 "\n"
13041304
" Remaining handshake_: %" PRIu64 "\n"
1305-
" Remaining txbuf_: %" PRIu64 "\n",
1305+
" Remaining txbuf_: %" PRIu64 "\n"
1306+
" Max In Flight Bytes: %" PRIu64 "\n",
13061307
uv_hrtime() - session_stats_.created_at,
13071308
session_stats_.handshake_start_at,
13081309
session_stats_.handshake_completed_at,
@@ -1314,7 +1315,8 @@ QuicSession::~QuicSession() {
13141315
session_stats_.streams_out_count,
13151316
sendbuf_length,
13161317
handshake_length,
1317-
txbuf_length);
1318+
txbuf_length,
1319+
session_stats_.max_bytes_in_flight);
13181320

13191321
connection_.reset();
13201322

@@ -1824,6 +1826,9 @@ bool QuicSession::Receive(
18241826
// and HandleScope are both exited before continuing on with the
18251827
// function. This allows any nextTicks and queued tasks to be processed
18261828
// before we continue.
1829+
OnScopeLeave update_stats([&](){
1830+
UpdateDataStats();
1831+
});
18271832
Debug(this, "Processing received packet");
18281833
HandleScope handle_scope(env()->isolate());
18291834
InternalCallbackScope callback_scope(this);
@@ -2558,6 +2563,7 @@ bool QuicSession::WritePackets(const char* diagnostic_label) {
25582563
data.Realloc(nwrite);
25592564
remote_address_.Update(path.path.remote.addr, path.path.remote.addrlen);
25602565
sendbuf_.Push(std::move(data));
2566+
UpdateDataStats();
25612567
if (!SendPacket(diagnostic_label))
25622568
return false;
25632569
}
@@ -2711,6 +2717,7 @@ void QuicSession::InitServer(
27112717
connection_.reset(conn);
27122718

27132719
InitializeTLS(this);
2720+
UpdateDataStats();
27142721
UpdateIdleTimer();
27152722
}
27162723

@@ -2745,6 +2752,16 @@ void QuicSession::UpdateRecoveryStats() {
27452752
recovery_stats_.smoothed_rtt = static_cast<double>(stat->smoothed_rtt);
27462753
}
27472754

2755+
void QuicSession::UpdateDataStats() {
2756+
state_[IDX_QUIC_SESSION_STATE_MAX_DATA_LEFT] =
2757+
static_cast<double>(ngtcp2_conn_get_max_data_left(Connection()));
2758+
size_t bytes_in_flight = ngtcp2_conn_get_bytes_in_flight(Connection());
2759+
state_[IDX_QUIC_SESSION_STATE_BYTES_IN_FLIGHT] =
2760+
static_cast<double>(bytes_in_flight);
2761+
if (bytes_in_flight > session_stats_.max_bytes_in_flight)
2762+
session_stats_.max_bytes_in_flight = bytes_in_flight;
2763+
}
2764+
27482765
BaseObjectPtr<QuicSession> QuicSession::CreateClient(
27492766
QuicSocket* socket,
27502767
const struct sockaddr* addr,
@@ -2860,6 +2877,7 @@ bool QuicSession::InitClient(
28602877
}
28612878

28622879
UpdateIdleTimer();
2880+
UpdateDataStats();
28632881
return true;
28642882
}
28652883

src/node_quic_session.h

+34
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,42 @@ enum QuicSessionState : int {
162162
IDX_QUIC_SESSION_STATE_MAX_STREAMS_BIDI,
163163
IDX_QUIC_SESSION_STATE_MAX_STREAMS_UNI,
164164

165+
// Communicates the current maxinum number of bytes that
166+
// the local endpoint can send in this connection
167+
// (updated immediately after processing sent/received packets)
168+
IDX_QUIC_SESSION_STATE_MAX_DATA_LEFT,
169+
170+
// Communicates the current total number of bytes in flight
171+
IDX_QUIC_SESSION_STATE_BYTES_IN_FLIGHT,
172+
165173
// Just the number of session state enums for use when
166174
// creating the AliasedBuffer.
167175
IDX_QUIC_SESSION_STATE_COUNT
168176
};
169177

178+
enum QuicSessionStatsIdx : int {
179+
IDX_QUIC_SESSION_STATS_CREATED_AT,
180+
IDX_QUIC_SESSION_STATS_HANDSHAKE_START_AT,
181+
IDX_QUIC_SESSION_STATS_HANDSHAKE_SEND_AT,
182+
IDX_QUIC_SESSION_STATS_HANDSHAKE_CONTINUE_AT,
183+
IDX_QUIC_SESSION_STATS_HANDSHAKE_COMPLETED_AT,
184+
IDX_QUIC_SESSION_STATS_HANDSHAKE_ACKED_AT,
185+
IDX_QUIC_SESSION_STATS_SENT_AT,
186+
IDX_QUIC_SESSION_STATS_RECEIVED_AT,
187+
IDX_QUIC_SESSION_STATS_CLOSING_AT,
188+
IDX_QUIC_SESSION_STATS_BYTES_RECEIVED,
189+
IDX_QUIC_SESSION_STATS_BYTES_SENT,
190+
IDX_QUIC_SESSION_STATS_BIDI_STREAM_COUNT,
191+
IDX_QUIC_SESSION_STATS_UNI_STREAM_COUNT,
192+
IDX_QUIC_SESSION_STATS_STREAMS_IN_COUNT,
193+
IDX_QUIC_SESSION_STATS_STREAMS_OUT_COUNT,
194+
IDX_QUIC_SESSION_STATS_KEYUPDATE_COUNT,
195+
IDX_QUIC_SESSION_STATS_RETRY_COUNT,
196+
IDX_QUIC_SESSION_STATS_LOSS_RETRANSMIT_COUNT,
197+
IDX_QUIC_SESSION_STATS_ACK_DELAY_RETRANSMIT_COUNT,
198+
IDX_QUIC_SESSION_STATS_PATH_VALIDATION_SUCCESS_COUNT,IDX_QUIC_SESSION_STATS_PATH_VALIDATION_FAILURE_COUNT,IDX_QUIC_SESSION_STATS_MAX_BYTES_IN_FLIGHT
199+
};
200+
170201
class QuicSessionListener {
171202
public:
172203
virtual ~QuicSessionListener();
@@ -948,6 +979,7 @@ class QuicSession : public AsyncWrap,
948979
uint64_t app_error_code);
949980
bool WritePackets(const char* diagnostic_label = nullptr);
950981
void UpdateRecoveryStats();
982+
void UpdateDataStats();
951983

952984
void VersionNegotiation(
953985
const ngtcp2_pkt_hd* hd,
@@ -1296,6 +1328,8 @@ class QuicSession : public AsyncWrap,
12961328
uint64_t path_validation_success_count;
12971329
// The total number of failed path validations
12981330
uint64_t path_validation_failure_count;
1331+
// The max number of in flight bytes recorded
1332+
uint64_t max_bytes_in_flight;
12991333
};
13001334
session_stats session_stats_{};
13011335

0 commit comments

Comments
 (0)