[MEDIUM] stick_table: separate storage and update of session entries

When an entry already exists, we just need to update its expiration
timer. Let's have a dedicated function for that instead of spreading
open code everywhere.

This change also ensures that an update of an existing sticky session
really leads to an update of its expiration timer, which was apparently
not the case till now. This point needs to be checked in 1.4.
This commit is contained in:
Willy Tarreau 2010-06-06 17:58:34 +02:00
parent a975b8f381
commit cb18364ca7
4 changed files with 19 additions and 13 deletions

View File

@ -37,6 +37,7 @@ void stksess_free(struct stktable *t, struct stksess *ts);
int stktable_init(struct stktable *t); int stktable_init(struct stktable *t);
int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size); int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size);
struct stksess *stktable_store(struct stktable *t, struct stksess *ts); struct stksess *stktable_store(struct stktable *t, struct stksess *ts);
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts);
struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts); struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts);
struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key); struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key);
struct stktable_key *stktable_fetch_key(struct proxy *px, struct session *l4, struct stktable_key *stktable_fetch_key(struct proxy *px, struct session *l4,

View File

@ -1086,12 +1086,8 @@ acl_fetch_src_update_count(struct proxy *px, struct session *l4, void *l7, int d
return 0; return 0;
stktable_store(&px->table, ts); stktable_store(&px->table, ts);
} }
else if (px->table.expire) { else
/* if entries can expire, let's update the entry and the table */ stktable_touch(&px->table, ts);
ts->expire = tick_add(now_ms, MS_TO_TICKS(px->table.expire));
px->table.exp_task->expire = px->table.exp_next = tick_first(ts->expire, px->table.exp_next);
task_queue(px->table.exp_task);
}
ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CUM); ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CUM);
if (!ptr) if (!ptr)

View File

@ -1057,6 +1057,7 @@ int process_store_rules(struct session *s, struct buffer *rep, int an_bit)
ts = stktable_lookup(s->store[i].table, s->store[i].ts); ts = stktable_lookup(s->store[i].table, s->store[i].ts);
if (ts) { if (ts) {
/* the entry already existed, we can free ours */ /* the entry already existed, we can free ours */
stktable_touch(s->store[i].table, s->store[i].ts);
stksess_free(s->store[i].table, s->store[i].ts); stksess_free(s->store[i].table, s->store[i].ts);
} }
else else

View File

@ -189,6 +189,19 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts)
return ebmb_entry(eb, struct stksess, key); return ebmb_entry(eb, struct stksess, key);
} }
/* Update the expiration timer for <ts> but do not touch its expiration node.
* The table's expiration timer is updated if set.
*/
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts)
{
ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
if (t->expire) {
t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
task_queue(t->exp_task);
}
return ts;
}
/* Insert new sticky session <ts> in the table. It is assumed that it does not /* Insert new sticky session <ts> in the table. It is assumed that it does not
* yet exist (the caller must check this). The table's timeout is updated if it * yet exist (the caller must check this). The table's timeout is updated if it
* is set. <ts> is returned. * is set. <ts> is returned.
@ -196,14 +209,9 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts)
struct stksess *stktable_store(struct stktable *t, struct stksess *ts) struct stksess *stktable_store(struct stktable *t, struct stksess *ts)
{ {
ebmb_insert(&t->keys, &ts->key, t->key_size); ebmb_insert(&t->keys, &ts->key, t->key_size);
stktable_touch(t, ts);
ts->exp.key = ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); ts->exp.key = ts->expire;
eb32_insert(&t->exps, &ts->exp); eb32_insert(&t->exps, &ts->exp);
if (t->expire) {
t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
task_queue(t->exp_task);
}
return ts; return ts;
} }