OpenMetadata/conf
Pere Miquel Brull d156dd9b2b
fix: add concurrency control for OpenAI embedding HTTP requests (#26574)
* fix: add concurrency control for OpenAI embedding HTTP requests (#26392)

During ingestion, many virtual threads call OpenAIEmbeddingClient.embed()
concurrently, overwhelming the HTTP/2 connection's stream limit and causing
"too many concurrent streams" IOException. Add a Semaphore with a limit of
10 concurrent requests to throttle outbound HTTP calls to the OpenAI API.

Closes #26392

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move concurrency control from OpenAIEmbeddingClient to EmbeddingClient base class

Convert EmbeddingClient from interface to abstract class with a Semaphore-based
template method: embed() acquires the permit, delegates to doEmbed(), and releases
in a finally block. All implementations (OpenAI, Bedrock, DJL) now get uniform
concurrency bounds without managing it individually.

- Remove per-client semaphore/executor from OpenAIEmbeddingClient and BedrockEmbeddingClient
- Rename embed() -> doEmbed() in all implementations
- Update MockEmbeddingClient in tests to extend the abstract class

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add missing authenticator() override to HttpClient stub in test

The CI JDK requires authenticator() to be implemented when subclassing
HttpClient directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add missing connectTimeout() override to HttpClient stub in test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: make maxConcurrentEmbeddingRequests configurable via NLS config

Add maxConcurrentEmbeddingRequests to the NaturalLanguageSearchConfiguration
JSON schema (default 10, minimum 1). The EmbeddingClient base class reads the
value from config via a shared resolveMaxConcurrent() helper. All three clients
(OpenAI, Bedrock, DJL) pass the config value to super() so the semaphore limit
is tunable per deployment without code changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update generated TypeScript types

* fix: add maxConcurrentEmbeddingRequests to openmetadata.yaml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Address review: use dedicated executor in concurrency test, validate maxConcurrentRequests, add test coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix package-private constructor to properly chain concurrency limit to super

The 6-arg package-private constructor was implicitly calling super(), which
hardcoded the semaphore to DEFAULT_MAX_CONCURRENT_REQUESTS regardless of
configuration. Added a 7-arg constructor that accepts maxConcurrentRequests
and calls super(maxConcurrentRequests), with the 6-arg version chaining to
it using the default. Updated concurrency test to use a custom limit (3)
to verify configurability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-20 17:56:26 +01:00
..
openmetadata-env.sh License header update (#1498) 2021-12-01 12:46:28 +05:30
openmetadata-s3-logs.yaml Add logging endpoint into S3 (#22533) 2025-09-15 07:22:25 -07:00
openmetadata.yaml fix: add concurrency control for OpenAI embedding HTTP requests (#26574) 2026-03-20 17:56:26 +01:00
operations.yaml Update operations.yaml (#22231) 2025-07-08 16:06:55 -07:00
private_key.der feat(ui): login via email and password - Basic auth (#7558) 2022-09-23 16:05:54 +05:30
public_key.der feat(ui): login via email and password - Basic auth (#7558) 2022-09-23 16:05:54 +05:30