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