fix(embeddings): bound the connection separately from the read - #346
Open
bakiburakogun wants to merge 1 commit into
Open
fix(embeddings): bound the connection separately from the read#346bakiburakogun wants to merge 1 commit into
bakiburakogun wants to merge 1 commit into
Conversation
The embedding request passed a single timeout value, so nothing bounded establishing the connection. When the TLS handshake to the embedding service stalls — TCP connects, the handshake never completes — the worker waits in recv for the whole request_timeout, 1800 s by default. That stops more than the one request: files_indexing_thread waits for every worker of the batch, so one stalled handshake holds up the batch and no further queue items are fetched until it returns. Give the connection its own bound so the retry already implemented in _get_embedding() can land on a healthy connection. On our deployment this took worker durations from ~300 s, all finishing together at the timeout, to 1.4-85 s, and indexing from 5.2 to 60-65 documents per minute. Fixes nextcloud#345 Signed-off-by: Baki Burak Öğün <63836730+bakiburakogun@users.noreply.github.com>
Author
|
Please hold this one for a moment — see #345 (comment). Running with this change I still caught workers stuck for 28 minutes in the HTTP/2 handshake exchange ( Forcing HTTP/1.1 for the embedding request removed the stall on our four instances (1 of 4 nodes working before, 4 of 4 after). Happy to extend this PR with that, or to make the protocol configurable instead — whichever shape you prefer. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #345
Problem
_get_embedding()passed a single value as the timeout, so nothing bounded establishing the connection — only reading the response. When the TLS handshake to the embedding service stalls (TCP connects, the handshake never completes) the worker waits inrecvfor the wholerequest_timeout, which defaults to 1800 s.It costs more than the one request:
files_indexing_threaddispatches a batch across workers and then waits for all of them, so a single stalled handshake holds up the batch and no further queue items are fetched until it returns. In the logs that shows up as every worker of a batch finishing at the same moment, at the timeout, instead of at its own pace.py-spy on a stalled worker put it inside
connect(), in the handshake exchange:Change
Add
HTTP_CONNECT_TIMEOUTnext to the existingTCP_CONNECT_TIMEOUTand pass(connect, read)toniquests.post. The read timeout is unchanged, so slow embedding responses are still tolerated exactly as before; only a connection that will not come up now fails quickly, and the retry already implemented in_get_embedding()can land on a healthy connection.15 s is generous relative to what a working handshake costs — the same endpoint from the same container answers a one-text request in 0.28 s — while being far below the read timeout.
Testing
Deployed on Nextcloud 34.0.3, four backend instances, external embedding service. Same corpus, same nodes, nothing else changed:
Sustained over the following hours at 60–65 documents/min. Before the change the run looked stopped rather than slow, which is what sent us looking for a hang in the first place.