diff --git a/conf/conf.h b/conf/conf.h index 56bde039..19a115b6 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -14,6 +14,7 @@ #include "lib/hash.h" #include "lib/resource.h" #include "lib/timer.h" +#include "lib/settle.h" /* Configuration structure */ struct config { diff --git a/proto/aggregator/aggregator.c b/proto/aggregator/aggregator.c index 65f558ae..a4c20856 100644 --- a/proto/aggregator/aggregator.c +++ b/proto/aggregator/aggregator.c @@ -44,9 +44,11 @@ #include "nest/iface.h" #include "filter/filter.h" #include "proto/aggregator/aggregator.h" +#include "lib/settle.h" #include #include + /* #include "nest/route.h" #include "nest/iface.h" @@ -928,6 +930,13 @@ aggregate_on_feed_end(struct channel *C) run_aggregation(p); } +static void +aggregate_on_settle_timer(struct settle *timer) +{ + struct aggregator_proto *p = SKIP_BACK(struct aggregator_proto, p, timer); + run_aggregation(p); +} + /* * Set static attribute in @rta from static attribute in @old according to @sa. */ @@ -1477,6 +1486,8 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new HASH_REMOVE2(p->buckets, AGGR_BUCK, p->p.pool, old_bucket); sl_free(old_bucket); } + + settle_kick(&p->aggr_timer); } static int @@ -1534,6 +1545,7 @@ aggregator_init(struct proto_config *CF) p->aggr_on = cf->aggr_on; p->net_present = cf->net_present; p->merge_by = cf->merge_by; + p->aggr_timer_cf = cf->aggr_timer_cf; P->rt_notify = aggregator_rt_notify; P->preexport = aggregator_preexport; @@ -1608,6 +1620,8 @@ aggregator_start(struct proto *P) /* Assign default route to the root */ p->root->bucket = new_bucket; + settle_init(&p->aggr_timer, &p->aggr_timer_cf, aggregate_on_settle_timer, p); + return PS_UP; } @@ -1634,6 +1648,8 @@ aggregator_shutdown(struct proto *P) } HASH_WALK_END; + settle_cancel(&p->aggr_timer); + delete_trie(p->root); p->root = NULL; @@ -1648,6 +1664,10 @@ aggregator_reconfigure(struct proto *P, struct proto_config *CF) TRACE(D_EVENTS, "Reconfiguring"); + /* Compare timer configuration */ + if (cf->aggr_timer_cf.min != p->aggr_timer_cf.min || cf->aggr_timer_cf.max != p->aggr_timer_cf.max) + return 0; + /* Compare numeric values (shortcut) */ if (cf->aggr_on_count != p->aggr_on_count) return 0; diff --git a/proto/aggregator/aggregator.h b/proto/aggregator/aggregator.h index cf5b605c..26a18c79 100644 --- a/proto/aggregator/aggregator.h +++ b/proto/aggregator/aggregator.h @@ -16,6 +16,7 @@ #include "nest/bird.h" #include "nest/protocol.h" #include "lib/hash.h" +#include "lib/settle.h" #define MAX_POTENTIAL_BUCKETS_COUNT 16 @@ -27,6 +28,7 @@ struct aggregator_config { struct aggr_item *aggr_on; int net_present; const struct f_line *merge_by; + struct settle_config aggr_timer_cf; }; struct aggregator_route { @@ -70,6 +72,8 @@ struct aggregator_proto { uint addr_type; slab *trie_slab; struct trie_node *root; + struct settle_config aggr_timer_cf; + struct settle aggr_timer; int before_count; int after_count; }; diff --git a/proto/aggregator/config.Y b/proto/aggregator/config.Y index f37d842c..4d6651c2 100644 --- a/proto/aggregator/config.Y +++ b/proto/aggregator/config.Y @@ -11,6 +11,7 @@ CF_HDR #include "proto/aggregator/aggregator.h" +#include "lib/settle.h" CF_DEFINES @@ -20,7 +21,7 @@ CF_DEFINES CF_DECLS -CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY) +CF_KEYWORDS(AGGREGATOR, AGGREGATE, ON, MERGE, BY, RELOAD, AFTER) %type aggr_item aggr_list @@ -35,8 +36,12 @@ aggregator_proto_start: proto_start AGGREGATOR this_proto = proto_config_new(&proto_aggregator, $1); this_channel = AGGREGATOR_CFG->src = channel_config_new(NULL, "source", 0, this_proto); AGGREGATOR_CFG->dst = channel_config_new(NULL, "destination", 0, this_proto); - AGGREGATOR_CFG->src->ra_mode = AGGREGATOR_CFG->dst->ra_mode = RA_ANY; + + AGGREGATOR_CFG->aggr_timer_cf = (struct settle_config) { + .min = 10 MS_, + .max = 100 MS_, + }; }; aggregator_proto_item: @@ -79,6 +84,7 @@ aggregator_proto_item: $4->args++; AGGREGATOR_CFG->merge_by = $4; } + | RELOAD AFTER settle { AGGREGATOR_CFG->aggr_timer_cf = $3; } ; aggregator_proto_opts: /* empty */ | aggregator_proto_opts aggregator_proto_item ';' ; @@ -136,6 +142,16 @@ aggr_item: } ; +/* Settle timer configuration */ +settle: + expr_us expr_us { + if ($1 > $2) + cf_error("Minimum settle time %t is bigger than maximum settle time %t", $1, $2); + $$.min = $1 MS_; + $$.max = $2 MS_; + } + ; + CF_CODE CF_END