fix(cache): refuse configuration written under a key 2.0 removed, and document the 1.x to 2.0 upgrade - #180
fix(cache): refuse configuration written under a key 2.0 removed, and document the 1.x to 2.0 upgrade#180cosmin-staicu wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The migration documentation contains incorrect compatibility, NSubstitute, and dependency-floor claims.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds safeguards and migration guidance for upgrading from 1.x to 2.0.
Changes:
- Rejects removed configuration keys during registration.
- Adds comprehensive upgrade documentation and navigation links.
- Corrects dependency and mocking guidance in the changelog.
File summaries
| File | Description |
|---|---|
RemovedConfigurationKeysTests.cs |
Tests removed-key validation. |
RemovedConfigurationKeys.cs |
Detects removed configuration keys. |
RedisCollectionExtensions.cs |
Validates Redis connection configuration. |
InMemoryRedisCollectionExtensions.cs |
Validates multilayer Redis configuration. |
InMemoryCollectionExtensions.cs |
Validates memory configuration. |
README.md |
Links the upgrade guide. |
docs/upgrade-to-2.0.md |
Documents 2.0 migration steps. |
docs/reference/settings.md |
Warns about removed settings. |
docs/index.md |
Adds upgrade-guide navigation. |
CHANGELOG.md |
Revises migration and dependency notes. |
Review details
Suppressed comments (2)
docs/upgrade-to-2.0.md:202
- This compatibility statement is too broad for an upgrade guide: 2.0 already removes methods and changes constructors/interfaces, so a 1.3 binary that references those contracts can fail now with
MissingMethodExceptionorTypeLoadException. Only integrations verified to use the listed unchanged seams can be described as binary-compatible.
A package compiled against `UiPath.Caching` 1.3.0 loads against 2.0: .NET accepts a higher assembly
version than the one referenced, and the seams such packages reach for, `ICachingTelemetryProvider`,
`ITelemetryOperation`, `ICachingBuilder`, `IRedisProfiler` and the `RedisConnectionOptions` members
they read, have no binary change since 1.3.0. That is a fact about 2.0.0, not a promise; a later
release that moves one of those members would fail at runtime with `MissingMethodException` or
CHANGELOG.md:372
- This is not a consumer dependency floor.
UiPath.Caching.OpenTelemetry.csprojhas no OpenTelemetry package references, and every OpenTelemetryPackageReferencein this repository is undersamples; listing the central sample pins in a table introduced as requirements for consumer restore can cause unnecessary upgrades.
| `OpenTelemetry.*` (`UiPath.Caching.OpenTelemetry`) | 1.17.0 | 1.18.0 (`Instrumentation.StackExchangeRedis` 1.18.0-beta.1) |
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ead76a8 to
ec27a12
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The migration guide contains several inaccurate guarantees about serializer detection, expiration validation, and no-TTL read results.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Balanced
ec27a12 to
421bf35
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The migration guide contains two inaccurate guarantees, and the PR description still incorrectly includes NSubstitute in the Moq-specific failure.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Balanced
421bf35 to
16e954a
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The relocated serializer check can miss legacy registrations added by completion callbacks.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Balanced
16e954a to
3ed0944
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Null-valued removed keys can bypass the new validation and silently retain changed defaults.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Balanced
3ed0944 to
da1c722
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The migration guide contains several inaccurate or contradictory upgrade instructions that should be corrected before release.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
docs/upgrade-to-2.0.md:44
ThreadPoolSocketManagerwas an obsolete no-op, not an alias; the table itself correctly says there is no replacement. Distinguish it from the three renamed multilayer aliases so the migration history is accurate.
Four options keys were `[Obsolete]` aliases in 1.x and are gone in 2.0. The configuration binder
ignores a key it cannot place, so a leftover alias does not fail the build or write a log line; the
value falls back to its default. For `PrimaryMaxExpiration` that means the L1 cap disappears.
docs/upgrade-to-2.0.md:178
- Interface implementations cannot
overridedefault interface methods, and an ordinary public method matching a removed member can remain without a compile error. Only an explicit interface implementation becomes invalid when that member leaves the interface, so the current instruction tells consumers to remove something that may not need removal and uses a C# construct that was never valid here.
- **The compat and sync forwarders are gone from the interfaces**, so an implementation no longer
inherits them and cannot have overridden them by accident. Remove any override.
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Balanced
… document the 1.x to 2.0 upgrade The binder skips a key it cannot place without a word, so a PrimaryMaxExpiration left in appsettings.json after the 2.0 upgrade did not fail the build, startup or a log line: the L1 cap was simply gone. The first consumer to move onto 2.0.0-preview.2 caught it by reading the resolved options, not by anything the library said. The section-bound AddMemory, AddInMemoryRedis and AddRedisConnection overloads now throw at registration when one of the four removed keys is present, naming the section, each key and its replacement, whether or not the provider is enabled. The same upgrade surfaced three gaps in what we tell consumers, fixed here: - The changelog's dependency floors were wrong: it said Microsoft.Extensions 10.0.11 and left StackExchange.Redis 3.1.31 out. Both now come from Directory.Packages.props, as a table. - The compat-removal entry said call sites need no edit. Production code does not; a Moq or NSubstitute setup on one of the short forms throws NotSupportedException when the test runs, because neither can intercept an extension method. The entry now says so and shows the re-targeting. - There was no migration guide. docs/upgrade-to-2.0.md walks every source, test and configuration change, says how each break shows itself, and states what does not change: no stored entry moves. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
da1c722 to
a83e877
Compare
|



Summary
The first consumer to move onto 2.0.0-preview.2 (Cloud-RPA #27279) nearly shipped with its L1 cap silently gone: the binder ignores a
PrimaryMaxExpirationit can no longer place, and nothing in the build, at startup or in the logs said so. This makes the library refuse the four keys 2.0 removed, corrects the changelog where that upgrade found it wrong, and adds the migration guide the PR author had to write themselves.Changes
AddMemory(sectionName),AddInMemoryRedis(sectionName)and both section-boundAddRedisConnectionoverloads fail withInvalidOperationExceptionwhenPrimaryMaxExpiration,PrimaryMaxExpirationDisconnected,UsePrimaryOnlyWhenDisconnectedorThreadPoolSocketManageris present under the section, naming the section, every offending key and its replacement. Runs whether or not the provider is enabled. Code-only overloads are not checked: the property no longer exists to assign. The existing leftover-ISerializerProxy<RedisValue>guard now runs on the same terms, before theEnabledswitch, so a disabled test profile reports it too. No public API change.Directory.Packages.props(SE.Redis 3.1.13 → 3.1.31, Microsoft.Extensions 10.0.10 → 10.0.12, Logging.Abstractions 10.0.11 → 10.0.12, OpenTelemetry 1.17.0 → 1.18.0).Setup/Verifyexpression and refuses a static call, so a short form inside one throwsNotSupportedExceptionat test run time. The entry now says so and shows the re-targeting with an any-policy matcher. NSubstitute is unaffected and the entry says that too.docs/upgrade-to-2.0.md, linked from the docs index and README. Opens with how each break shows itself (three do not show at compile time), then covers floors, config keys, the serializer seam andIMemorySerializerProxy, the nullable-expiration branch and the throw on zero or past values, mocking, hand-written implementations, the clock, renamed types, the binary-compat position for integrations built against 1.x, and rollback.settings.mdgains a one-line pointer above each of the three affected sections.Test plan
RemovedConfigurationKeysTests: each renamed key on both multilayer sections, the socket-manager key on both connection overloads, disabled provider still refused, all offending keys in one message, renamed keys bind cleanly, unrelated sections untouched, code-only overload not guarded.Linked issues
Prompted by UiPath/Cloud-RPA#27279.
Contributor declaration
git commit -s).🤖 Generated with Claude Code