[PATCH 2 of 2] HTTP/3: delayed Insert Count Increment instruction
Roman Arutyunyan
arut at nginx.com
Thu Oct 21 13:41:00 UTC 2021
# HG changeset patch
# User Roman Arutyunyan <arut at nginx.com>
# Date 1634804424 -10800
# Thu Oct 21 11:20:24 2021 +0300
# Branch quic
# Node ID e2d65b59ccb9035cbd619358a121ba5bcca3404a
# Parent 8b049432ef2dcdb8d1a8ec1a5e41c0a340285b65
HTTP/3: delayed Insert Count Increment instruction.
Sending the instruction is delayed until the end of the current event cycle.
Delaying the instruction is allowed by quic-qpack-21, section 2.2.2.3.
The goal is to reduce the amount of data sent back to client by accumulating
inserts.
diff --git a/src/http/v3/ngx_http_v3.c b/src/http/v3/ngx_http_v3.c
--- a/src/http/v3/ngx_http_v3.c
+++ b/src/http/v3/ngx_http_v3.c
@@ -47,6 +47,10 @@ ngx_http_v3_init_session(ngx_connection_
h3c->keepalive.handler = ngx_http_v3_keepalive_handler;
h3c->keepalive.cancelable = 1;
+ h3c->table.send_insert_count.log = pc->log;
+ h3c->table.send_insert_count.data = pc;
+ h3c->table.send_insert_count.handler = ngx_http_v3_inc_insert_count_handler;
+
cln = ngx_pool_cleanup_add(pc->pool, 0);
if (cln == NULL) {
return NGX_ERROR;
@@ -85,6 +89,10 @@ ngx_http_v3_cleanup_session(void *data)
if (h3c->keepalive.timer_set) {
ngx_del_timer(&h3c->keepalive);
}
+
+ if (h3c->table.send_insert_count.posted) {
+ ngx_delete_posted_event(&h3c->table.send_insert_count);
+ }
}
diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c
--- a/src/http/v3/ngx_http_v3_parse.c
+++ b/src/http/v3/ngx_http_v3_parse.c
@@ -395,6 +395,8 @@ done:
if (ngx_http_v3_send_ack_section(c, c->quic->id) != NGX_OK) {
return NGX_ERROR;
}
+
+ ngx_http_v3_ack_insert_count(c, st->prefix.insert_count);
}
st->state = sw_start;
diff --git a/src/http/v3/ngx_http_v3_tables.c b/src/http/v3/ngx_http_v3_tables.c
--- a/src/http/v3/ngx_http_v3_tables.c
+++ b/src/http/v3/ngx_http_v3_tables.c
@@ -232,11 +232,9 @@ ngx_http_v3_insert(ngx_connection_t *c,
dt->elts[dt->nelts++] = field;
dt->size += size;
- /* TODO increment can be sent less often */
+ dt->insert_count++;
- if (ngx_http_v3_send_inc_insert_count(c, 1) != NGX_OK) {
- return NGX_ERROR;
- }
+ ngx_post_event(&dt->send_insert_count, &ngx_posted_events);
if (ngx_http_v3_new_entry(c) != NGX_OK) {
return NGX_ERROR;
@@ -246,6 +244,34 @@ ngx_http_v3_insert(ngx_connection_t *c,
}
+void
+ngx_http_v3_inc_insert_count_handler(ngx_event_t *ev)
+{
+ ngx_connection_t *c;
+ ngx_http_v3_session_t *h3c;
+ ngx_http_v3_dynamic_table_t *dt;
+
+ c = ev->data;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 inc insert count handler");
+
+ h3c = ngx_http_v3_get_session(c);
+ dt = &h3c->table;
+
+ if (dt->insert_count > dt->ack_insert_count) {
+ if (ngx_http_v3_send_inc_insert_count(c,
+ dt->insert_count - dt->ack_insert_count)
+ != NGX_OK)
+ {
+ return;
+ }
+
+ dt->ack_insert_count = dt->insert_count;
+ }
+}
+
+
ngx_int_t
ngx_http_v3_set_capacity(ngx_connection_t *c, ngx_uint_t capacity)
{
@@ -603,6 +629,21 @@ ngx_http_v3_check_insert_count(ngx_conne
}
+void
+ngx_http_v3_ack_insert_count(ngx_connection_t *c, uint64_t insert_count)
+{
+ ngx_http_v3_session_t *h3c;
+ ngx_http_v3_dynamic_table_t *dt;
+
+ h3c = ngx_http_v3_get_session(c);
+ dt = &h3c->table;
+
+ if (dt->ack_insert_count < insert_count) {
+ dt->ack_insert_count = insert_count;
+ }
+}
+
+
static void
ngx_http_v3_unblock(void *data)
{
diff --git a/src/http/v3/ngx_http_v3_tables.h b/src/http/v3/ngx_http_v3_tables.h
--- a/src/http/v3/ngx_http_v3_tables.h
+++ b/src/http/v3/ngx_http_v3_tables.h
@@ -26,9 +26,13 @@ typedef struct {
ngx_uint_t base;
size_t size;
size_t capacity;
+ uint64_t insert_count;
+ uint64_t ack_insert_count;
+ ngx_event_t send_insert_count;
} ngx_http_v3_dynamic_table_t;
+void ngx_http_v3_inc_insert_count_handler(ngx_event_t *ev);
void ngx_http_v3_cleanup_table(ngx_http_v3_session_t *h3c);
ngx_int_t ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
ngx_uint_t index, ngx_str_t *value);
@@ -46,6 +50,7 @@ ngx_int_t ngx_http_v3_decode_insert_coun
ngx_uint_t *insert_count);
ngx_int_t ngx_http_v3_check_insert_count(ngx_connection_t *c,
ngx_uint_t insert_count);
+void ngx_http_v3_ack_insert_count(ngx_connection_t *c, uint64_t insert_count);
ngx_int_t ngx_http_v3_set_param(ngx_connection_t *c, uint64_t id,
uint64_t value);
More information about the nginx-devel
mailing list