]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: filters: Add check_timeouts callback to handle timers expiration on streams
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 10 Nov 2016 13:58:05 +0000 (14:58 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 21 Nov 2016 14:29:58 +0000 (15:29 +0100)
A filter can now be notified when a stream is woken up because of an expired
timer.

The documentation and the TRACE filter have been updated.

doc/internals/filters.txt
include/proto/filters.h
include/types/filters.h
src/filters.c
src/flt_trace.c
src/stream.c

index 7e949a92b35ecd1d9ca60b7a266385c81112ce88..83aebf520640a35c593d49f83b2bb4849628de45 100644 (file)
@@ -1,6 +1,6 @@
                    -----------------------------------------
                           Filters Guide - version 1.7
-                          ( Last update: 2016-06-21 )
+                          ( Last update: 2016-11-10 )
                    ------------------------------------------
                           Author : Christopher Faulet
               Contact : christopher dot faulet at capflam dot org
@@ -191,6 +191,7 @@ existing callbacks. Available callbacks are listed in the following structure:
         int  (*stream_set_backend)(struct stream *s, struct filter *f, struct proxy *be);
         void (*stream_stop)       (struct stream *s, struct filter *f);
         void (*detach)            (struct stream *s, struct filter *f);
+        void (*check_timeouts)    (struct stream *s, struct filter *f);
 
         /*
          * Channel callbacks
@@ -612,6 +613,25 @@ For example:
         /* ... */
     }
 
+Finally, you may be interested to be notified when the stream is woken up
+because of an expired timer. This could let you a chance to check your own
+timeouts, if any. To do so you can use the following callback:
+
+  * 'flt_opt.check_timeouts': It is called when a stream is woken up because
+                              of an expired timer.
+
+For example:
+
+    /* Called when a stream is woken up because of an expired timer */
+    static void
+    my_filter_check_timeouts(struct stream *s, struct filter *filter)
+    {
+        struct my_filter_config *my_conf = FLT_CONF(filter);
+
+        /* ... */
+    }
+
+
 3.5. ANALYZING THE CHANNELS ACTIVITY
 ------------------------------------
 
index c351f6e20fe2fa23838fe9ed8eea49cc89a6b67f..912c4135cfe1a40439a0166fcfaffb9ecf347d3e 100644 (file)
@@ -104,6 +104,7 @@ void flt_stream_stop(struct stream *s);
 int  flt_set_stream_backend(struct stream *s, struct proxy *be);
 int  flt_stream_init(struct stream *s);
 void flt_stream_release(struct stream *s, int only_backend);
+void flt_stream_check_timeouts(struct stream *s);
 
 int  flt_http_data(struct stream *s, struct http_msg *msg);
 int  flt_http_chunk_trailers(struct stream *s, struct http_msg *msg);
index 62b457de7ad6d0888544dbad4377f8adf103fcc7..e6d0c2c971ec9dad032321915361572acfd8cc66 100644 (file)
@@ -90,6 +90,8 @@ struct flt_kw_list {
  *                          the stream is stopped for filters defined on the
  *                          stream's frontend and when the analyze ends for
  *                          filters defined on the stream's backend.
+ *  - check_timeouts      : Called when a a stream is woken up because of an
+ *                          expired timer.
  *
  *
  *  - channel_start_analyze: Called when a filter starts to analyze a channel.
@@ -159,7 +161,7 @@ struct flt_ops {
        int  (*stream_set_backend)(struct stream *s, struct filter *f, struct proxy *be);
        void (*stream_stop)       (struct stream *s, struct filter *f);
        void (*detach)            (struct stream *s, struct filter *f);
-
+       void (*check_timeouts)    (struct stream *s, struct filter *f);
        /*
         * Channel callbacks
         */
index 8c3485e10c7c5ce3780ed713f859d9dc160d9e8f..91404a48488ea451de3deb64fb134f5fa7939cf1 100644 (file)
@@ -397,6 +397,21 @@ flt_stream_stop(struct stream *s)
        }
 }
 
+/*
+ * Calls 'check_timeouts' for all filters attached to a stream. This happens when
+ * the stream is woken up because of expired timer.
+ */
+void
+flt_stream_check_timeouts(struct stream *s)
+{
+       struct filter *filter;
+
+       list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+               if (FLT_OPS(filter)->check_timeouts)
+                       FLT_OPS(filter)->check_timeouts(s, filter);
+       }
+}
+
 /*
  * Called when a backend is set for a stream. If the frontend and the backend
  * are not the same, this function attaches all backend filters to the
index 76081b2d56c6ac2481033e4ecb195d14ce00e90b..96ce2ac58e51bc9bdc5001d9956051c9b4478da7 100644 (file)
@@ -214,6 +214,16 @@ trace_stream_stop(struct stream *s, struct filter *filter)
                   __FUNCTION__);
 }
 
+/* Called when the stream is woken up because of an expired timer */
+static void
+trace_check_timeouts(struct stream *s, struct filter *filter)
+{
+       struct trace_config *conf = FLT_CONF(filter);
+
+       STRM_TRACE(conf, s, "%-25s",
+                  __FUNCTION__);
+}
+
 /**************************************************************************
  * Hooks to handle channels activity
  *************************************************************************/
@@ -509,6 +519,7 @@ struct flt_ops trace_ops = {
        .stream_start       = trace_stream_start,
        .stream_set_backend = trace_stream_set_backend,
        .stream_stop        = trace_stream_stop,
+       .check_timeouts     = trace_check_timeouts,
 
        /* Handle channels activity */
        .channel_start_analyze = trace_chn_start_analyze,
index a5d80a3b013843a8aa5a5bcf17fe3df53dfd7bdd..288d36defea98d742ae222a7a5abf6d01ef05baf 100644 (file)
@@ -1620,6 +1620,9 @@ struct task *process_stream(struct task *t)
                        si_shutr(si_b);
                }
 
+               if (HAS_FILTERS(s))
+                       flt_stream_check_timeouts(s);
+
                /* Once in a while we're woken up because the task expires. But
                 * this does not necessarily mean that a timeout has been reached.
                 * So let's not run a whole stream processing if only an expiration
@@ -2365,8 +2368,9 @@ struct task *process_stream(struct task *t)
 
        update_exp_and_leave:
                /* Note: please ensure that if you branch here you disable SI_FL_DONT_WAKE */
-               t->expire = tick_first(tick_first(req->rex, req->wex),
-                                      tick_first(res->rex, res->wex));
+               t->expire = tick_first((tick_is_expired(t->expire, now_ms) ? 0 : t->expire),
+                                      tick_first(tick_first(req->rex, req->wex),
+                                                 tick_first(res->rex, res->wex)));
                if (!req->analysers)
                        req->analyse_exp = TICK_ETERNITY;