Skip to content

Commit 280028c

Browse files
authored
docs(changelog): add v4.7.1 and v4.7.2 sections (opensearch-project#1005)
1 parent 7311cec commit 280028c

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
88

99
- Fix an unbounded connection/heap leak in node discovery when the cluster has a dedicated cluster manager (`cluster_manager` role with no work roles). The node was filtered out of the `allConns` inventory while the router received the unfiltered added/removed diffs, so `findConnectionByURL` never matched it: a new `*Connection` was created every discovery cycle and the stale one was never evicted, accumulating without bound in the round-robin fallback pool whose `checkDead` health checks repopulated a per-connection `poolRegistry` `sync.Map` each cycle (leak rate scaled with discovery frequency). `allConns` is now the full connection inventory so discovery reuses and evicts symmetrically, and dedicated cluster managers are excluded at request-routing selection instead: `RoundRobinPolicy` skips them in its `DiscoveryUpdate` add path and `multiServerPool.Next()` skips them during selection (including the no-router fallback), both gated on `IncludeDedicatedClusterManagers`. Discovery still bootstraps against a dedicated cluster manager seed via the seed-fallback pool ([#1003](https://github.com/opensearch-project/opensearch-go/pull/1003))
1010

11+
## [4.7.2]
12+
13+
### Fixed
14+
15+
- Fix data races on `multiServerPool` lock-guarded fields: `activeListCap`, `warmupRounds`, `warmupSkipCount`, and `healthCheck` were de-facto guarded by `cp.mu` but declared at the top level of the struct, allowing accesses from `snapshot()`, `createOrUpdateMultiNodePoolWithLock`, and `updateConnectionPool` to escape the lock without looking wrong. All four fields are now nested inside the `mu` embedded struct so every access is spelled `cp.mu.<field>` and the guard is structural. `snapshot()` reads `activeListCap` under the read lock; `createOrUpdateMultiNodePoolWithLock` runs fully under `allConnsPool.mu` with per-connection `conn.mu` taken inside the loop; `updateConnectionPool`'s RTT-probe scheduling loop reads `healthCheck` under the read lock. `recalculateWarmupParams`/`getWarmupParams` renamed `*WithLock` to document that all callers now hold the pool lock ([#995](https://github.com/opensearch-project/opensearch-go/pull/995))
16+
- Fix removed `opensearch.BuildRequest` reference in v4 upgrade guide ([#978](https://github.com/opensearch-project/opensearch-go/pull/978))
17+
18+
### Dependencies
19+
20+
- Bump `actions/setup-go` to 7.0.0 and `actions/setup-java` to 5.6.0 ([#993](https://github.com/opensearch-project/opensearch-go/pull/993))
21+
22+
## [4.7.1]
23+
24+
### Changed
25+
26+
- Add a first-class container-provider abstraction to the test harness `Makefile`. `CONTAINER_PROVIDER` is auto-detected by CLI presence in the order Colima -> Rancher Desktop (`rdctl`) -> Docker, and overridable with `CONTAINER_PROVIDER=colima|rancher|docker`. Selecting a provider pins the docker context (`colima` / `rancher-desktop`; the Docker provider leaves the active context alone, and a pre-set `DOCKER_CONTEXT` in the environment is respected), resolves the CLI runtime `$(CTR)` (now `docker` by default for every provider, with `CONTAINER_RUNTIME=nerdctl` as an advanced override), ensures the backing VM/daemon is running via the new `cluster.provider.ensure` target (wired into `cluster.start`), and sets `vm.max_map_count` through the provider's VM (`colima ssh` / `rdctl shell`) or a privileged helper container. Previously `$(CTR)` preferred `nerdctl` whenever it was on `PATH`, so a Rancher-installed `nerdctl` could hijack a Colima session. `make cluster.runtime` now reports the detected provider, docker context, and runtime ([#968](https://github.com/opensearch-project/opensearch-go/pull/968))
27+
28+
### Fixed
29+
30+
- Fix two gaps in the seed-fallback routing path left by [#952](https://github.com/opensearch-project/opensearch-go/pull/952)/[#954](https://github.com/opensearch-project/opensearch-go/pull/954)/[#956](https://github.com/opensearch-project/opensearch-go/pull/956): `RoundRobinPolicy.Eval` went straight to `pool.Next()` without checking its own `psEnabled` bit (unlike `CoordinatorPolicy.Eval` and `RolePolicy.Eval`), so a dead but unverified discovered node was returned as a zombie producing a transport error — not `ErrNoConnections` — and the seed fallback never fired; `PolicyChain.Eval` also did not gate on `IsEnabled()` even though `PolicyChain.Route` did, leaving the nested chain inside `IfEnabledPolicy.Eval` unguarded. Both gaps are now closed: `RoundRobinPolicy.Eval` returns no connection when its enabled bit is clear, and `PolicyChain.Eval` skips not-enabled sub-policies, matching the behavior of every other leaf policy and `Route` ([#966](https://github.com/opensearch-project/opensearch-go/pull/966))
31+
- Fix node discovery serving unverified discovered nodes as last-resort zombies and bypassing the seed-URL fallback when `publish_address` is unroutable from the client (NAT'd clusters, Kubernetes stack clusters in CI). `multiServerPool.nextFallbackWithLock` previously returned any dead connection unconditionally; a never-health-checked discovered node was handed out and failed with a transport error (`connection reset by peer` / `no route to host`), which is not `ErrNoConnections` so the seed fallback never fired. Introduce `lcViable`, a monotonic lifecycle bit meaning "proven directly reachable at least once" — seeds are born viable; discovered nodes earn it on their first successful health check or request. `availableForRouting()` now gates on `lcViable` so a dead list holding only never-verified discovered nodes yields `ErrNoConnections` and the request cascades to the seed-URL fallback ([#973](https://github.com/opensearch-project/opensearch-go/pull/973))
32+
1133
## [4.7.0]
1234

1335
### Added
@@ -172,7 +194,6 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
172194

173195
### Changed
174196

175-
- Add a first-class container-provider abstraction to the test harness `Makefile`. `CONTAINER_PROVIDER` is auto-detected by CLI presence in the order Colima -> Rancher Desktop (`rdctl`) -> Docker, and overridable with `CONTAINER_PROVIDER=colima|rancher|docker`. Selecting a provider pins the docker context (`colima` / `rancher-desktop`; the Docker provider leaves the active context alone, and a pre-set `DOCKER_CONTEXT` in the environment is respected), resolves the CLI runtime `$(CTR)` (now `docker` by default for every provider, with `CONTAINER_RUNTIME=nerdctl` as an advanced override), ensures the backing VM/daemon is running via the new `cluster.provider.ensure` target (wired into `cluster.start`), and sets `vm.max_map_count` through the provider's VM (`colima ssh` / `rdctl shell`) or a privileged helper container. Previously `$(CTR)` preferred `nerdctl` whenever it was on `PATH`, so a Rancher-installed `nerdctl` could hijack a Colima session. `make cluster.runtime` now reports the detected provider, docker context, and runtime
176197
- Connection dead/overloaded timestamps (`deadSince`/`overloadedAt`) are now lock-free `atomic.Int64` values. `buildConnectionMetric` no longer locks each connection to read them, removing the dominant metrics-snapshot lock contention against the per-request writers. No public API change; `EnableMetrics` behavior is unchanged. ([#892](https://github.com/opensearch-project/opensearch-go/issues/892))
177198
- Per-request transport metrics (`requests`, `failures`, responses-by-status) are now always collected via lock-free atomics, independent of `EnableMetrics`. `EnableMetrics` now gates only the detailed-metrics snapshot (per-connection, per-policy, and router state returned by `Metrics()`). The responses-by-status counter moved from a mutex-guarded map to a lock-free atomic array. `Metrics()` no longer returns an error when metrics are disabled — it always returns the per-request counters (callers that branched on `if err != nil` for the disabled case should drop that check). ([#891](https://github.com/opensearch-project/opensearch-go/issues/891))
178199
- **BREAKING**: `opensearch.Request` interface signature changed from `GetRequest() (*http.Request, error)` to `GetRequest(method string) (*http.Request, error)`. The HTTP method is now caller-provided rather than hardcoded per operation, enabling correct method selection for operations that support multiple HTTP methods (e.g. search supports both GET and POST). This only affects code that implements or calls `GetRequest` directly; standard usage through client methods (e.g. `client.Search(ctx, req)`) is unaffected ([#650](https://github.com/opensearch-project/opensearch-go/issues/650))
@@ -221,9 +242,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
221242

222243
### Fixed
223244

224-
- Fix a data race on the multi-server pool's warmup fields in the node-discovery path: `createOrUpdateMultiNodePoolWithLock` recalculated warmup parameters, partitioned the ready list, and wrote `mu.activeCount` after releasing the pool write lock, touching `mu`-guarded fields (`activeListCap`, `warmupRounds`, `warmupSkipCount`, `activeCount`) that `resurrectWithLock` reads and writes under `pool.mu`. The caller holds the transport lock, which serializes this against `metrics.snapshot()` but not against resurrection. The whole section now runs under `allConnsPool.mu`, with per-connection `conn.mu` taken inside the loop (the `pool.mu` -> `conn.mu` ordering already used by `deferredStandbyPromotion`). `recalculateWarmupParams`/`getWarmupParams` are renamed `*WithLock` to document that every caller now holds the pool lock (the discovery path was the last that did not)
225245
- Fix node discovery hijacking the request stream with unverified, unreachable discovered nodes and masking the user-supplied seed-URL fallback. When discovered `publish_address` values are unroutable from the client (NAT'd or misconfigured clusters, e.g. a Kubernetes stack cluster in CI), a freshly discovered but never-health-checked node could be served to requests as a zombie -- failing every request with `no route to host` -- instead of returning `ErrNoConnections` and cascading to the reachable seed URL. Connections are now considered available for routing only when they are a user-supplied seed (assumed reachable) or a discovered node confirmed reachable, and every routing policy and pool (round-robin, role, coordinator, index/doc router, single-server, and multi-server pools) consistently honors that gate on both the enabled-bit and connection-selection paths, so the seed fallback serves requests until a discovered node health-checks clean ([#952](https://github.com/opensearch-project/opensearch-go/pull/952), [#954](https://github.com/opensearch-project/opensearch-go/pull/954), [#956](https://github.com/opensearch-project/opensearch-go/pull/956))
226-
- Fix a data race (reported by the race detector in `TestClientCustomTransport`) between `multiServerPool.snapshot()` and node discovery: `snapshot()` read `activeListCap` after releasing the pool read lock, while `recalculateWarmupParams` writes it under the write lock during `DiscoveryUpdate`. `activeListCap`, `warmupRounds`, and `warmupSkipCount` were guarded by the pool lock only by convention (declared at the top level of the struct), which let the unlocked read look correct; they are now nested inside the pool's lock-guarded `mu` struct so every access is spelled `cp.mu.<field>` and the guard is structural, and `snapshot()` reads `activeListCap` while holding the read lock. For the same reason `healthCheck` is moved under `mu` (it is rewritten by `updateConnectionPool` on pool reuse); this also surfaced one discovery-path read of `healthCheck` that had escaped the lock, now taken under the read lock
227246
- Fix `BulkIndexerStats.NumAdded` overcounting items rejected by `Add()` when the caller's context is cancelled before the item could be enqueued: increment `NumAdded` only after the queue accepts the item, and add a new `BulkAddFailCount` counter for items dropped on the `<-ctx.Done()` branch. Migrate `bulkIndexerStats` fields to `sync/atomic.Uint64` typed values so future direct access is a compile-time error rather than a `-race`-only finding ([#783](https://github.com/opensearch-project/opensearch-go/issues/783))
228247
- Fix `opensearchtransport.Client.setReqGlobalHeader` comparing the per-request header value against the global header name, so a request-level header never suppressed the matching global default and both were sent ([#859](https://github.com/opensearch-project/opensearch-go/pull/859))
229248
- Fix gzip buffer-pool nil poisoning on compress error: `gzipCompressor.compress` returned `(nil, err)` while the caller's deferred `collectBuffer` still ran, putting a typed-nil `*bytes.Buffer` into the `sync.Pool` that panics on the next `Get().Reset()` ([#859](https://github.com/opensearch-project/opensearch-go/pull/859))
@@ -662,6 +681,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
662681

663682
[4.7.3]: https://github.com/opensearch-project/opensearch-go/compare/v4.7.2...v4.7.3
664683
[4.7.2]: https://github.com/opensearch-project/opensearch-go/compare/v4.7.1...v4.7.2
684+
[4.7.1]: https://github.com/opensearch-project/opensearch-go/compare/v4.7.0...v4.7.1
665685
[4.7.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.6.0...v4.7.0
666686
[4.6.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.5.0...v4.6.0
667687
[4.5.0]: https://github.com/opensearch-project/opensearch-go/compare/v4.4.0...v4.5.0

0 commit comments

Comments
 (0)