├── .gitignore
├── .travis.yml
├── LICENSE
├── wandoujia-LICENSE
├── README.md
├── src
├── main
│ └── java
│ │ └── io
│ │ └── codis
│ │ └── jodis
│ │ ├── JedisResourcePool.java
│ │ ├── CodisProxyInfo.java
│ │ ├── JedisPoolAdaptor.java
│ │ ├── BoundedExponentialBackoffRetryUntilElapsed.java
│ │ └── RoundRobinJedisPool.java
└── test
│ └── java
│ └── io
│ └── codis
│ └── jodis
│ ├── RedisServer.java
│ ├── TestBoundedExponentialBackoffRetryUntilElapsed.java
│ └── TestRoundRobinJedisPool.java
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings
4 | target
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | jdk:
4 | - oraclejdk8
5 |
6 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip=true -B -V
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 CodisLabs.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/wandoujia-LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Wandoujia Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jodis - Java client for codis
2 |
3 | [](https://travis-ci.org/CodisLabs/jodis)
4 |
5 | Jodis is a java client for codis based on [Jedis](https://github.com/xetorthio/jedis) and [Curator](http://curator.apache.org/).
6 |
7 | # Features
8 | - Use a round robin policy to balance load to multiple codis proxies.
9 | - Detect proxy online and offline automatically.
10 |
11 | # How to use
12 | Add this to your pom.xml. We deploy jodis to https://oss.sonatype.org.
13 | ```xml
14 |
41 | * We do not have a returnResource method, just close the jedis instance
42 | * returned directly.
43 | */
44 | Jedis getResource();
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/io/codis/jodis/RedisServer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)RedisServer.java, 2014-11-30.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import java.io.IOException;
28 |
29 | /**
30 | * @author Apache9
31 | */
32 | public class RedisServer {
33 |
34 | private final ProcessBuilder builder;
35 |
36 | private Process process;
37 |
38 | public RedisServer(int port) {
39 | builder = new ProcessBuilder().command("redis-server", "--port",
40 | Long.toString(port)).inheritIO();
41 | }
42 |
43 | public void start() throws IOException {
44 | process = builder.start();
45 | }
46 |
47 | public void stop() {
48 | if (process != null) {
49 | process.destroy();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/codis/jodis/CodisProxyInfo.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)CodisProxyInfo.java, 2015-10-14.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
28 |
29 | /**
30 | * We only care about the proxy address and if it is online.
31 | *
32 | * @author Apache9
33 | */
34 | @JsonIgnoreProperties(ignoreUnknown = true)
35 | public class CodisProxyInfo {
36 |
37 | private String addr;
38 |
39 | private String state;
40 |
41 | public String getAddr() {
42 | return addr;
43 | }
44 |
45 | public void setAddr(String addr) {
46 | this.addr = addr;
47 | }
48 |
49 | public String getState() {
50 | return state;
51 | }
52 |
53 | public void setState(String state) {
54 | this.state = state;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/io/codis/jodis/TestBoundedExponentialBackoffRetryUntilElapsed.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)TestBoundedExponentialBackoffRetryUntilElapsed.java, 2014-12-2.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import static org.junit.Assert.assertEquals;
28 | import static org.junit.Assert.assertFalse;
29 | import static org.junit.Assert.assertTrue;
30 |
31 | import java.util.concurrent.ThreadLocalRandom;
32 | import java.util.concurrent.TimeUnit;
33 |
34 | import org.apache.curator.RetrySleeper;
35 | import org.junit.Test;
36 |
37 | /**
38 | * @author Apache9
39 | */
40 | public class TestBoundedExponentialBackoffRetryUntilElapsed {
41 |
42 | private static final class FakeRetrySleeper implements RetrySleeper {
43 |
44 | public long sleepTimeMs;
45 |
46 | @Override
47 | public void sleepFor(long time, TimeUnit unit) {
48 | this.sleepTimeMs = unit.toMillis(time);
49 | }
50 | }
51 |
52 | @Test
53 | public void test() {
54 | FakeRetrySleeper sleeper = new FakeRetrySleeper();
55 | BoundedExponentialBackoffRetryUntilElapsed r = new BoundedExponentialBackoffRetryUntilElapsed(
56 | 10, 2000, 60000);
57 | for (int i = 0; i < 100; i++) {
58 | assertTrue(r.allowRetry(i, ThreadLocalRandom.current().nextInt(60000), sleeper));
59 | System.out.println(sleeper.sleepTimeMs);
60 | assertTrue(sleeper.sleepTimeMs <= 2000);
61 | }
62 | assertTrue(r.allowRetry(1000, 59900, sleeper));
63 | System.out.println(sleeper.sleepTimeMs);
64 | assertTrue(sleeper.sleepTimeMs <= 100);
65 | sleeper.sleepTimeMs = -1L;
66 | assertFalse(r.allowRetry(1, 60000, sleeper));
67 | assertEquals(-1L, sleeper.sleepTimeMs);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/io/codis/jodis/JedisPoolAdaptor.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)JedisPoolAdaptor.java, 2014-12-2.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import java.net.URI;
28 |
29 | import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
30 |
31 | import redis.clients.jedis.JedisPool;
32 |
33 | /**
34 | * Adaptor of JedisPool to make writing testcase easier.
35 | *
36 | * @author Apache9
37 | */
38 | public class JedisPoolAdaptor extends JedisPool implements JedisResourcePool {
39 |
40 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host, int port, int timeout,
41 | String password, int database, String clientName) {
42 | super(poolConfig, host, port, timeout, password, database, clientName);
43 | }
44 |
45 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host, int port, int timeout,
46 | String password, int database) {
47 | super(poolConfig, host, port, timeout, password, database);
48 | }
49 |
50 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host, int port, int timeout,
51 | String password) {
52 | super(poolConfig, host, port, timeout, password);
53 | }
54 |
55 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host, int port, int timeout) {
56 | super(poolConfig, host, port, timeout);
57 | }
58 |
59 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host, int port) {
60 | super(poolConfig, host, port);
61 | }
62 |
63 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, String host) {
64 | super(poolConfig, host);
65 | }
66 |
67 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, URI uri, int timeout) {
68 | super(poolConfig, uri, timeout);
69 | }
70 |
71 | public JedisPoolAdaptor(GenericObjectPoolConfig poolConfig, URI uri) {
72 | super(poolConfig, uri);
73 | }
74 |
75 | public JedisPoolAdaptor(String host, int port) {
76 | super(host, port);
77 | }
78 |
79 | public JedisPoolAdaptor(String host) {
80 | super(host);
81 | }
82 |
83 | public JedisPoolAdaptor(URI uri, int timeout) {
84 | super(uri, timeout);
85 | }
86 |
87 | public JedisPoolAdaptor(URI uri) {
88 | super(uri);
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/io/codis/jodis/BoundedExponentialBackoffRetryUntilElapsed.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)BoundedExponentialBackoffRetryUntilElapsed.java, 2014-12-2.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import java.util.concurrent.ThreadLocalRandom;
28 | import java.util.concurrent.TimeUnit;
29 |
30 | import org.apache.curator.RetryPolicy;
31 | import org.apache.curator.RetrySleeper;
32 |
33 | /**
34 | * Similar to {@link org.apache.curator.retry.BoundedExponentialBackoffRetry},
35 | * but limit the retry elapsed time, not retry number.
36 | *
37 | * @author Apache9
38 | */
39 | public class BoundedExponentialBackoffRetryUntilElapsed implements RetryPolicy {
40 |
41 | private final int baseSleepTimeMs;
42 |
43 | private final int maxSleepTimeMs;
44 |
45 | private final long maxElapsedTimeMs;
46 |
47 | /**
48 | * @param baseSleepTimeMs
49 | * initial amount of time to wait between retries
50 | * @param maxSleepTimeMs
51 | * max time in ms to sleep on each retry
52 | * @param maxElapsedTimeMs
53 | * total time in ms to retry
54 | */
55 | public BoundedExponentialBackoffRetryUntilElapsed(int baseSleepTimeMs, int maxSleepTimeMs,
56 | long maxElapsedTimeMs) {
57 | this.baseSleepTimeMs = baseSleepTimeMs;
58 | this.maxSleepTimeMs = maxSleepTimeMs;
59 | if (maxElapsedTimeMs < 0) {
60 | this.maxElapsedTimeMs = Long.MAX_VALUE;
61 | } else {
62 | this.maxElapsedTimeMs = maxElapsedTimeMs;
63 | }
64 | }
65 |
66 | private long getSleepTimeMs(int retryCount, long elapsedTimeMs) {
67 | return Math.min(
68 | maxSleepTimeMs,
69 | (long) baseSleepTimeMs
70 | * Math.max(
71 | 1,
72 | ThreadLocalRandom.current().nextInt(
73 | 1 << Math.min(30, retryCount + 1))));
74 | }
75 |
76 | @Override
77 | public boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper) {
78 | if (elapsedTimeMs >= maxElapsedTimeMs) {
79 | return false;
80 | }
81 | long sleepTimeMs = Math.min(maxElapsedTimeMs - elapsedTimeMs,
82 | getSleepTimeMs(retryCount, elapsedTimeMs));
83 | try {
84 | sleeper.sleepFor(sleepTimeMs, TimeUnit.MILLISECONDS);
85 | } catch (InterruptedException e) {
86 | Thread.currentThread().interrupt();
87 | return false;
88 | }
89 | return true;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/test/java/io/codis/jodis/TestRoundRobinJedisPool.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @(#)TestRoundRobinJedisPool.java, 2014-12-1.
3 | *
4 | * Copyright (c) 2014 CodisLabs.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining
7 | * a copy of this software and associated documentation files (the
8 | * "Software"), to deal in the Software without restriction, including
9 | * without limitation the rights to use, copy, modify, merge, publish,
10 | * distribute, sublicense, and/or sell copies of the Software, and to
11 | * permit persons to whom the Software is furnished to do so, subject to
12 | * the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be
15 | * included in all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 | package io.codis.jodis;
26 |
27 | import static org.junit.Assert.assertEquals;
28 |
29 | import java.io.File;
30 | import java.io.IOException;
31 | import java.net.ServerSocket;
32 | import java.nio.file.FileVisitResult;
33 | import java.nio.file.Files;
34 | import java.nio.file.Path;
35 | import java.nio.file.SimpleFileVisitor;
36 | import java.nio.file.attribute.BasicFileAttributes;
37 |
38 | import org.apache.curator.test.TestingServer;
39 | import org.apache.zookeeper.CreateMode;
40 | import org.apache.zookeeper.KeeperException;
41 | import org.apache.zookeeper.ZooDefs;
42 | import org.apache.zookeeper.ZooKeeper;
43 | import org.junit.After;
44 | import org.junit.Before;
45 | import org.junit.Test;
46 |
47 | import com.fasterxml.jackson.databind.ObjectMapper;
48 | import com.fasterxml.jackson.databind.node.ObjectNode;
49 | import com.google.common.io.Closeables;
50 |
51 | import io.codis.jodis.RoundRobinJedisPool;
52 | import redis.clients.jedis.Jedis;
53 | import redis.clients.jedis.exceptions.JedisException;
54 |
55 | /**
56 | * @author Apache9
57 | */
58 | public class TestRoundRobinJedisPool {
59 |
60 | private ObjectMapper mapper = new ObjectMapper();
61 |
62 | private int zkPort;
63 |
64 | private File testDir = new File(getClass().getName());
65 |
66 | private TestingServer zkServer;
67 |
68 | private int redisPort1;
69 |
70 | private RedisServer redis1;
71 |
72 | private int redisPort2;
73 |
74 | private RedisServer redis2;
75 |
76 | private Jedis jedis1;
77 |
78 | private Jedis jedis2;
79 |
80 | private String zkProxyDir = "/" + getClass().getName();
81 |
82 | private RoundRobinJedisPool jodisPool;
83 |
84 | private static int probeFreePort() throws IOException {
85 | try (ServerSocket ss = new ServerSocket(0)) {
86 | ss.setReuseAddress(true);
87 | return ss.getLocalPort();
88 | }
89 | }
90 |
91 | private static void waitUntilRedisStarted(int port) throws InterruptedException {
92 | for (;;) {
93 | try (Jedis jedis = new Jedis("127.0.0.1", port)) {
94 | if ("PONG".equals(jedis.ping())) {
95 | break;
96 | }
97 | } catch (JedisException e) {}
98 | Thread.sleep(100);
99 | }
100 | }
101 |
102 | private void deleteDirectory(File directory) throws IOException {
103 | if (!directory.exists()) {
104 | return;
105 | }
106 | Files.walkFileTree(directory.toPath(), new SimpleFileVisitor
330 | * We will create curator client based on these parameters and close it
331 | * while closing pool.
332 | *
333 | * @param zkAddr
334 | * ZooKeeper connect string. e.g., "zk1:2181"
335 | * @param zkSessionTimeoutMs
336 | * ZooKeeper session timeout in milliseconds
337 | */
338 | public Builder curatorClient(String zkAddr, int zkSessionTimeoutMs) {
339 | this.zkAddr = zkAddr;
340 | this.zkSessionTimeoutMs = zkSessionTimeoutMs;
341 | return this;
342 | }
343 |
344 | /**
345 | * Set jedis pool config.
346 | */
347 | public Builder poolConfig(JedisPoolConfig poolConfig) {
348 | this.poolConfig = poolConfig;
349 | return this;
350 | }
351 |
352 | /**
353 | * Set jedis pool timeout in milliseconds.
354 | *
355 | * We will set connectionTimeoutMs and soTimeoutMs both.
356 | *
357 | * @param timeoutMs
358 | * timeout is milliseconds
359 | */
360 | public Builder timeoutMs(int timeoutMs) {
361 | this.connectionTimeoutMs = this.soTimeoutMs = timeoutMs;
362 | return this;
363 | }
364 |
365 | /**
366 | * Set jedis pool connection timeout in milliseconds.
367 | *
368 | * @param connectionTimeoutMs
369 | * timeout is milliseconds
370 | */
371 | public Builder connectionTimeoutMs(int connectionTimeoutMs) {
372 | this.connectionTimeoutMs = connectionTimeoutMs;
373 | return this;
374 | }
375 |
376 | /**
377 | * Set jedis pool connection soTimeout in milliseconds.
378 | *
379 | * @param soTimeoutMs
380 | * timeout is milliseconds
381 | */
382 | public Builder soTimeoutMs(int soTimeoutMs) {
383 | this.soTimeoutMs = soTimeoutMs;
384 | return this;
385 | }
386 |
387 | /**
388 | * Set password.
389 | */
390 | public Builder password(String password) {
391 | this.password = password;
392 | return this;
393 | }
394 |
395 | /**
396 | * Set redis database.
397 | */
398 | public Builder database(int database) {
399 | this.database = database;
400 | return this;
401 | }
402 |
403 | /**
404 | * Set redis client name.
405 | */
406 | public Builder clientName(String clientName) {
407 | this.clientName = clientName;
408 | return this;
409 | }
410 |
411 | private void validate() {
412 | Preconditions.checkNotNull(zkProxyDir, "zkProxyDir can not be null");
413 | if (curatorClient == null) {
414 | Preconditions.checkNotNull(zkAddr, "zk client can not be null");
415 | curatorClient = CuratorFrameworkFactory.builder().connectString(zkAddr)
416 | .sessionTimeoutMs(zkSessionTimeoutMs)
417 | .retryPolicy(new BoundedExponentialBackoffRetryUntilElapsed(
418 | CURATOR_RETRY_BASE_SLEEP_MS, CURATOR_RETRY_MAX_SLEEP_MS, -1L))
419 | .build();
420 | curatorClient.start();
421 | closeCurator = true;
422 | } else {
423 | // we need to get the initial data so client must be started
424 | if (curatorClient.getState() == LATENT) {
425 | curatorClient.start();
426 | }
427 | }
428 | if (poolConfig == null) {
429 | poolConfig = new JedisPoolConfig();
430 | }
431 | }
432 |
433 | /**
434 | * Create the {@link RoundRobinJedisPool}.
435 | */
436 | public RoundRobinJedisPool build() {
437 | validate();
438 | return new RoundRobinJedisPool(curatorClient, closeCurator, zkProxyDir, poolConfig,
439 | connectionTimeoutMs, soTimeoutMs, password, database, clientName);
440 | }
441 | }
442 | }
443 |
--------------------------------------------------------------------------------