https://bugs.openldap.org/show_bug.cgi?id=9652
--- Comment #3 from Ondřej Kuzník ondra@mistotebe.net --- On Tue, Aug 31, 2021 at 11:17:17PM +0000, openldap-its@openldap.org wrote:
I'll take a stab at this.
On Aug 31, 2021, at 9:25 AM, openldap-its@openldap.org wrote:
First thoughts:
Assuming all backends will react identically (do we need to serialise *all* operations to do that?), there are two approaches to this:
- we send the operation to the first backend, when it's processed, second, etc.
That would mean that each incoming (upstream) operation takes as long to complete as the sum of all of the downstream operations, adding in timeouts for unreachable/failing downstream nodes. I don't see how that could be very useful.
Fair enough. We might still need to serialise operations to make sure conflicting (add/add conflicts, ...) requests are run in the same order everywhere?
(what happens if the client drops dead or abandons the request?)
I think it goes without saying that if the client sends an abandon request it's forwarded to each of the downstream servers and whatever, if anything, comes back from the primary server is sent back to the client.
Yes, this was mostly about the sequential case where the other operations have not been issued yet, not the simultaneous one.
- we send the operation to all backends in parallel
This seems to be more useful because an upstream operation only takes as long as the longest downstream operation takes to complete.
Irrespective of these, when we send the response back can vary too, assuming the first configured backend is the one we care about:
- forward the response as soon as we have the response from the first configured backend
- wait until all backends have finished with the request
I think that it's simpler to hold any responses until all backends have finished with the request. If the other case becomes interesting in practice, add it as a feature.
I agree that from the client's perspective it makes most sense, however we'd need to buffer the response at the junction point. That might get tricky but we'll have to reshape things so they do cope I guess.
Obvious limitations:
- operations that change the state of the connection, especially where the server is in charge of how that happens, are not going to work (SASL multi-step binds, TXNs, paging, etc. come to mind)
I don't see why that should be the case. Explain?
- in SASL binds, each server is likely to issue a different challenge, we have no way of transforming client's response to suit - similarly in other cases, the backends generate their cookies, this is high enough on the LDAP layer that we stand no chance of massaging those with just PDU reframing (lloadd's approach)
- different server capacity could mean we get to send the request to one server but the others will be over their configured limits/unavailable, we need to decide whether we (even can) go ahead with sending the request
I think that, at least for the first release, it's an exercise for the person setting things up to make sure things are reasonably well matched and we shouldn't worry about fixing that situation- perhaps just detecting and flagging it in the log.
Maybe, but this *will* come up in practice so we should keep it in mind and explain what that means in practice. Just like the fact we have to buffer upstream responses until clients are ready to receive them (leading to unbounded memory footprint) since there is no way to do per-operation pacing in LDAP - something that's proven really hard to explain without people understanding the principal design first.