From b4384b7f0ecf3b47dd60acaf77636b679e3adc05 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 9 Feb 2018 10:27:55 +0100 Subject: [PATCH] winbind: Improve child selection This improves the situation when a client request blocks a winbind child. This might be a slow samlogon or lookupnames to a domain that's far away. With random selection of the child for new request coming in we could end up with a long queue when other, non-blocked children could serve those new requests. Choose the shortest queue. This is an immediate and simple fix. Step two will be to have a per-domain and not a per-child queue. Right now we're pre-selecting the check-out queue at Fry's randomly without looking at the queue length. With this change we're picking the shortest queue. The better change will be what Fry's really does: One central queue and red/green lights on the busy/free checkout counters. Signed-off-by: Volker Lendecke Reviewed-by: Andreas Schneider Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Mon Feb 12 19:51:35 CET 2018 on sn-devel-144 --- source3/winbindd/winbindd_dual.c | 36 +++++++++++++++----------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 33f1393e082..993166d82d9 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -248,33 +248,31 @@ static void wb_child_request_cleanup(struct tevent_req *req, DLIST_REMOVE(winbindd_children, state->child); } -static bool winbindd_child_busy(struct winbindd_child *child) -{ - return tevent_queue_length(child->queue) > 0; -} - -static struct winbindd_child *find_idle_child(struct winbindd_domain *domain) +struct winbindd_child *choose_domain_child(struct winbindd_domain *domain) { + struct winbindd_child *shortest = &domain->children[0]; + struct winbindd_child *current; int i; for (i=0; ichildren[i])) { - return &domain->children[i]; - } - } + size_t shortest_len, current_len; - return NULL; -} + current = &domain->children[i]; + current_len = tevent_queue_length(current->queue); -struct winbindd_child *choose_domain_child(struct winbindd_domain *domain) -{ - struct winbindd_child *result; + if (current_len == 0) { + /* idle child */ + return current; + } - result = find_idle_child(domain); - if (result != NULL) { - return result; + shortest_len = tevent_queue_length(shortest->queue); + + if (current_len < shortest_len) { + shortest = current; + } } - return &domain->children[rand() % lp_winbind_max_domain_connections()]; + + return shortest; } struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain) -- 2.34.1