]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] session counters: automatically remove expired entries.
authorWilly Tarreau <w@1wt.eu>
Tue, 3 Aug 2010 18:34:06 +0000 (20:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Aug 2010 16:04:15 +0000 (18:04 +0200)
When a ref_cnt goes down to zero and the entry is expired, remove it.

include/proto/session.h
include/proto/stick_table.h
src/dumpstats.c
src/stick_table.c

index 095932071445f09381618c799eebb60d546d08ba..bf390cacab6e64b86252c0cdd063df82a6d781fd 100644 (file)
@@ -60,6 +60,7 @@ static inline void session_store_counters(struct session *s)
                if (ptr)
                        stktable_data_cast(ptr, conn_cur)--;
                s->be_tracked_counters->ref_cnt--;
+               stksess_kill_if_expired(s->be_tracked_table, s->be_tracked_counters);
                s->be_tracked_counters = NULL;
        }
 
@@ -68,6 +69,7 @@ static inline void session_store_counters(struct session *s)
                if (ptr)
                        stktable_data_cast(ptr, conn_cur)--;
                s->fe_tracked_counters->ref_cnt--;
+               stksess_kill_if_expired(s->fe_tracked_table, s->fe_tracked_counters);
                s->fe_tracked_counters = NULL;
        }
 }
@@ -87,6 +89,7 @@ static inline void session_stop_backend_counters(struct session *s)
        if (ptr)
                stktable_data_cast(ptr, conn_cur)--;
        s->be_tracked_counters->ref_cnt--;
+       stksess_kill_if_expired(s->be_tracked_table, s->be_tracked_counters);
        s->be_tracked_counters = NULL;
 }
 
index e702356fd93861aaae508a7bcde7ae044e233e4d..583e32acd1833aec71c20cd621139efdd9b442c8 100644 (file)
@@ -24,6 +24,8 @@
 #define _PROTO_STICK_TABLE_H
 
 #include <common/errors.h>
+#include <common/ticks.h>
+#include <common/time.h>
 #include <types/stick_table.h>
 
 #define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type))
@@ -34,6 +36,7 @@ extern struct stktable_key static_table_key;
 struct stksess *stksess_new(struct stktable *t, struct stktable_key *key);
 void stksess_setkey(struct stktable *t, struct stksess *ts, struct stktable_key *key);
 void stksess_free(struct stktable *t, struct stksess *ts);
+void stksess_kill(struct stktable *t, struct stksess *ts);
 
 int stktable_init(struct stktable *t);
 int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size);
@@ -122,4 +125,11 @@ static inline void *stktable_data_ptr(struct stktable *t, struct stksess *ts, in
        return (void *)ts + t->data_ofs[type];
 }
 
+/* kill an entry if it's expired and its ref_cnt is zero */
+static inline void stksess_kill_if_expired(struct stktable *t, struct stksess *ts)
+{
+       if (tick_is_expired(ts->expire, now_ms))
+               stksess_kill(t, ts);
+}
+
 #endif /* _PROTO_STICK_TABLE_H */
index a8c832ef86c0e7d282676094e3b367cf4a748651..a6ce0cf502998337bdd0a5853be2ff7f6ec1decb 100644 (file)
@@ -2921,8 +2921,10 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
 
        if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
                /* in case of abort, remove any refcount we might have set on an entry */
-               if (s->data_state == DATA_ST_LIST)
+               if (s->data_state == DATA_ST_LIST) {
                        s->data_ctx.table.entry->ref_cnt--;
+                       stksess_kill_if_expired(&s->data_ctx.table.proxy->table, s->data_ctx.table.entry);
+               }
                return 1;
        }
 
@@ -3080,11 +3082,14 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep)
 
                        eb = ebmb_next(&s->data_ctx.table.entry->key);
                        if (eb) {
+                               struct stksess *old = s->data_ctx.table.entry;
                                s->data_ctx.table.entry = ebmb_entry(eb, struct stksess, key);
+                               stksess_kill_if_expired(&s->data_ctx.table.proxy->table, old);
                                s->data_ctx.table.entry->ref_cnt++;
                                break;
                        }
 
+                       stksess_kill_if_expired(&s->data_ctx.table.proxy->table, s->data_ctx.table.entry);
                        s->data_ctx.table.proxy = s->data_ctx.table.proxy->next;
                        s->data_state = DATA_ST_INFO;
                        break;
index ccfd7b57929e671069a1fba342fde77ecdbf5685..78a0df7514876d649f7b7578464ef69cfa6da8e5 100644 (file)
@@ -42,6 +42,19 @@ void stksess_free(struct stktable *t, struct stksess *ts)
        pool_free2(t->pool, (void *)ts - t->data_size);
 }
 
+/*
+ * Kill an stksess (only if its ref_cnt is zero).
+ */
+void stksess_kill(struct stktable *t, struct stksess *ts)
+{
+       if (ts->ref_cnt)
+               return;
+
+       eb32_delete(&ts->exp);
+       ebmb_delete(&ts->key);
+       stksess_free(t, ts);
+}
+
 /*
  * Initialize or update the key in the sticky session <ts> present in table <t>
  * from the value present in <key>.