We now order and assemble results of multi-key commands (e.g. MGET with cross-slot keys) that are executed on different nodes by positional keys to retain duplicate keys in the requested order and retain the server response.
Previously duplicate keys were treated as set of keys and the response didn't match the requested keys.
Original Pull Request: #303
We now rely more on Jedis to select the appropriate Redis database and we no longer select the database when opening/closing a connection. Previously, we always reset the database if a database index greater zero was configured.
A properly configured Jedis pool ensures that the appropriate database is selected even if the database was selected during connection interaction.
Relying on Jedis reduces the number of issued SELECT commands and improves that way overall performance when executing commands via the Template API.
Original Pull Request: #291
We now support Redis hashes via Repository support that contain colon in their id. We're using colons to split a composite id string into keyspace and id parts. Previously, we partially rejected processing of id's that don't exactly match the number of parts delimited by colon. This caused leftovers in secondary indexes.
Original Pull Request: #298
Some minor code and documentation changes. More interestingly obtain the RedisConverter instead of the KeyValueAdapter for IndexResolver resolution in QueryByExampleRedisExecutor and stick to findOne contract by throwing IncorrectResultSizeDataAccessException for queries returning non unique results.
Original Pull Request: #301
We now support query by example via Redis repositories. We allow case-sensitive, exact matching of singular simple and nested properties, using any/all match modes, value transformation of the criteria value for indexed properties.
We do not support findAll with sorting, case-insensitive properties or string matchers other than exact.
interface PersonRepository extends QueryByExampleExecutor<Person> {
}
class PersonService {
@Autowired PersonRepository personRepository;
List<Person> findPeople(Person probe) {
return personRepository.findAll(Example.of(probe));
}
}
Original Pull Request: #301
Fix tests not closing connections properly. Remove usage of Optional in constructors, avoid recreating DirectFieldAccessor on every getConnection call and update documentation.
Original Pull Request: #287
We now allow configuration of ReadFrom settings using the Lettuce driver to enable slave reads. If ReadFrom is configured, we opt-in to Master/Slave connections instead of plain connections. Master/Slave connections route commands to the configured type of node depending on whether the command is a read or write command.
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder().readFrom(ReadFrom.SLAVE).build();
ReadFrom is available for:
* Static Master/Slave Redis without Redis Sentinel
* Sentinel-Managed Master/Slave Redis
* Redis Cluster
ReadFrom is not configured for Pub/Sub connections or connections to the actual Sentinel servers.
Original Pull Request: #287
Add Template methods for unlink(…). Align unlink with del/mDel methods on reactive API using concatMap to retain order and provide batching/streaming. Reword Javadoc. Extend tests.
Replace blocking calls with StepVerifier in LettuceReactiveKeyCommandsTests.
Original pull request: #294.
We now support UNLINK for both Jedis & Lettuce throughout the single node and cluster connection. Reactive support is only available for Lettuce.
Original pull request: #294.
We now support Redis connections using OS-native transports through unix domain sockets when using the Lettuce driver. Domain sockets do not require a roundtrip through the networking layer but directly use native epoll or kqueue interfaces.
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
Unix domain socket support requires netty's native epoll/kqueue dependencies matching the runtime environment:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>linux-x86_64</classifier>
<version>${netty}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<classifier>osx-x86_64</classifier>
<version>${netty}</version>
</dependency>
Original Pull Request: #286
Adapt Lettuce implementation to use async commands in transaction mode. Adapt tests to changed behavior of returning status responses. Extend Javadoc.
Original pull request: #284.
We now reuse a shared Lettuce connection across our reactive connection wrappers if LettuceConnectionFactory is configured to provide a shared connection instance. Reactive connections can either operate with a shared connection or with a connection provider only.
We also now execute blocking Redis commands (BLPOP, BRPOP, BRPOPLPUSH) on dedicated connection.
Original Pull Request: #290
We now encapsulate deferred results for pipelining and transactions entirely within FutureResult and its subtypes. FutureResult accepts a Supplier<T> for default values, if operations return null and reports whether its result requires conversion. JedisResult and LettuceResult are now top-level classes and no longer inner classes of their connection factories.
Original pull request: #289.
Provide a String-focused convenience class for simpler bootstrapping and to provide a dedicated bean type for the application context when using auto-configuration.
Original Pull Request: #288
We now allow configuration of the client name that is applied to connections using the Lettuce driver.
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder().clientName("foo-bar").build();
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), configuration);
Fixed some typos, javadoc and method visibility along the way.
Original Pull Request: #285
Accept varargs byte arrays instead of Collection of byte arrays. Bypass own routing for exists single-slot execution in Redis Cluster. Replace parallel stream execution of exists(…) with sequential ClusterCommandExecutor dispatch.
Reorder methods in ClusterConnectionTests by name. Adapt Javadoc.
Original pull request: #281.
Strengthen non-null requirements when obtaining the native connection from LettuceReactiveRedisConnection. Guard close against multiple calls and use concatMap instead of flatMap to retain publisher sequence.
Original Pull Request: #282
We now emit array responses from Lua script execution as complete List instead of emitting the individual elements through the Publisher.
Lua scripts may return nil (null) elements that would be not emitted through a Publisher. Skipping null values would garble up the response – and in several cases, the response array is required as List. Emitting the whole List aligns the response to the signatures imposed by generics and aligns the behavior with the imperative API.
Original Pull Request: #282
Eagerly initialize known commands. Preallocate Jedis response builder. Replace list concatenation with array copy. Reject null arguments in execute(). Remove inversion through collections with direct byte array creation. Reorder arguments in signatures, visibility modifiers, Javadoc.
Original pull request: #283.
We now support HSTRLEN command throug RedisHashCommands for Lettuce and Jedis in both an imperative and reactive manner.
However, Jedis not natively supporting HSTRLEN via its API we’ve come up with some more reflective invocation allowing to execute commands currently not known by Jedis. We also added this behavior to the cluster implementation which as of now also supports RedisClusterConnection#execute.
Original pull request: #283.
Change return type for mset from void to Boolean. Add missing Nullable annotations. Add Javadoc.
Disable flakey tests for now.
Related pull request: #279.
We now use a fallback exception translation strategy in JedisClusterConnection to map all non-mapped exceptions to RedisSystemException. This change prevents null pointer exceptions caused by potentially throwing null.
Original Pull Request: #275
Add NonNullFields to packages. Add missing Nullable annotations. Extend Javadoc. Replace simple equals/hashCode methods using Lomboks EqualsAndHashCode annotation. Use RequiredArgsConstructor for private classes in favor of own constructors. Replace null-checks with qualified access whether objects are empty/applicable. Rearrange methods according to interface ordering.
Remove demo code from KeyspaceConfiguration.
Original pull request: #277.
Mark all packages with Spring Frameworks @NonNullApi. Add Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapted using code to make sure the IDE can evaluate the null flow properly. Fix Javadoc in places where an invalid null handling policy was advertised. Strengthened null requirements for types that expose null-instances.
Resolve some of the inherited null invariants, align Converters to null contract.
Original pull request: #277.
We removed the geo prefix from the imperative and reactive GeoOperations interfaces and our methods to match a more expressive scheme:
geoAdd(…) -> add(…)
geoDist(…) -> distance(…)
geoHash(…) -> hash(…)
geoPos(…) -> position(…)
geoRadius(…) -> radius(…)
geoRadiusByMember(…) -> radius(…)
geoRemove(…) -> remove(…)
Methods on the imperative API remain as deprecated default methods to retain compatibility and not enforce changes in the client code.
Original Pull Request: #274
We now release Jedis cluster node connections with Jedis.close() to the pool instead of Pool.returnResource(…). The close() method itself checks whether the connection was broken and if so, the connection gets destroyed. Destroying broken connections prevents the pool from supplying broken connections on borrow when testOnBorrow is disabled.
The only case where we return broken resources ourselves to the Pool is when we discover a broken connection ourselves: If we run into a NullPointerException or RedisConnectionFailureException, then we consider a connection is broken.
Original Pull Request: #271
Remove builder interfaces and aim for classes instead.
Also use delegation for builders avoiding constructors with too many arguments.
Alter ConnectionProvider#getConnection(Class) to return a typed connection as this is is the expected return type given the input parameters used.
Remove LettuceConnectionProvider.getConnection() method as it makes no longer sense for the non-lambda enabled interface. Remove unnecessary casts.
Add connection factory to cleanup-tracker on test class instantiation instead within the parameter supplier method to prevent shutdown by other cleanup calls that may happen in between. Reuse client resources.
Original Pull Request: #262
We now support Lettuce connection pooling by configuring a specialized client configuration via LettucePoolingClientConfiguration.builder(). Pooling settings can be configured through the builder and used with LettuceConnectionFactory.
Connection pooling is supported with Standalone and Sentinel-managed connections.
LettucePoolingClientConfiguration.builder()
.poolConfig(poolConfig)
.and() // allows configuration of further settings.
Original Pull Request: #262
We now create and release Lettuce connections using LettuceConnectionProvider. Connection providers encapsulate the underlying client and expose only creation and release methods. A connection provider can provide connections for Standalone or Cluster connections or wrap a LettucePool.
Previously we used RedisClient and RedisClusterClient directly which required context propagation (pooling/non-pooling) conditional code to obtain the appropriate connection type.
Original Pull Request: #262