use of org.redisson.client.protocol.BatchCommandData in project redisson by redisson.
the class CommandBatchService method executeAsync.
public RFuture<BatchResult<?>> executeAsync() {
if (executed.get()) {
throw new IllegalStateException("Batch already executed!");
}
if (commands.isEmpty()) {
executed.set(true);
BatchResult<Object> result = new BatchResult<>(Collections.emptyList(), 0);
return RedissonPromise.newSucceededFuture(result);
}
if (isRedisBasedQueue()) {
return executeRedisBasedQueue();
}
if (this.options.getExecutionMode() != ExecutionMode.IN_MEMORY) {
for (Entry entry : commands.values()) {
BatchCommandData<?, ?> multiCommand = new BatchCommandData(RedisCommands.MULTI, new Object[] {}, index.incrementAndGet());
entry.getCommands().addFirst(multiCommand);
BatchCommandData<?, ?> execCommand = new BatchCommandData(RedisCommands.EXEC, new Object[] {}, index.incrementAndGet());
entry.getCommands().add(execCommand);
}
}
if (this.options.isSkipResult()) {
for (Entry entry : commands.values()) {
BatchCommandData<?, ?> offCommand = new BatchCommandData(RedisCommands.CLIENT_REPLY, new Object[] { "OFF" }, index.incrementAndGet());
entry.getCommands().addFirst(offCommand);
BatchCommandData<?, ?> onCommand = new BatchCommandData(RedisCommands.CLIENT_REPLY, new Object[] { "ON" }, index.incrementAndGet());
entry.getCommands().add(onCommand);
}
}
if (this.options.getSyncSlaves() > 0) {
for (Entry entry : commands.values()) {
BatchCommandData<?, ?> waitCommand = new BatchCommandData(RedisCommands.WAIT, new Object[] { this.options.getSyncSlaves(), this.options.getSyncTimeout() }, index.incrementAndGet());
entry.getCommands().add(waitCommand);
}
}
RPromise<BatchResult<?>> promise = new RedissonPromise<>();
CompletableFuture<Void> voidPromise = new CompletableFuture<>();
if (this.options.isSkipResult() && this.options.getSyncSlaves() == 0) {
voidPromise.whenComplete((res, ex) -> {
executed.set(true);
if (ex != null) {
for (Entry e : commands.values()) {
e.getCommands().forEach(t -> t.tryFailure(ex));
}
promise.tryFailure(ex);
commands.clear();
nestedServices.clear();
return;
}
commands.clear();
nestedServices.clear();
promise.trySuccess(new BatchResult<>(Collections.emptyList(), 0));
});
} else {
voidPromise.whenComplete((res, ex) -> {
executed.set(true);
if (ex != null) {
for (Entry e : commands.values()) {
e.getCommands().forEach(t -> t.tryFailure(ex));
}
promise.tryFailure(ex);
commands.clear();
nestedServices.clear();
return;
}
List<BatchCommandData> entries = new ArrayList<BatchCommandData>();
for (Entry e : commands.values()) {
entries.addAll(e.getCommands());
}
Collections.sort(entries);
List<Object> responses = new ArrayList<Object>(entries.size());
int syncedSlaves = 0;
for (BatchCommandData<?, ?> commandEntry : entries) {
if (isWaitCommand(commandEntry)) {
syncedSlaves = (Integer) commandEntry.getPromise().getNow(null);
} else if (!commandEntry.getCommand().getName().equals(RedisCommands.MULTI.getName()) && !commandEntry.getCommand().getName().equals(RedisCommands.EXEC.getName()) && !this.options.isSkipResult()) {
if (commandEntry.getPromise().isCancelled()) {
continue;
}
Object entryResult = commandEntry.getPromise().getNow(null);
try {
if (objectBuilder != null) {
entryResult = objectBuilder.tryHandleReference(entryResult, referenceType);
}
} catch (ReflectiveOperationException exc) {
log.error("Unable to handle reference from " + entryResult, exc);
}
responses.add(entryResult);
}
}
BatchResult<Object> result = new BatchResult<Object>(responses, syncedSlaves);
promise.trySuccess(result);
commands.clear();
nestedServices.clear();
});
}
AtomicInteger slots = new AtomicInteger(commands.size());
for (Map.Entry<RFuture<?>, List<CommandBatchService>> entry : nestedServices.entrySet()) {
slots.incrementAndGet();
for (CommandBatchService service : entry.getValue()) {
service.executeAsync();
}
entry.getKey().whenComplete((res, e) -> {
handle(voidPromise, slots, entry.getKey());
});
}
for (Map.Entry<MasterSlaveEntry, Entry> e : commands.entrySet()) {
RedisCommonBatchExecutor executor = new RedisCommonBatchExecutor(new NodeSource(e.getKey()), voidPromise, connectionManager, this.options, e.getValue(), slots, referenceType, false);
executor.execute();
}
return promise;
}
Aggregations