]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] Create updates tree on stick table to manage sync.
authorEmeric Brun <ebrun@exceliance.fr>
Thu, 23 Sep 2010 16:16:52 +0000 (18:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 11 Nov 2010 08:29:08 +0000 (09:29 +0100)
include/proto/stick_table.h
include/types/stick_table.h
src/session.c
src/stick_table.c

index 4365fcdfc7c7e43d2dc618c959001eb5162d28eb..5da327ca648bc221782cff701c24788fe234eca1 100644 (file)
@@ -41,8 +41,8 @@ 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);
 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_touch(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, int local);
 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_update_key(struct stktable *table, struct stktable_key *key);
index b835066074f25ac7db14435a43101e5e2446d31d..cb3fb3b35d0895153bc388c356607b875413a8d2 100644 (file)
@@ -130,16 +130,23 @@ struct stksess {
        unsigned int expire;      /* session expiration date */
        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 upd;     /* ebtree node used to hold the update sequence tree */
        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 */
 };
 
+
 /* stick table */
 struct stktable {
+       char *id;                 /* table id name */
        struct eb_root keys;      /* head of sticky session 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 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) */
        size_t key_size;          /* size of a key, maximum size in case of string */
        unsigned int size;        /* maximum number of sticky sessions in table */
index 4d2b6054e075f8f362df6125a2f9a5084bdc188c..5432266cd7bb86774ac25b4676097d3d900888fc 100644 (file)
@@ -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) {
@@ -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);
                if (ts) {
                        /* 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);
                }
                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;
                ptr = stktable_data_ptr(s->store[i].table, ts, STKTABLE_DT_SERVER_ID);
index bf8df0f44704a8b3a96f091010969afda3ac9af6..fb75d3f5d0969f7e5433d1a1e925fd4434997c2e 100644 (file)
@@ -51,6 +51,7 @@ void stksess_kill(struct stktable *t, struct stksess *ts)
                return;
 
        eb32_delete(&ts->exp);
+       eb32_delete(&ts->upd);
        ebmb_delete(&ts->key);
        stksess_free(t, ts);
 }
@@ -80,6 +81,7 @@ static struct stksess *stksess_init(struct stktable *t, struct stksess * ts)
        ts->ref_cnt = 0;
        ts->key.node.leaf_p = NULL;
        ts->exp.node.leaf_p = NULL;
+       ts->upd.node.leaf_p = NULL;
        return ts;
 }
 
@@ -137,6 +139,7 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch)
 
                /* session expired, trash it */
                ebmb_delete(&ts->key);
+               eb32_delete(&ts->upd);
                stksess_free(t, ts);
                batched++;
        }
@@ -204,12 +207,12 @@ struct stksess *stktable_update_key(struct stktable *table, struct stktable_key
 
        ts = stktable_lookup_key(table, key);
        if (likely(ts))
-               return stktable_touch(table, ts);
+               return stktable_touch(table, ts, 1);
 
        /* entry does not exist, initialize a new one */
        ts = stksess_new(table, key);
        if (likely(ts))
-               stktable_store(table, ts);
+               stktable_store(table, ts, 1);
        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.
  * 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));
        if (t->expire) {
                t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next);
                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;
 }
 
@@ -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
  * 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);
-       stktable_touch(t, ts);
+       stktable_touch(t, ts, local);
        ts->exp.key = ts->expire;
        eb32_insert(&t->exps, &ts->exp);
        return ts;
@@ -275,10 +291,10 @@ struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *
                ts = stksess_new(table, key);
                if (!ts)
                        return NULL;
-               stktable_store(table, ts);
+               stktable_store(table, ts, 1);
        }
        else
-               stktable_touch(table, ts);
+               stktable_touch(table, ts, 1);
        return ts;
 }
 
@@ -339,6 +355,7 @@ static int stktable_trash_expired(struct stktable *t)
 
                /* session expired, trash it */
                ebmb_delete(&ts->key);
+               eb32_delete(&ts->upd);
                stksess_free(t, ts);
        }