You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gm...@apache.org on 2020/10/27 17:18:40 UTC
[qpid-dispatch] branch dev-protocol-adaptors-2 updated:
DISPATCH-1815: Send PING frame every 4 seconds on an egress connection.
This closes #897.
This is an automated email from the ASF dual-hosted git repository.
gmurthy pushed a commit to branch dev-protocol-adaptors-2
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git
The following commit(s) were added to refs/heads/dev-protocol-adaptors-2 by this push:
new 1b9149c DISPATCH-1815: Send PING frame every 4 seconds on an egress connection. This closes #897.
1b9149c is described below
commit 1b9149c675186e68016e3cb506f3e4096c9d7a0b
Author: Ganesh Murthy <gm...@apache.org>
AuthorDate: Mon Oct 26 16:43:41 2020 -0400
DISPATCH-1815: Send PING frame every 4 seconds on an egress connection. This closes #897.
---
src/adaptors/http2/http2_adaptor.c | 62 +++++++++++++++++++++++++++++++++++---
src/adaptors/http2/http2_adaptor.h | 4 +++
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/src/adaptors/http2/http2_adaptor.c b/src/adaptors/http2/http2_adaptor.c
index 5c94830..8618b81 100644
--- a/src/adaptors/http2/http2_adaptor.c
+++ b/src/adaptors/http2/http2_adaptor.c
@@ -312,6 +312,11 @@ void free_qdr_http2_connection(qdr_http2_connection_t* http_conn, bool on_shutdo
http_conn->activate_timer = 0;
}
+ if (http_conn->ping_timer) {
+ qd_timer_free(http_conn->ping_timer);
+ http_conn->ping_timer = 0;
+ }
+
// Free all the stream data associated with this connection/session.
qdr_http2_stream_data_t *stream_data = DEQ_HEAD(http_conn->session_data->streams);
while (stream_data) {
@@ -719,6 +724,29 @@ static void create_settings_frame(qdr_http2_connection_t *conn)
}
+static void send_ping_frame(qdr_http2_connection_t *conn)
+{
+ qdr_http2_session_data_t *session_data = conn->session_data;
+ nghttp2_submit_ping(session_data->session, NGHTTP2_FLAG_NONE, 0);
+ nghttp2_session_send(session_data->session);
+}
+
+static void check_send_ping_frame(qdr_http2_connection_t *conn)
+{
+ time_t current = time(NULL);
+ time_t prev = conn->prev_ping;
+
+ //
+ // Send a ping frame every 4 seconds.
+ //
+ if (current - prev >= 4) {
+ send_ping_frame(conn);
+ qd_log(http2_adaptor->log_source, QD_LOG_TRACE, "[C%"PRIu64"] Sent PING frame", conn->conn_id);
+ qd_timer_schedule(conn->ping_timer, 4000);
+ conn->prev_ping = current;
+ }
+}
+
static void send_settings_frame(qdr_http2_connection_t *conn)
{
qdr_http2_session_data_t *session_data = conn->session_data;
@@ -747,6 +775,10 @@ static int on_frame_recv_callback(nghttp2_session *session,
qdr_http2_stream_data_t *stream_data = nghttp2_session_get_stream_user_data(session_data->session, stream_id);
switch (frame->hd.type) {
+ case NGHTTP2_PING: {
+ qd_log(http2_adaptor->protocol_log_source, QD_LOG_TRACE, "[C%"PRIu64"][S%"PRId32"] HTTP2 PING frame received", conn->conn_id, stream_id);
+ }
+ break;
case NGHTTP2_PRIORITY: {
qd_log(http2_adaptor->protocol_log_source, QD_LOG_TRACE, "[C%"PRIu64"][S%"PRId32"] HTTP2 PRIORITY frame received", conn->conn_id, stream_id);
}
@@ -1833,6 +1865,22 @@ static void handle_disconnected(qdr_http2_connection_t* conn)
sys_mutex_unlock(qd_server_get_activation_lock(http2_adaptor->core->qd->server));
}
+
+static void egress_conn_ping_sender(void *context)
+{
+ qdr_http2_connection_t* conn = (qdr_http2_connection_t*) context;
+ qd_log(http2_adaptor->log_source, QD_LOG_TRACE, "[C%"PRIu64"] Running egress_conn_ping_sender", conn->conn_id);
+
+ if (!conn->connection_established)
+ return;
+
+ if (conn->pn_raw_conn) {
+ qd_log(http2_adaptor->log_source, QD_LOG_TRACE, "[C%"PRIu64"] egress_conn_ping_sender, calling pn_raw_connection_wake()", conn->conn_id);
+ pn_raw_connection_wake(conn->pn_raw_conn);
+ }
+}
+
+
static void egress_conn_timer_handler(void *context)
{
qdr_http2_connection_t* conn = (qdr_http2_connection_t*) context;
@@ -1843,7 +1891,7 @@ static void egress_conn_timer_handler(void *context)
return;
if (!conn->ingress) {
- qd_log(http2_adaptor->log_source, QD_LOG_DEBUG, "[C%"PRIu64"] - egress_conn_timer_handler - Trying to establishing outbound connection", conn->conn_id);
+ qd_log(http2_adaptor->log_source, QD_LOG_TRACE, "[C%"PRIu64"] - Egress_conn_timer_handler - Trying to establishing outbound connection", conn->conn_id);
http_connector_establish(conn);
}
}
@@ -1883,6 +1931,7 @@ qdr_http2_connection_t *qdr_http_connection_egress(qd_http_connector_t *connecto
qdr_http2_connection_t* egress_http_conn = new_qdr_http2_connection_t();
ZERO(egress_http_conn);
egress_http_conn->activate_timer = qd_timer(http2_adaptor->core->qd, egress_conn_timer_handler, egress_http_conn);
+ egress_http_conn->ping_timer = qd_timer(http2_adaptor->core->qd, egress_conn_ping_sender, egress_http_conn);
egress_http_conn->ingress = false;
egress_http_conn->context.context = egress_http_conn;
@@ -1958,11 +2007,11 @@ static void handle_connection_event(pn_event_t *e, qd_server_t *qd_server, void
} else {
qd_log(log, QD_LOG_INFO, "[C%"PRIu64"] Connected Egress (PN_RAW_CONNECTION_CONNECTED), thread_id=%i", conn->conn_id, pthread_self());
conn->connection_established = true;
- if (!conn->ingress) {
- create_stream_dispatcher_link(conn);
- qd_log(log, QD_LOG_TRACE, "[C%"PRIu64"] Created stream_dispatcher_link in PN_RAW_CONNECTION_CONNECTED", conn->conn_id);
- }
+ create_stream_dispatcher_link(conn);
+ qd_log(log, QD_LOG_TRACE, "[C%"PRIu64"] Created stream_dispatcher_link in PN_RAW_CONNECTION_CONNECTED", conn->conn_id);
qdr_connection_process(conn->qdr_conn);
+ // Send a PING frame 4 seconds after opening an egress connection.
+ qd_timer_schedule(conn->ping_timer, 4000);
}
break;
}
@@ -2000,6 +2049,9 @@ static void handle_connection_event(pn_event_t *e, qd_server_t *qd_server, void
break;
}
case PN_RAW_CONNECTION_WAKE: {
+ if (!conn->ingress) {
+ check_send_ping_frame(conn);
+ }
qd_log(log, QD_LOG_TRACE, "[C%"PRIu64"] PN_RAW_CONNECTION_WAKE Wake-up", conn->conn_id);
while (qdr_connection_process(conn->qdr_conn)) {}
break;
diff --git a/src/adaptors/http2/http2_adaptor.h b/src/adaptors/http2/http2_adaptor.h
index 2fe08c3..979f34d 100644
--- a/src/adaptors/http2/http2_adaptor.h
+++ b/src/adaptors/http2/http2_adaptor.h
@@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
+#include <time.h>
+
#include <qpid/dispatch/server.h>
#include <qpid/dispatch/threading.h>
#include <qpid/dispatch/compose.h>
@@ -117,6 +119,7 @@ struct qdr_http2_connection_t {
pn_raw_connection_t *pn_raw_conn;
pn_raw_buffer_t read_buffers[4];
qd_timer_t *activate_timer;
+ qd_timer_t *ping_timer; // This timer is used to send a ping frame on the egress connection every 4 seconds.
qd_http_bridge_config_t *config;
qd_server_t *server;
uint64_t conn_id;
@@ -134,6 +137,7 @@ struct qdr_http2_connection_t {
bool ingress;
bool timer_scheduled;
bool client_magic_sent;
+ time_t prev_ping; // Time the previous PING frame was sent on egress connection.
DEQ_LINKS(qdr_http2_connection_t);
};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org