From f72a66eef2452dec81b703a99516b6a904016aba Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Fri, 18 Oct 2024 18:40:41 +0200 Subject: [PATCH] MINOR: pattern: publish event_hdl events on pat_ref updates Now that PAT_REF events were defined in previous commit, let's actually publish them from pattern API where relevant. Unlike server events, pattern reference events are only published in the pat_ref subscriber's list on purpose, because in some setups patref updates (updates performed on a map for instance from action or cli) are very frequent, and we don't want to impact pattern API performance just for that. Moreover, as the main use case is to be able to subscribe to maps updates from Lua, allowing a per-pattern reference registration is already enough. No additional data is provided for such events (also for performance reason) Care was taken not to publish events when the update doesn't affect the live subset (the one targeted by curr_gen). --- include/haproxy/pattern-t.h | 2 ++ include/haproxy/pattern.h | 5 ++++- src/pattern.c | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/haproxy/pattern-t.h b/include/haproxy/pattern-t.h index b84c7e71e4..35c4fd0956 100644 --- a/include/haproxy/pattern-t.h +++ b/include/haproxy/pattern-t.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -116,6 +117,7 @@ struct pat_ref { unsigned long long entry_cnt; /* the total number of entries */ THREAD_ALIGN(64); __decl_thread(HA_RWLOCK_T lock); /* Lock used to protect pat ref elements */ + event_hdl_sub_list e_subs; /* event_hdl: pat_ref's subscribers list (atomically updated) */ }; /* This is a part of struct pat_ref. Each entry contains one pattern and one diff --git a/include/haproxy/pattern.h b/include/haproxy/pattern.h index 283eb5b086..2b1235853c 100644 --- a/include/haproxy/pattern.h +++ b/include/haproxy/pattern.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -238,8 +239,10 @@ static inline void pat_ref_giveup(struct pat_ref *ref, unsigned int gen) */ static inline int pat_ref_commit(struct pat_ref *ref, unsigned int gen) { - if ((int)(gen - ref->curr_gen) > 0) + if ((int)(gen - ref->curr_gen) > 0) { ref->curr_gen = gen; + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_COMMIT, NULL); + } return gen - ref->curr_gen; } diff --git a/src/pattern.c b/src/pattern.c index 2c1a483424..59deced0c2 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -1606,6 +1606,7 @@ int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt) /* delete pattern from reference */ list_for_each_entry_safe(elt, safe, &ref->head, list) { if (elt == refelt) { + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_DEL, NULL); pat_ref_delete_by_ptr(ref, elt); return 1; } @@ -1636,6 +1637,9 @@ int pat_ref_gen_delete(struct pat_ref *ref, unsigned int gen_id, const char *key found = 1; } + if (found) + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_DEL, NULL); + return found; } @@ -1815,6 +1819,10 @@ static int pat_ref_set_from_node(struct pat_ref *ref, struct ebmb_node *node, co memprintf(err, "entry not found"); return 0; } + + if (gen == ref->curr_gen) // gen cannot be uninitialized here + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_SET, NULL); + return 1; } @@ -1887,6 +1895,7 @@ static struct pat_ref *_pat_ref_new(const char *display, unsigned int flags) ref->ebmb_root = EB_ROOT; LIST_INIT(&ref->pat); HA_RWLOCK_INIT(&ref->lock); + event_hdl_sub_list_init(&ref->e_subs); return ref; } @@ -1896,6 +1905,7 @@ static void pat_ref_free(struct pat_ref *ref) { ha_free(&ref->reference); ha_free(&ref->display); + event_hdl_sub_list_destroy(&ref->e_subs); free(ref); } @@ -2095,6 +2105,10 @@ struct pat_ref_elt *pat_ref_load(struct pat_ref *ref, unsigned int gen, } else memprintf(err, "out of memory error"); + /* ignore if update requires committing to be seen */ + if (elt && gen == ref->curr_gen) + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_ADD, NULL); + return elt; } @@ -2167,6 +2181,12 @@ int pat_ref_purge_range(struct pat_ref *ref, uint from, uint to, int budget) list_for_each_entry(expr, &ref->pat, list) HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock); + /* only publish when we're done and if curr_gen was impacted by the + * purge + */ + if (done && ref->curr_gen - from <= to - from) + event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_CLEAR, NULL); + return done; } -- 2.39.5