public <T> T withCluster(final Function<StatefulRedisClusterConnection<String, String>, T> function) {
    return withConnection(stringConnection, function);
  }
@Test
  void testTimeoutCircuitBreaker() throws Exception {
    // because we’re using a single key, and blpop involves *Redis* also blocking, the breaker wait duration must be
    // longer than the sum of the remote timeouts
    final Duration breakerWaitDuration = TIMEOUT.multipliedBy(5);

    final CircuitBreakerConfiguration circuitBreakerConfig = new CircuitBreakerConfiguration();
    circuitBreakerConfig.setFailureRateThreshold(1);
    circuitBreakerConfig.setSlidingWindowMinimumNumberOfCalls(1);
    circuitBreakerConfig.setSlidingWindowSize(1);
    circuitBreakerConfig.setWaitDurationInOpenState(breakerWaitDuration);

    cluster = buildCluster(circuitBreakerConfig, ClientResources.builder());

    final String key = "key";

    // the first call should time out and open the breaker
    assertThrows(RedisCommandTimeoutException.class,
        () -> cluster.withCluster(connection -> connection.sync().blpop(2 * TIMEOUT.toMillis() / 1000d, key)));

    // the second call gets blocked by the breaker
    final RedisException e = assertThrows(RedisException.class,
        () -> cluster.withCluster(connection -> connection.sync().blpop(2 * TIMEOUT.toMillis() / 1000d, key)));
    assertInstanceOf(CallNotPermittedException.class, e.getCause());

    // wait for breaker to be half-open
    Thread.sleep(breakerWaitDuration.toMillis() * 2);

    assertEquals(0, (Long) cluster.withCluster(connection -> connection.sync().llen(key)));
  }