Support MSETEX by mgravell · Pull Request #2977 · StackExchange/StackExchange.Redis

Redis 8.4.0 is due to add MSETEX (see redis/redis#14434 and redis/redis#14470)

Here we:

  • add relevant StringSet[Async] APIs that take optional relative expiration via overload
  • rewrite ExpiryToken for simplicity and performance (note existing unit tests)
  • add a new Message subclass that natively and efficiently supports MSETEX, MSETNX and MSET, and use that for the new API
  • refactor the existing multi-set API to also use that same approach, avoiding additional array copies
  • add integration tests

Open design question (please discuss):

Expiration is a PITA to express, because we have multiple overlapping concepts:

  • (nothing special)
  • absolute (DateTime) - EXAT/PXAT
  • relative (TimeSpan) - EX/PX
  • preserve existing - KEEPTTL
  • explicit wipe - PERSIST

Internally, we use ExpiryToken to represent these efficiently, allowing a single API that expresses all of these intents. For the new API, I have only added relative expiration, but conceptually the code also supports absolute. Should we:

  1. keep adding TimeSpan/DateTime/etc overloads, or
  2. make ExpiryToken (presumably renaming it and making the API suitable for public callers) a first class citizen, i.e. we make this the first example of APIs with a new RedisExpiry (or whatever) parameter, rather than complicated overloads - and the caller specifies expiration from there

Fix #2892

Note that CI will be dependent on access to a suitable server, i.e. #2976