Preserve cached configuration when refresh fails
Build replacement appenders and thresholds before installing them and advancing the local version. Release partial replacements and old caches outside the configuration lock. In order to make the `ensureFreshness` version check as cheap as posible and only incur overhead when we actually need to update the local cache, isolate the refresh logic in a separate scope to prevent initialization and cleanup of temporary variables when the version has not changed Add regression coverage for repeated clone failures, cache preservation, cleanup, and retry without another configuration change. Update documentation to reflect the remaining freshness issue.
This commit is contained in:
1 parent
d5e3b9c301
commit
14e71c72ca
4 files changed
+99
-32
No files matched your search
@@ -314,9 +314,10 @@ loggers or configuring each worker separately.
|
||||
|
||||
> [!NOTE]
|
||||
> Thread-safety work is still in progress. Custom state and captured
|
||||
> formatters must follow the ownership rules above. Runtime configuration
|
||||
> refresh and concurrent local-time timestamp construction still have known
|
||||
> failures. Nim 2.2.10 also produces sanitizer reports in its default allocator
|
||||
> formatters must follow the ownership rules above. Standalone `isEnabled()`
|
||||
> checks do not yet notice changed namespace thresholds, and concurrent
|
||||
> local-time timestamp construction still has a known failure.
|
||||
> Nim 2.2.10 also produces sanitizer reports in its default allocator
|
||||
> during some cross-thread allocation patterns. See
|
||||
> [the regression tests](tests/README.md) for the remaining work.
|
||||
|
||||
@@ -375,9 +376,10 @@ let handle = localLogSvc.service
|
||||
```
|
||||
|
||||
Configuration methods remain available on both types. Shared handles contain no
|
||||
cache; `ensureFreshness(handle)` only validates initialization, and
|
||||
`handle.appenders()` clones the current shared configuration. Local services
|
||||
retain their per-thread caches and refresh them through `ensureFreshness(local)`.
|
||||
cache; `handle.appenders()` clones the current shared configuration.
|
||||
`ensureFreshness` applies only to *ThreadLocalLogService*, which maintains a
|
||||
per-thread cache. Calls to `ensureFreshness(handle)` must be removed or changed
|
||||
to refresh the relevant local service when migrating to version 3.0.0.
|
||||
|
||||
*ThreadLocalLogService* is the object that users are expected to interact with
|
||||
during regular operation and support both the configuration functions of
|
||||
@@ -450,8 +452,10 @@ proc ensureFreshness*(ls: ThreadLocalLogService) =
|
||||
|
||||
# Only acquire lock and copy if versions differ
|
||||
withLock ls.shared.lock:
|
||||
ls.configVersion = ls.shared.configVersion.load
|
||||
# Sync state...
|
||||
let version = ls.shared.configVersion.load()
|
||||
# Build the complete replacement cache, then install it after success.
|
||||
# If building raises, preserve the previous cache and version for retry.
|
||||
ls.configVersion = version
|
||||
```
|
||||
|
||||
Goals/Motivation:
|
||||
|
||||
Reference in new issue
Block a user