From c176d5fac2f98205228142040e7778e0fff20967 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 9 Jul 2020 10:54:26 -0700 Subject: [PATCH] quic: set destroyed at timestamps for duration calculation PR-URL: https://github.com/nodejs/node/pull/34262 Reviewed-By: Anna Henningsen --- lib/internal/quic/core.js | 41 ++++++++++++++++++++++-------------- src/quic/node_quic_session.h | 1 + src/quic/node_quic_socket.h | 1 + src/quic/node_quic_stream.h | 1 + 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/internal/quic/core.js b/lib/internal/quic/core.js index 6f48ea3a6509d5..e46e2763241914 100644 --- a/lib/internal/quic/core.js +++ b/lib/internal/quic/core.js @@ -126,6 +126,7 @@ const { AF_INET6, NGTCP2_DEFAULT_MAX_PKTLEN, IDX_QUIC_SESSION_STATS_CREATED_AT, + IDX_QUIC_SESSION_STATS_DESTROYED_AT, IDX_QUIC_SESSION_STATS_HANDSHAKE_START_AT, IDX_QUIC_SESSION_STATS_BYTES_RECEIVED, IDX_QUIC_SESSION_STATS_BYTES_SENT, @@ -143,6 +144,7 @@ const { IDX_QUIC_SESSION_STATS_SMOOTHED_RTT, IDX_QUIC_SESSION_STATS_LATEST_RTT, IDX_QUIC_STREAM_STATS_CREATED_AT, + IDX_QUIC_STREAM_STATS_DESTROYED_AT, IDX_QUIC_STREAM_STATS_BYTES_RECEIVED, IDX_QUIC_STREAM_STATS_BYTES_SENT, IDX_QUIC_STREAM_STATS_MAX_OFFSET, @@ -150,6 +152,7 @@ const { IDX_QUIC_STREAM_STATS_MAX_OFFSET_ACK, IDX_QUIC_STREAM_STATS_MAX_OFFSET_RECV, IDX_QUIC_SOCKET_STATS_CREATED_AT, + IDX_QUIC_SOCKET_STATS_DESTROYED_AT, IDX_QUIC_SOCKET_STATS_BOUND_AT, IDX_QUIC_SOCKET_STATS_LISTEN_AT, IDX_QUIC_SOCKET_STATS_BYTES_RECEIVED, @@ -1433,6 +1436,9 @@ class QuicSocket extends EventEmitter { // Mark the QuicSocket as being destroyed. state.state = kSocketDestroyed; + this[kHandle].stats[IDX_QUIC_SOCKET_STATS_DESTROYED_AT] = + process.hrtime.bigint(); + state.stats = new BigInt64Array(this[kHandle].stats); // Immediately close any sessions that may be remaining. // If the udp socket is in a state where it is able to do so, @@ -1531,24 +1537,21 @@ class QuicSocket extends EventEmitter { } get duration() { - // TODO(@jasnell): If the object is destroyed, it should - // use a fixed duration rather than calculating from now - return Number(process.hrtime.bigint() - - getStats(this, IDX_QUIC_SOCKET_STATS_CREATED_AT)); + const end = getStats(this, IDX_QUIC_SOCKET_STATS_DESTROYED_AT) || + process.hrtime.bigint(); + return Number(end - getStats(this, IDX_QUIC_SOCKET_STATS_CREATED_AT)); } get boundDuration() { - // TODO(@jasnell): If the object is destroyed, it should - // use a fixed duration rather than calculating from now - return Number(process.hrtime.bigint() - - getStats(this, IDX_QUIC_SOCKET_STATS_BOUND_AT)); + const end = getStats(this, IDX_QUIC_SOCKET_STATS_DESTROYED_AT) || + process.hrtime.bigint(); + return Number(end - getStats(this, IDX_QUIC_SOCKET_STATS_BOUND_AT)); } get listenDuration() { - // TODO(@jasnell): If the object is destroyed, it should - // use a fixed duration rather than calculating from now - return Number(process.hrtime.bigint() - - getStats(this, IDX_QUIC_SOCKET_STATS_LISTEN_AT)); + const end = getStats(this, IDX_QUIC_SOCKET_STATS_DESTROYED_AT) || + process.hrtime.bigint(); + return Number(end - getStats(this, IDX_QUIC_SOCKET_STATS_LISTEN_AT)); } get bytesReceived() { @@ -1920,6 +1923,8 @@ class QuicSession extends EventEmitter { this[kHandle] = undefined; if (handle !== undefined) { // Copy the stats for use after destruction + handle.stats[IDX_QUIC_SESSION_STATS_DESTROYED_AT] = + process.hrtime.bigint(); state.stats = new BigInt64Array(handle.stats); state.idleTimeout = this[kInternalState].state.idleTimeout; @@ -2148,8 +2153,9 @@ class QuicSession extends EventEmitter { } get duration() { - return Number(process.hrtime.bigint() - - getStats(this, IDX_QUIC_SESSION_STATS_CREATED_AT)); + const end = getStats(this, IDX_QUIC_SESSION_STATS_DESTROYED_AT) || + process.hrtime.bigint(); + return Number(end - getStats(this, IDX_QUIC_SESSION_STATS_CREATED_AT)); } get handshakeDuration() { @@ -2972,6 +2978,8 @@ class QuicStream extends Duplex { // object has been destroyed. Any attempt to use the object // will segfault and crash the process. if (handle !== undefined) { + handle.stats[IDX_QUIC_STREAM_STATS_DESTROYED_AT] = + process.hrtime.bigint(); state.stats = new BigInt64Array(handle.stats); handle.destroy(); } @@ -3139,8 +3147,9 @@ class QuicStream extends Duplex { } get duration() { - return Number(process.hrtime.bigint() - - getStats(this, IDX_QUIC_STREAM_STATS_CREATED_AT)); + const end = getStats(this, IDX_QUIC_STREAM_STATS_DESTROYED_AT) || + process.hrtime.bigint(); + return Number(end - getStats(this, IDX_QUIC_STREAM_STATS_CREATED_AT)); } get bytesReceived() { diff --git a/src/quic/node_quic_session.h b/src/quic/node_quic_session.h index daa189d40d291c..ae5ec0754b8249 100644 --- a/src/quic/node_quic_session.h +++ b/src/quic/node_quic_session.h @@ -182,6 +182,7 @@ enum QuicSessionStateFields { V(SENT_AT, sent_at, "Last Sent At") \ V(RECEIVED_AT, received_at, "Last Received At") \ V(CLOSING_AT, closing_at, "Closing") \ + V(DESTROYED_AT, destroyed_at, "Destroyed At") \ V(BYTES_RECEIVED, bytes_received, "Bytes Received") \ V(BYTES_SENT, bytes_sent, "Bytes Sent") \ V(BIDI_STREAM_COUNT, bidi_stream_count, "Bidi Stream Count") \ diff --git a/src/quic/node_quic_socket.h b/src/quic/node_quic_socket.h index 41092c344c8f16..f108eb47901b81 100644 --- a/src/quic/node_quic_socket.h +++ b/src/quic/node_quic_socket.h @@ -71,6 +71,7 @@ enum QuicSocketStateFields { V(CREATED_AT, created_at, "Created At") \ V(BOUND_AT, bound_at, "Bound At") \ V(LISTEN_AT, listen_at, "Listen At") \ + V(DESTROYED_AT, destroyed_at, "Destroyed At") \ V(BYTES_RECEIVED, bytes_received, "Bytes Received") \ V(BYTES_SENT, bytes_sent, "Bytes Sent") \ V(PACKETS_RECEIVED, packets_received, "Packets Received") \ diff --git a/src/quic/node_quic_stream.h b/src/quic/node_quic_stream.h index 53a8cdaea52d51..96727d8661b1ba 100644 --- a/src/quic/node_quic_stream.h +++ b/src/quic/node_quic_stream.h @@ -50,6 +50,7 @@ enum QuicStreamHeadersKind : int { V(RECEIVED_AT, received_at, "Last Received At") \ V(ACKED_AT, acked_at, "Last Acknowledged At") \ V(CLOSING_AT, closing_at, "Closing At") \ + V(DESTROYED_AT, destroyed_at, "Destroyed At") \ V(BYTES_RECEIVED, bytes_received, "Bytes Received") \ V(BYTES_SENT, bytes_sent, "Bytes Sent") \ V(MAX_OFFSET, max_offset, "Max Offset") \