Use Properties instead of List of Strings arranged as sequence of key-value pairs to improve value lookup. Properties allows direct value lookup whereas the List previously required List scanning for an index and another index access to retrieve the actual value.
Original Pull Request: #255
Reduce visibility of DefaultRedisCacheWriter as trivial implementation. Replace ConnectionCallback with Java 8 functions. Increase visibility of the RedisCache constructor to allow subclassing. Move factory methods to create DefaultRedisCacheWriter to RedisCacheWriter interface.
Refactor RedisCacheManagerConfigurator to stateful RedisCacheManagerBuilder. Remove RedisCache.setTransactionAware override in RedisCacheManagerConfigurator removing behavior not compliant with AbstractTransactionSupportingCacheManager. Terminate interrupted cache wait loop with exception. Javadoc, formatting, reorder methods.
Allow ConversionService configuration via RedisCacheConfiguration. Accept cache keys that are either convertible to String or that override toString to obtain the String representation of the cache key.
Original pull request: #252.
RedisCache now operates directly with RedisConnectionFactory allowing each Cache to use its own SerializationPair for cache key and value conversion.
A RedisCacheManager with default settings is created with RedisCacheManager.create(connectionFactory). Use RedisCacheManager.builder(…) to obtain a builder to customize cache settings.
RedisCacheManager cm = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(defaultCacheConfig())
.initialCacheConfigurations(singletonMap("predefined", defaultCacheConfig().disableCachingNullValues()))
.transactionAware()
.build();
The behavior of a single RedisCache is defined via its RedisCacheConfiguration. Starting from defaultCacheConfig() the configuration can be altered as needed.
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(1))
.disableCachingNullValues();
RedisCacheManager defaults to a lock-free RedisCacheWriter for reading & writing binary values. Lock-free caching improves throughput. The lack of entry locking can lead to overlapping, non atomic commands, for putIfAbsent and clean methods as those require multiple commands sent to Redis. The locking counterpart prevents command overlap by setting an explicit lock key and checking against presence of this key, which leads to additional requests and potential command wait times.
Original pull request: #252.
Update JavaDoc and assert nullability contract.
Use slowlog-max-len in tests instead of maxclients avoiding potential ulimit errors.
Original Pull Request: #253
Reducing the default to 100 milliseconds is a good compromise to retain a quiet time in for parallel execution and optimize for default, single-threaded execution (such as test execution or regular application shutdown). The shutdown timeout can be adjusted to fit specific application needs.
Previously, LettuceConnectionFactory used different defaults: 2 seconds if used LettuceClientConfiguration and 60 seconds without LettuceClientConfiguration. In any case, defaults delay shutdown and cause severe delays in total. The driver default of two seconds provides enough time to complete long-running tasks before the actual thread pool shutdown.
Original Pull Request: #251
We now consider the last key in SDIFF command execution on Redis Cluster to correctly compute the set difference.
For reactive connections we collect the result sets entirely before applying further computation. Previously, the zip function could return a previous view of the result that caused too many/too few results.
Original Pull Request: #250
Migrate LettuceReactiveStringCommandsTests to StepVerifier and replace Collection.stream().toArray(…) with Collection.toArray(…).
Original Pull Request: #249
We now return AbsentByteBufferResponse to indicate absence of a Redis key when retrieving the key as top-level element. CommandResponse indicates via isPresent its presence or absence of a response value. Omission of absent values can cause a stream with a different response structure compared to the request. Retaining the stream sequence is required for response to request correlation.
GET and GETSET commands use presence of CommandResponse to filter response emission. Both commands return a single element so absence does not interferes with the request structure.
Previously, we just returned an empty byte-array that caused downstream errors deserializing and emitting null values that are prohibited in Reactive Streams.
Original Pull Request: #249
We added Jedis-/LettuceClientConfiguration and mutable Jedis-/LettuceClientConfiguration to encapsulate Jedis/Lettuce specific client features. Those should be used for ConnectionFactory configuration.
Additionally we added RedisStandaloneConfiguration next to the existing configurations for Sentinel and Cluster.
Along the way we also removed superfluous test system properties and Gemfire specific hooks and truststore customization.
Original Pull Request: #236
We now follow a more consistent naming scheme for the methods in repository that are driven by the following guidelines:
* Methods referring to an identifier now all end on …ById(…).
* Methods taking or returning a collection are named …All(…)
Please see DATACMNS-944 for details.
We now shut down ClusterCommandExecutor via LettuceClusterConnection and JedisClusterConnection if the ClusterCommandExecutor was created through the connection instance. In such case ClusterCommandExecutor is managed through Lettuce/JedisClusterConnection and disposed on connection close.
Previously ClusterCommandExecutor created through a ClusterConnection was not disposed.
Original pull request: #247.
Refactor server and scripting commands to their own implementations and interfaces.
Fix JavaDoc indentations. Fix typos. Replace explicit type arguments with diamond syntax. Replace anonymous inner classes with method references and lambdas, where possible. Use shared ClientResources with LettuceConnectionFactory tests.
Align reactive command implementation visibility with blocking command implementation visibility to package-protected. These implementations are not an extension point and subject to be used through their interfaces.
Original pull request: #247.
We refactored JedisConnection and LettuceConnection from monolithic connection classes into modular classes that organize methods according the Redis feature group and created segregated interfaces per Redis feature group. Segregated interfaces reduce the number of methods available on the interface to the used data type. This refactoring reduces the responsibility of JedisConnection/LettuceConnection and JedisClusterConnection/LettuceClusterConnection to a minimum of commands.
To preserve backwards-compatibility with users of the connection classes, we introduced DefaultedRedisConnection and DefaultedRedisClusterConnection to forward calls from the connection facade to the specific implementation. Deprecation of connection facade method assists migration off these methods towards using methods on the feature group interface.
LettuceConnection connection = …
connection.keyCommands().del(key);
connection.hashCommands().hSet(key, field, value);
Original pull request: #247.
Introduce RedisCustomConversions extending o.s.d.convert.CustomConversions.
Remove o.s.d.mongo.core.convert.CustomConversions implementation code and utility classes and let it extend RedisCustomConversions. Replace references to o.s.d.r.c.c.CustomConversions with o.s.d.convert.CustomConversions. Adapt tests.
Introduce constructors for ObjectHashMapper and RedisKeyValueAdapter requiring o.s.d.convert.CustomConversions and deprecate constructors accepting o.s.d.r.c.c.CustomConversions.
Related ticket: DATACMNS-1035.
Replace Flux/Mono.onErrorResumeWith(…) with Flux/Mono.onErrorMap(…) and turn translateException into a method returning a mapping function instead of a reactive type emitting the mapped exception. Replace otherwiseIfEmpty(…) with switchIfEmpty(…) and otherwiseReturn(…) with onErrorReturn(…).