]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stick-table: Add table_expire() and table_idle() new converters
authorFrédéric Lécaille <flecaille@haproxy.com>
Tue, 16 Aug 2022 16:11:25 +0000 (18:11 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 17 Aug 2022 08:52:15 +0000 (10:52 +0200)
table_expire() returns the expiration delay for a stick-table entry associated
to an input sample. Its counterpart table_idle() returns the time the entry
remained idle since the last time it was updated.
Both converters may take a default value as second argument which is returned
when the entry is not present.

doc/configuration.txt
src/stick_table.c

index aa167a8264a089228316e064e61db6c089268e5e..7b01c7969a38835177a0912ecbb1646a57f46abf 100644 (file)
@@ -17710,6 +17710,14 @@ table_conn_rate(<table>)
   rate associated with the input sample in the designated table. See also the
   sc_conn_rate sample fetch keyword.
 
+table_expire(<table>[,<default_value>])
+  Uses the input sample to perform a look up in the specified table. If the key
+  is not found in the table, the converter fails except if <default_value> is
+  set: this makes the converter succeed and return <default_value>. If the key
+  is found the converter returns the key expiration delay associated with the
+  input sample in the designated table.
+  See also the table_idle sample fetch keyword.
+
 table_gpt(<idx>,<table>)
   Uses the string representation of the input sample to perform a lookup in
   the specified table. If the key is not found in the table, boolean value zero
@@ -17828,6 +17836,15 @@ table_http_req_rate(<table>)
   period configured in the table. See also the sc_http_req_rate sample fetch
   keyword.
 
+table_idle(<table>)
+  Uses the input sample to perform a look up in the specified table. If the key
+  is not found in the table, the converter fails except if <default_value> is
+  set: this makes the converter succeed and return <default_value>. If the key
+  is found the converter returns the time the key entry associated with the
+  input sample in the designated table remained idle since the last time it was
+  updated.
+  See also the table_expire sample fetch keyword.
+
 table_kbytes_in(<table>)
   Uses the string representation of the input sample to perform a look up in
   the specified table. If the key is not found in the table, integer value zero
index 9112996aa545958e9623636349bb4bba24585b43..b1e7b59a5ef2623224a71b2e8ee21c256775cbb0 100644 (file)
@@ -1392,6 +1392,82 @@ static int sample_conv_table_conn_rate(const struct arg *arg_p, struct sample *s
        return !!ptr;
 }
 
+/* Casts sample <smp> to the type of the table specified in arg(0), and looks
+ * it up into this table. Returns the expiration delay for the key if the key is
+ * present in the table, otherwise the default value provided as second argument
+ * if any, if not (no default value), <not found> is returned.
+ */
+static int sample_conv_table_expire(const struct arg *arg_p, struct sample *smp, void *private)
+{
+       struct stktable *t;
+       struct stktable_key *key;
+       struct stksess *ts;
+
+       t = arg_p[0].data.t;
+
+       key = smp_to_stkey(smp, t);
+       if (!key)
+               return 0;
+
+       ts = stktable_lookup_key(t, key);
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (!ts) { /* key not present */
+               if (arg_p[1].type == ARGT_STOP)
+                       return 0;
+
+               /* default value */
+               smp->data.u.sint = arg_p[1].data.sint;
+               return 1;
+       }
+
+       smp->data.u.sint = tick_remain(now_ms, ts->expire);
+
+       stktable_release(t, ts);
+       return 1;
+}
+
+/* Casts sample <smp> to the type of the table specified in arg(0), and looks
+ * it up into this table. Returns the time the key remains unused if the key is
+ * present in the table,  otherwise the default value provided as second argument
+ * if any, if not (no default value), <not found> is returned.
+ */
+static int sample_conv_table_idle(const struct arg *arg_p, struct sample *smp, void *private)
+{
+       struct stktable *t;
+       struct stktable_key *key;
+       struct stksess *ts;
+
+       t = arg_p[0].data.t;
+
+       key = smp_to_stkey(smp, t);
+       if (!key)
+               return 0;
+
+       ts = stktable_lookup_key(t, key);
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (!ts) { /* key not present */
+               if (arg_p[1].type == ARGT_STOP)
+                       return 0;
+
+               /* default value */
+               smp->data.u.sint = arg_p[1].data.sint;
+               return 1;
+       }
+
+       smp->data.u.sint = tick_remain(tick_remain(now_ms, ts->expire), t->expire);
+
+       stktable_release(t, ts);
+       return 1;
+}
+
 /* Casts sample <smp> to the type of the table specified in arg(0), and looks
  * it up into this table. Returns the data rate sent to clients in bytes/s
  * if the key is present in the table, otherwise zero, so that comparisons can
@@ -5074,6 +5150,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
        { "table_conn_cnt",       sample_conv_table_conn_cnt,       ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_conn_cur",       sample_conv_table_conn_cur,       ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_conn_rate",      sample_conv_table_conn_rate,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
+       { "table_expire",         sample_conv_table_expire,         ARG2(1,TAB,SINT),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpt",            sample_conv_table_gpt,            ARG2(2,SINT,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpt0",           sample_conv_table_gpt0,           ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpc",            sample_conv_table_gpc,            ARG2(2,SINT,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
@@ -5088,6 +5165,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
        { "table_http_fail_rate", sample_conv_table_http_fail_rate, ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_http_req_cnt",   sample_conv_table_http_req_cnt,   ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_http_req_rate",  sample_conv_table_http_req_rate,  ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
+       { "table_idle",           sample_conv_table_idle,           ARG2(1,TAB,SINT),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_kbytes_in",      sample_conv_table_kbytes_in,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_kbytes_out",     sample_conv_table_kbytes_out,     ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_server_id",      sample_conv_table_server_id,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },