[MEDIUM] Create updates tree on stick table to manage sync.
This commit is contained in:
parent
1e029aa965
commit
85e77c7f0d
@ -41,8 +41,8 @@ void stksess_kill(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_get_entry(struct stktable *table, struct stktable_key *key);
|
struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *key);
|
||||||
struct stksess *stktable_store(struct stktable *t, struct stksess *ts);
|
struct stksess *stktable_store(struct stktable *t, struct stksess *ts, int local);
|
||||||
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts);
|
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts, int local);
|
||||||
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 stksess *stktable_update_key(struct stktable *table, struct stktable_key *key);
|
struct stksess *stktable_update_key(struct stktable *table, struct stktable_key *key);
|
||||||
|
@ -130,16 +130,23 @@ struct stksess {
|
|||||||
unsigned int expire; /* session expiration date */
|
unsigned int expire; /* session expiration date */
|
||||||
unsigned int ref_cnt; /* reference count, can only purge when zero */
|
unsigned int ref_cnt; /* reference count, can only purge when zero */
|
||||||
struct eb32_node exp; /* ebtree node used to hold the session in expiration tree */
|
struct eb32_node exp; /* ebtree node used to hold the session in expiration tree */
|
||||||
|
struct eb32_node upd; /* ebtree node used to hold the update sequence tree */
|
||||||
struct ebmb_node key; /* ebtree node used to hold the session in table */
|
struct ebmb_node key; /* ebtree node used to hold the session in table */
|
||||||
/* WARNING! do not put anything after <keys>, it's used by the key */
|
/* WARNING! do not put anything after <keys>, it's used by the key */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* stick table */
|
/* stick table */
|
||||||
struct stktable {
|
struct stktable {
|
||||||
|
char *id; /* table id name */
|
||||||
struct eb_root keys; /* head of sticky session tree */
|
struct eb_root keys; /* head of sticky session tree */
|
||||||
struct eb_root exps; /* head of sticky session expiration tree */
|
struct eb_root exps; /* head of sticky session expiration tree */
|
||||||
|
struct eb_root updates; /* head of sticky updates sequence tree */
|
||||||
struct pool_head *pool; /* pool used to allocate sticky sessions */
|
struct pool_head *pool; /* pool used to allocate sticky sessions */
|
||||||
struct task *exp_task; /* expiration task */
|
struct task *exp_task; /* expiration task */
|
||||||
|
struct task *sync_task; /* sync task */
|
||||||
|
unsigned int update;
|
||||||
|
unsigned int localupdate;
|
||||||
unsigned long type; /* type of table (determines key format) */
|
unsigned long type; /* type of table (determines key format) */
|
||||||
size_t key_size; /* size of a key, maximum size in case of string */
|
size_t key_size; /* size of a key, maximum size in case of string */
|
||||||
unsigned int size; /* maximum number of sticky sessions in table */
|
unsigned int size; /* maximum number of sticky sessions in table */
|
||||||
|
@ -1077,7 +1077,7 @@ int process_sticking_rules(struct session *s, struct buffer *req, int an_bit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stktable_touch(rule->table.t, ts);
|
stktable_touch(rule->table.t, ts, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rule->flags & STK_IS_STORE) {
|
if (rule->flags & STK_IS_STORE) {
|
||||||
@ -1172,11 +1172,11 @@ 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, ts);
|
stktable_touch(s->store[i].table, ts, 1);
|
||||||
stksess_free(s->store[i].table, s->store[i].ts);
|
stksess_free(s->store[i].table, s->store[i].ts);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ts = stktable_store(s->store[i].table, s->store[i].ts);
|
ts = stktable_store(s->store[i].table, s->store[i].ts, 1);
|
||||||
|
|
||||||
s->store[i].ts = NULL;
|
s->store[i].ts = NULL;
|
||||||
ptr = stktable_data_ptr(s->store[i].table, ts, STKTABLE_DT_SERVER_ID);
|
ptr = stktable_data_ptr(s->store[i].table, ts, STKTABLE_DT_SERVER_ID);
|
||||||
|
@ -51,6 +51,7 @@ void stksess_kill(struct stktable *t, struct stksess *ts)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
eb32_delete(&ts->exp);
|
eb32_delete(&ts->exp);
|
||||||
|
eb32_delete(&ts->upd);
|
||||||
ebmb_delete(&ts->key);
|
ebmb_delete(&ts->key);
|
||||||
stksess_free(t, ts);
|
stksess_free(t, ts);
|
||||||
}
|
}
|
||||||
@ -80,6 +81,7 @@ static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
|
|||||||
ts->ref_cnt = 0;
|
ts->ref_cnt = 0;
|
||||||
ts->key.node.leaf_p = NULL;
|
ts->key.node.leaf_p = NULL;
|
||||||
ts->exp.node.leaf_p = NULL;
|
ts->exp.node.leaf_p = NULL;
|
||||||
|
ts->upd.node.leaf_p = NULL;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +139,7 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch)
|
|||||||
|
|
||||||
/* session expired, trash it */
|
/* session expired, trash it */
|
||||||
ebmb_delete(&ts->key);
|
ebmb_delete(&ts->key);
|
||||||
|
eb32_delete(&ts->upd);
|
||||||
stksess_free(t, ts);
|
stksess_free(t, ts);
|
||||||
batched++;
|
batched++;
|
||||||
}
|
}
|
||||||
@ -204,12 +207,12 @@ struct stksess *stktable_update_key(struct stktable *table, struct stktable_key
|
|||||||
|
|
||||||
ts = stktable_lookup_key(table, key);
|
ts = stktable_lookup_key(table, key);
|
||||||
if (likely(ts))
|
if (likely(ts))
|
||||||
return stktable_touch(table, ts);
|
return stktable_touch(table, ts, 1);
|
||||||
|
|
||||||
/* entry does not exist, initialize a new one */
|
/* entry does not exist, initialize a new one */
|
||||||
ts = stksess_new(table, key);
|
ts = stksess_new(table, key);
|
||||||
if (likely(ts))
|
if (likely(ts))
|
||||||
stktable_store(table, ts);
|
stktable_store(table, ts, 1);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,13 +238,26 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts)
|
|||||||
/* Update the expiration timer for <ts> but do not touch its expiration node.
|
/* Update the expiration timer for <ts> but do not touch its expiration node.
|
||||||
* The table's expiration timer is updated if set.
|
* The table's expiration timer is updated if set.
|
||||||
*/
|
*/
|
||||||
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts)
|
struct stksess *stktable_touch(struct stktable *t, struct stksess *ts, int local)
|
||||||
{
|
{
|
||||||
|
struct eb32_node * eb;
|
||||||
ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
|
ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
|
||||||
if (t->expire) {
|
if (t->expire) {
|
||||||
t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
|
t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
|
||||||
task_queue(t->exp_task);
|
task_queue(t->exp_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t->sync_task && local) {
|
||||||
|
ts->upd.key = ++t->update;
|
||||||
|
t->localupdate = t->update;
|
||||||
|
eb32_delete(&ts->upd);
|
||||||
|
eb = eb32_insert(&t->updates, &ts->upd);
|
||||||
|
if (eb != &ts->upd) {
|
||||||
|
eb32_delete(eb);
|
||||||
|
eb32_insert(&t->updates, &ts->upd);
|
||||||
|
}
|
||||||
|
task_wakeup(t->sync_task, TASK_WOKEN_MSG);
|
||||||
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,10 +265,10 @@ struct stksess *stktable_touch(struct stktable *t, struct stksess *ts)
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
struct stksess *stktable_store(struct stktable *t, struct stksess *ts)
|
struct stksess *stktable_store(struct stktable *t, struct stksess *ts, int local)
|
||||||
{
|
{
|
||||||
ebmb_insert(&t->keys, &ts->key, t->key_size);
|
ebmb_insert(&t->keys, &ts->key, t->key_size);
|
||||||
stktable_touch(t, ts);
|
stktable_touch(t, ts, local);
|
||||||
ts->exp.key = ts->expire;
|
ts->exp.key = ts->expire;
|
||||||
eb32_insert(&t->exps, &ts->exp);
|
eb32_insert(&t->exps, &ts->exp);
|
||||||
return ts;
|
return ts;
|
||||||
@ -275,10 +291,10 @@ struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *
|
|||||||
ts = stksess_new(table, key);
|
ts = stksess_new(table, key);
|
||||||
if (!ts)
|
if (!ts)
|
||||||
return NULL;
|
return NULL;
|
||||||
stktable_store(table, ts);
|
stktable_store(table, ts, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
stktable_touch(table, ts);
|
stktable_touch(table, ts, 1);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +355,7 @@ static int stktable_trash_expired(struct stktable *t)
|
|||||||
|
|
||||||
/* session expired, trash it */
|
/* session expired, trash it */
|
||||||
ebmb_delete(&ts->key);
|
ebmb_delete(&ts->key);
|
||||||
|
eb32_delete(&ts->upd);
|
||||||
stksess_free(t, ts);
|
stksess_free(t, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user