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).
This commit is contained in:
Aurelien DARRAGON 2024-10-18 18:40:41 +02:00
parent f7267bd315
commit f72a66eef2
3 changed files with 26 additions and 1 deletions

View File

@ -25,6 +25,7 @@
#include <import/ebtree-t.h>
#include <haproxy/api-t.h>
#include <haproxy/event_hdl-t.h>
#include <haproxy/regex-t.h>
#include <haproxy/sample_data-t.h>
#include <haproxy/thread-t.h>
@ -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

View File

@ -25,6 +25,7 @@
#include <string.h>
#include <haproxy/api.h>
#include <haproxy/event_hdl.h>
#include <haproxy/pattern-t.h>
#include <haproxy/sample-t.h>
@ -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;
}

View File

@ -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;
}