com.redis.spring.batch.writer.OperationItemWriter Maven / Gradle / Ivy
package com.redis.spring.batch.writer;
import java.text.MessageFormat;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import org.springframework.batch.item.ItemStreamWriter;
import com.redis.spring.batch.AbstractRedisItemStreamSupport;
import io.lettuce.core.AbstractRedisClient;
import io.lettuce.core.RedisCommandExecutionException;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.api.async.BaseRedisAsyncCommands;
import io.lettuce.core.api.async.RedisTransactionalAsyncCommands;
import io.lettuce.core.cluster.PipelinedRedisFuture;
import io.lettuce.core.codec.RedisCodec;
public class OperationItemWriter extends AbstractRedisItemStreamSupport implements ItemStreamWriter {
public static final Duration DEFAULT_WAIT_TIMEOUT = Duration.ofSeconds(1);
private int waitReplicas;
private Duration waitTimeout = DEFAULT_WAIT_TIMEOUT;
private boolean multiExec;
private Operation operation;
public OperationItemWriter(AbstractRedisClient client, RedisCodec codec) {
super(client, codec);
}
public OperationItemWriter(AbstractRedisClient client, RedisCodec codec, Operation operation) {
super(client, codec);
this.operation = operation;
}
public void setWaitReplicas(int replicas) {
this.waitReplicas = replicas;
}
public void setWaitTimeout(Duration timeout) {
this.waitTimeout = timeout;
}
public void setMultiExec(boolean multiExec) {
this.multiExec = multiExec;
}
public void setOperation(Operation operation) {
this.operation = operation;
}
@Override
public void write(List extends T> items) throws Exception {
execute(items);
}
@SuppressWarnings("unchecked")
@Override
protected void execute(BaseRedisAsyncCommands commands, Collection extends T> items, List> futures) {
if (multiExec) {
futures.add(((RedisTransactionalAsyncCommands) commands).multi());
}
super.execute(commands, items, futures);
if (waitReplicas > 0) {
RedisFuture waitFuture = commands.waitForReplication(waitReplicas, waitTimeout.toMillis());
futures.add(new PipelinedRedisFuture<>(waitFuture.thenAccept(this::checkReplicas)));
}
if (multiExec) {
futures.add(((RedisTransactionalAsyncCommands) commands).exec());
}
}
@Override
protected void execute(BaseRedisAsyncCommands commands, T item, List> futures) {
operation.execute(commands, item, futures);
}
private void checkReplicas(Long actual) {
if (actual == null || actual < waitReplicas) {
throw new RedisCommandExecutionException(
MessageFormat.format("Insufficient replication level ({0}/{1})", actual, waitReplicas));
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy