*/
static void fwlc_srv_reposition(struct server *s, int locked)
{
+ unsigned int inflight = _HA_ATOMIC_LOAD(&s->served) + _HA_ATOMIC_LOAD(&s->nbpend);
+ unsigned int new_key = inflight ? (inflight + 1) * SRV_EWGHT_MAX / s->cur_eweight : 0;
+
+ /* some calls will be made for no change (e.g connect_server() after
+ * assign_server(). Let's check that first.
+ */
+ if (s->lb_node.node.leaf_p && s->lb_node.key == new_key)
+ return;
+
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
if (s->lb_tree) {
- fwlc_dequeue_srv(s);
- fwlc_queue_srv(s, s->cur_eweight);
+ /* we might have been waiting for a while on the lock above
+ * so it's worth testing again because other threads are very
+ * likely to have released a connection or taken one leading
+ * to our target value (50% of the case in measurements).
+ */
+ inflight = _HA_ATOMIC_LOAD(&s->served) + _HA_ATOMIC_LOAD(&s->nbpend);
+ new_key = inflight ? (inflight + 1) * SRV_EWGHT_MAX / s->cur_eweight : 0;
+ if (!s->lb_node.node.leaf_p || s->lb_node.key != new_key) {
+ eb32_delete(&s->lb_node);
+ s->lb_node.key = new_key;
+ eb32_insert(s->lb_tree, &s->lb_node);
+ }
}
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &s->proxy->lbprm.lock);
}