我正在尝试使用Redis的scan功能,它需要被调用,直到返回的游标为“0”。
这种方法很有效,但感觉太复杂了--有没有一种不需要递归的方法?
Uni<Object> callScanRecursively(String cursorNum, List<String> results) {
List<String> args = new ArrayList<>(List.of(cursorNum, "MATCH", "*"));
return reactiveRedisClient.scan(args)
.onItem()
.transformToUni(item -> {
List<String> keysList = new ArrayList<>();
item.get(1).forEach(k -> {
keysList.add(k.toString());
});
results.addAll(keysList);
if (item.get(0).toString().equals("0")) {
return Uni.createFrom().item(results);
} else {
String nextCursorNum = item.get(0).toString();
return callScanRecursively(nextCursorNum, results);
}
}
);
}
List<String> results = new ArrayList<>();
String startingCursorRedis = "0";
callScanRecursively(startingCursorRedis, results)
.subscribe()
.with(item ->
LOGGER.info(item)
);发布于 2021-11-10 16:00:00
当给定条件response.get(0).toString().equals("0")仍未满足时,您可以使用MultiRepeat通过Uni发射器收集ReactiveRedisClient#scan结果:
Uni发射器
Multi<String> callScan(String initialCursor) {
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.<AtomicReference<String>, List<String>>uni(
() -> cursorReference,
(state, emitter) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.subscribe()
.with(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
java.util.List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
emitter.complete(keysList);
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}Uni
如果不需要对发出的项进行更多的控制,甚至可以更简单:
Multi<String> callScan(String initialCursor) {
ReactiveRedisClientImpl reactiveRedisClient = new ReactiveRedisClientImpl();
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.uni(
() -> cursorReference,
(state) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.invoke(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
})
.map(response -> {
List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
return keysList;
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}https://stackoverflow.com/questions/69815030
复制相似问题