|
9 | 9 | import io.vertx.ext.unit.junit.RunTestOnContext; |
10 | 10 | import io.vertx.ext.unit.junit.VertxUnitRunner; |
11 | 11 | import io.vertx.redis.client.*; |
12 | | -import java.util.stream.Collectors; |
| 12 | +import io.vertx.redis.client.impl.ZModem; |
13 | 13 | import org.junit.*; |
14 | 14 | import org.junit.runner.RunWith; |
15 | 15 | import org.testcontainers.containers.FixedHostPortGenericContainer; |
16 | 16 | import org.testcontainers.containers.GenericContainer; |
17 | 17 |
|
18 | 18 | import java.util.*; |
19 | 19 | import java.util.concurrent.atomic.AtomicInteger; |
| 20 | +import java.util.stream.Collectors; |
20 | 21 |
|
21 | 22 | import static io.vertx.redis.client.Command.*; |
22 | 23 | import static io.vertx.redis.client.Request.cmd; |
@@ -1163,6 +1164,70 @@ public void setAndWaitEmptyBatch(TestContext should) { |
1163 | 1164 | )); |
1164 | 1165 | } |
1165 | 1166 |
|
| 1167 | + @Test(timeout = 30_000) |
| 1168 | + @SuppressWarnings("unchecked") |
| 1169 | + public void batchSameSlotGroupByMultipleSlotsCommands(TestContext should) { |
| 1170 | + final Async test = should.async(); |
| 1171 | + |
| 1172 | + Map<Integer, List<Request>> mapCommands = new HashMap<>(); |
| 1173 | + for (int i = 0; i < 100000; i++) { |
| 1174 | + String key = "key-" + i; |
| 1175 | + String value = "value-" + i; |
| 1176 | + int endpoint; |
| 1177 | + int slot = ZModem.generate(key); |
| 1178 | + if (slot < 16384 / (options.getEndpoints().size() / 2)) { |
| 1179 | + endpoint = 0; |
| 1180 | + } else if (slot <= 2 * 16384 / (options.getEndpoints().size() / 2)) { |
| 1181 | + endpoint = 1; |
| 1182 | + } else { |
| 1183 | + endpoint = 2; |
| 1184 | + } |
| 1185 | + List<Request> commands = mapCommands.computeIfAbsent(endpoint, k -> new ArrayList<>()); |
| 1186 | + commands.add(Request.cmd(Command.SET).arg(key).arg(value)); |
| 1187 | + } |
| 1188 | + |
| 1189 | + Redis.createClient(rule.vertx(), options) |
| 1190 | + .connect() |
| 1191 | + .onComplete(should.asyncAssertSuccess(cluster -> { |
| 1192 | + List<Future<List<Response>>> futures = new ArrayList<>(); |
| 1193 | + for (Map.Entry<Integer, List<Request>> entry : mapCommands.entrySet()) { |
| 1194 | + futures.add(cluster.batch(entry.getValue())); |
| 1195 | + } |
| 1196 | + Future.all(futures).onComplete(should.asyncAssertSuccess(responses -> { |
| 1197 | + should.assertEquals(mapCommands.values().stream().map(List::size).reduce(0 , Integer::sum), responses.result().list().stream().map(item -> ((List<Request>) item).size()).reduce(0, Integer::sum)); |
| 1198 | + |
| 1199 | + test.countDown(); |
| 1200 | + })).onFailure(should::fail); |
| 1201 | + } |
| 1202 | + )); |
| 1203 | + } |
| 1204 | + |
| 1205 | + @Test(timeout = 30_000) |
| 1206 | + public void batchSameSlotsCommands(TestContext should) { |
| 1207 | + final Async test = should.async(); |
| 1208 | + |
| 1209 | + List<Request> rawCommands = new ArrayList<>(); |
| 1210 | + for (int i = 0; i < 100000; i++) { |
| 1211 | + String key = "key-" + i; |
| 1212 | + String value = "value-" + i; |
| 1213 | + int endpoint; |
| 1214 | + int slot = ZModem.generate(key); |
| 1215 | + if (slot < 16384 / (options.getEndpoints().size() / 2)) { |
| 1216 | + rawCommands.add(Request.cmd(Command.SET).arg(key).arg(value)); |
| 1217 | + } |
| 1218 | + } |
| 1219 | + |
| 1220 | + Redis.createClient(rule.vertx(), options) |
| 1221 | + .connect() |
| 1222 | + .onComplete(should.asyncAssertSuccess(cluster -> { |
| 1223 | + cluster.batch(rawCommands).onComplete(should.asyncAssertSuccess(responses -> { |
| 1224 | + should.assertEquals(rawCommands.size(), responses.size()); |
| 1225 | + test.countDown(); |
| 1226 | + })).onFailure(should::fail); |
| 1227 | + } |
| 1228 | + )); |
| 1229 | + } |
| 1230 | + |
1166 | 1231 | @Test(timeout = 30_000) |
1167 | 1232 | public void clusterInfoReturnsVerbatimString(TestContext should) { |
1168 | 1233 | final Async test = should.async(); |
|
0 commit comments