5
5
6
6
#include <aws/http/private/h2_stream.h>
7
7
8
+ #include <aws/common/clock.h>
8
9
#include <aws/http/private/h2_connection.h>
9
10
#include <aws/http/private/strutil.h>
10
11
#include <aws/http/status_code.h>
@@ -240,10 +241,17 @@ struct aws_h2_stream *aws_h2_stream_new_request(
240
241
stream -> base .on_incoming_headers = options -> on_response_headers ;
241
242
stream -> base .on_incoming_header_block_done = options -> on_response_header_block_done ;
242
243
stream -> base .on_incoming_body = options -> on_response_body ;
244
+ stream -> base .on_metrics = options -> on_metrics ;
243
245
stream -> base .on_complete = options -> on_complete ;
244
246
stream -> base .on_destroy = options -> on_destroy ;
245
247
stream -> base .client_data = & stream -> base .client_or_server_data .client ;
246
248
stream -> base .client_data -> response_status = AWS_HTTP_STATUS_CODE_UNKNOWN ;
249
+ stream -> base .metrics .send_start_timestamp_ns = -1 ;
250
+ stream -> base .metrics .send_end_timestamp_ns = -1 ;
251
+ stream -> base .metrics .sending_duration_ns = -1 ;
252
+ stream -> base .metrics .receive_start_timestamp_ns = -1 ;
253
+ stream -> base .metrics .receive_end_timestamp_ns = -1 ;
254
+ stream -> base .metrics .receiving_duration_ns = -1 ;
247
255
aws_linked_list_init (& stream -> thread_data .outgoing_writes );
248
256
aws_linked_list_init (& stream -> synced_data .pending_write_list );
249
257
@@ -446,6 +454,9 @@ void aws_h2_stream_complete(struct aws_h2_stream *stream, int error_code) {
446
454
s_h2_stream_destroy_pending_writes (stream );
447
455
448
456
/* Invoke callback */
457
+ if (stream -> base .on_metrics ) {
458
+ stream -> base .on_metrics (& stream -> base , & stream -> base .metrics , stream -> base .user_data );
459
+ }
449
460
if (stream -> base .on_complete ) {
450
461
stream -> base .on_complete (& stream -> base , error_code , stream -> base .user_data );
451
462
}
@@ -706,7 +717,8 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_
706
717
AWS_H2_STREAM_LOGF (ERROR , stream , "Failed to create HEADERS frame: %s" , aws_error_name (aws_last_error ()));
707
718
goto error ;
708
719
}
709
-
720
+ AWS_ASSERT (stream -> base .metrics .send_start_timestamp_ns == -1 );
721
+ aws_high_res_clock_get_ticks ((uint64_t * )& stream -> base .metrics .send_start_timestamp_ns );
710
722
/* Initialize the flow-control window size */
711
723
stream -> thread_data .window_size_peer =
712
724
connection -> thread_data .settings_peer [AWS_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE ];
@@ -721,6 +733,11 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_
721
733
/* If stream has no body, then HEADERS frame marks the end of outgoing data */
722
734
stream -> thread_data .state = AWS_H2_STREAM_STATE_HALF_CLOSED_LOCAL ;
723
735
AWS_H2_STREAM_LOG (TRACE , stream , "Sending HEADERS with END_STREAM. State -> HALF_CLOSED_LOCAL" );
736
+ /* There is no further frames to be sent, now is the end timestamp of sending. */
737
+ AWS_ASSERT (stream -> base .metrics .send_end_timestamp_ns == -1 );
738
+ aws_high_res_clock_get_ticks ((uint64_t * )& stream -> base .metrics .send_end_timestamp_ns );
739
+ stream -> base .metrics .sending_duration_ns =
740
+ stream -> base .metrics .send_end_timestamp_ns - stream -> base .metrics .send_start_timestamp_ns ;
724
741
}
725
742
726
743
if (s_h2_stream_has_outgoing_writes (stream )) {
@@ -798,6 +815,11 @@ int aws_h2_stream_encode_data_frame(
798
815
*/
799
816
if (input_stream_complete && ends_stream ) {
800
817
/* Done sending data. No more data will be sent. */
818
+ AWS_ASSERT (stream -> base .metrics .send_end_timestamp_ns == -1 );
819
+ aws_high_res_clock_get_ticks ((uint64_t * )& stream -> base .metrics .send_end_timestamp_ns );
820
+ stream -> base .metrics .sending_duration_ns =
821
+ stream -> base .metrics .send_end_timestamp_ns - stream -> base .metrics .send_start_timestamp_ns ;
822
+
801
823
if (stream -> thread_data .state == AWS_H2_STREAM_STATE_HALF_CLOSED_REMOTE ) {
802
824
/* Both sides have sent END_STREAM */
803
825
stream -> thread_data .state = AWS_H2_STREAM_STATE_CLOSED ;
@@ -841,6 +863,7 @@ struct aws_h2err aws_h2_stream_on_decoder_headers_begin(struct aws_h2_stream *st
841
863
if (aws_h2err_failed (stream_err )) {
842
864
return s_send_rst_and_close_stream (stream , stream_err );
843
865
}
866
+ aws_high_res_clock_get_ticks ((uint64_t * )& stream -> base .metrics .receive_start_timestamp_ns );
844
867
845
868
return AWS_H2ERR_SUCCESS ;
846
869
}
@@ -1150,6 +1173,13 @@ struct aws_h2err aws_h2_stream_on_decoder_end_stream(struct aws_h2_stream *strea
1150
1173
* an actual frame type. It's a flag on DATA or HEADERS frames, and we
1151
1174
* already checked the legality of those frames in their respective callbacks. */
1152
1175
1176
+ AWS_ASSERT (stream -> base .metrics .receive_start_timestamp_ns != -1 );
1177
+ AWS_ASSERT (stream -> base .metrics .receive_end_timestamp_ns == -1 );
1178
+ aws_high_res_clock_get_ticks ((uint64_t * )& stream -> base .metrics .receive_end_timestamp_ns );
1179
+ AWS_ASSERT (stream -> base .metrics .receive_end_timestamp_ns >= stream -> base .metrics .receive_start_timestamp_ns );
1180
+ stream -> base .metrics .receiving_duration_ns =
1181
+ stream -> base .metrics .receive_end_timestamp_ns - stream -> base .metrics .receive_start_timestamp_ns ;
1182
+
1153
1183
if (stream -> thread_data .content_length_received ) {
1154
1184
if (stream -> base .request_method != AWS_HTTP_METHOD_HEAD &&
1155
1185
stream -> base .client_data -> response_status != AWS_HTTP_STATUS_CODE_304_NOT_MODIFIED ) {
0 commit comments