mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-18 19:50:54 +00:00
[BUG] task: fix handling of duplicate keys
A bug was introduced with the ebtree-based scheduler. It seldom causes some timeouts to last longer than required if they hit an expiration date which is the same as the last queued date, is also part of a duplicate tree without being the top of the tree. In this case, the task will not be expired until after the duplicate tree has been flushed. It is easier to reproduce by setting a very short client timeout (1s) and sending connections and waiting for them to expire with the 408 status. Then in parallel, inject at about 1kh/s. The bug causes the connections to sometimes wait longer than 1s before timing out. The cause was the use of eb_insert_dup() on wrong nodes, as this function is designed to work only on the top of the dup tree. The solution consists in updating last_timer only when its bit is -1, and using it only if its bit is still -1 (top of a dup tree). The fix has not reduced performance because it only fixes the case where this bug could fire, which is extremely rare.
This commit is contained in:
parent
39af0f663d
commit
1b8ca663a4
@ -180,15 +180,18 @@ struct task *task_queue(struct task *task)
|
||||
|
||||
if (likely(last_timer &&
|
||||
last_timer->eb.key == task->eb.key &&
|
||||
last_timer->eb.node.node_p)) {
|
||||
last_timer->eb.node.node_p &&
|
||||
last_timer->eb.node.bit == -1)) {
|
||||
/* Most often, last queued timer has the same expiration date, so
|
||||
* if it's not queued at the root, let's queue a dup directly there.
|
||||
* Note that we can only use dups at the dup tree's root (bit==-1).
|
||||
*/
|
||||
eb_insert_dup(&last_timer->eb.node, &task->eb.node);
|
||||
return task;
|
||||
}
|
||||
eb32_insert(&timers[ticks_to_tree(task->eb.key)], &task->eb);
|
||||
last_timer = task;
|
||||
if (task->eb.node.bit == -1)
|
||||
last_timer = task; /* we only want dup a tree's root */
|
||||
return task;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user