From a00d817abad610c66a607c50298b579e85981e9e Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 10 Nov 2016 14:58:05 +0100 Subject: [PATCH] MINOR: filters: Add check_timeouts callback to handle timers expiration on streams 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 | 22 +++++++++++++++++++++- include/proto/filters.h | 1 + include/types/filters.h | 4 +++- src/filters.c | 15 +++++++++++++++ src/flt_trace.c | 11 +++++++++++ src/stream.c | 8 ++++++-- 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/doc/internals/filters.txt b/doc/internals/filters.txt index 7e949a92b3..83aebf5206 100644 --- a/doc/internals/filters.txt +++ b/doc/internals/filters.txt @@ -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 ------------------------------------ diff --git a/include/proto/filters.h b/include/proto/filters.h index c351f6e20f..912c4135cf 100644 --- a/include/proto/filters.h +++ b/include/proto/filters.h @@ -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); diff --git a/include/types/filters.h b/include/types/filters.h index 62b457de7a..e6d0c2c971 100644 --- a/include/types/filters.h +++ b/include/types/filters.h @@ -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 */ diff --git a/src/filters.c b/src/filters.c index 8c3485e10c..91404a4848 100644 --- a/src/filters.c +++ b/src/filters.c @@ -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 diff --git a/src/flt_trace.c b/src/flt_trace.c index 76081b2d56..96ce2ac58e 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -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, diff --git a/src/stream.c b/src/stream.c index a5d80a3b01..288d36defe 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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;