]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream: add an "epoch" to figure which streams appeared when
authorWilly Tarreau <w@1wt.eu>
Wed, 24 Feb 2021 10:29:51 +0000 (11:29 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 24 Feb 2021 11:12:51 +0000 (12:12 +0100)
The "show sess" CLI command currently lists all streams and needs to
stop at a given position to avoid dumping forever. Since 2.2 with
commit c6e7a1b8e ("MINOR: cli: make "show sess" stop at the last known
session"), a hack consists in unlinking the stream running the applet
and linking it again at the current end of the list, in order to serve
as a delimiter. But this forces the stream list to be global, which
affects scalability.

This patch introduces an epoch, which is a global 32-bit counter that
is incremented by the "show sess" command, and which is copied by newly
created streams. This way any stream can know whether any other one is
newer or older than itself.

For now it's only stored and not exploited.

include/haproxy/stream-t.h
src/stream.c

index 1e0ab1ecd7aa9403b3c184cf91924b700dde564b..429d99244ccf3822b529711b8fd0a3616838545f 100644 (file)
@@ -181,6 +181,8 @@ struct stream {
        struct list *current_rule_list;         /* this is used to store the current executed rule list. */
        void *current_rule;                     /* this is used to store the current rule to be resumed. */
        int rules_exp;                          /* expiration date for current rules execution */
+
+       unsigned int stream_epoch;              /* copy of stream_epoch when the stream was created */
        struct hlua *hlua;                      /* lua runtime context */
 
        /* Context */
index 1dfbd361ac06ec79cb9c1f70f41c9ea3e2edcb01..0b86488a53675e579060a75865fb0050c8095901 100644 (file)
@@ -64,6 +64,8 @@
 DECLARE_POOL(pool_head_stream, "stream", sizeof(struct stream));
 DECLARE_POOL(pool_head_uniqueid, "uniqueid", UNIQUEID_LEN);
 
+/* incremented by each "show sess" to fix a delimiter between streams */
+unsigned stream_epoch = 0;
 struct list streams = LIST_HEAD_INIT(streams);
 __decl_spinlock(streams_lock);
 
@@ -414,6 +416,7 @@ struct stream *stream_new(struct session *sess, enum obj_type *origin, struct bu
        s->si[0].flags = SI_FL_NONE;
        s->si[1].flags = SI_FL_ISBACK;
 
+       s->stream_epoch = _HA_ATOMIC_LOAD(&stream_epoch);
        s->uniq_id = _HA_ATOMIC_XADD(&global.req_count, 1);
 
        /* OK, we're keeping the stream, so let's properly initialize the stream */
@@ -2885,9 +2888,9 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st
                }
 
                chunk_appendf(&trash,
-                            "  flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p waiting=%d\n",
+                            "  flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p waiting=%d epoch=%#x\n",
                             strm->flags, strm->si[1].conn_retries, strm->srv_conn, strm->pend_pos,
-                            LIST_ADDED(&strm->buffer_wait.list));
+                            LIST_ADDED(&strm->buffer_wait.list), strm->stream_epoch);
 
                chunk_appendf(&trash,
                             "  frontend=%s (id=%u mode=%s), listener=%s (id=%u)",
@@ -3185,6 +3188,11 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx
        appctx->ctx.sess.section = 0; /* start with stream status */
        appctx->ctx.sess.pos = 0;
 
+       /* let's set our own stream's epoch to the current one and increment
+        * it so that we know which streams were already there before us.
+        */
+       si_strm(appctx->owner)->stream_epoch = _HA_ATOMIC_XADD(&stream_epoch, 1);
+
        /* we need to put an end marker into the streams list. We're just moving
         * ourselves there, so that once we found ourselves we know we've reached
         * the end. Without this we can run forever if new streams arrive faster
@@ -3302,8 +3310,8 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
                        }
 
                        chunk_appendf(&trash,
-                                    " ts=%02x age=%s calls=%u rate=%u cpu=%llu lat=%llu",
-                                    curr_strm->task->state,
+                                    " ts=%02x epoch=%#x age=%s calls=%u rate=%u cpu=%llu lat=%llu",
+                                    curr_strm->task->state, curr_strm->stream_epoch,
                                     human_time(now.tv_sec - curr_strm->logs.tv_accept.tv_sec, 1),
                                     curr_strm->task->calls, read_freq_ctr(&curr_strm->call_rate),
                                     (unsigned long long)curr_strm->task->cpu_time, (unsigned long long)curr_strm->task->lat_time);