package com.lambdaworks.redis.masterslave;
import com.lambdaworks.redis.ReadFrom;
import com.lambdaworks.redis.RedisChannelHandler;
import com.lambdaworks.redis.RedisChannelWriter;
import com.lambdaworks.redis.RedisException;
import com.lambdaworks.redis.api.StatefulRedisConnection;
import com.lambdaworks.redis.internal.LettuceAssert;
import com.lambdaworks.redis.protocol.ProtocolKeyword;
import com.lambdaworks.redis.protocol.RedisCommand;
/**
* Channel writer/dispatcher that dispatches commands based on the intent to different connections.
*
* @author Mark Paluch
*/
class MasterSlaveChannelWriter<K, V> implements RedisChannelWriter<K, V> {
private MasterSlaveConnectionProvider<K, V> masterSlaveConnectionProvider;
private boolean closed = false;
public MasterSlaveChannelWriter(MasterSlaveConnectionProvider<K, V> masterSlaveConnectionProvider) {
this.masterSlaveConnectionProvider = masterSlaveConnectionProvider;
}
@Override
public <T, C extends RedisCommand<K, V, T>> C write(C command) {
LettuceAssert.notNull(command, "Command must not be null");
if (closed) {
throw new RedisException("Connection is closed");
}
MasterSlaveConnectionProvider.Intent intent = getIntent(command.getType());
StatefulRedisConnection<K, V> connection = masterSlaveConnectionProvider.getConnection(intent);
return connection.dispatch(command);
}
private MasterSlaveConnectionProvider.Intent getIntent(ProtocolKeyword type) {
for (ProtocolKeyword readOnlyCommand : ReadOnlyCommands.READ_ONLY_COMMANDS) {
if (readOnlyCommand == type) {
return MasterSlaveConnectionProvider.Intent.READ;
}
}
return MasterSlaveConnectionProvider.Intent.WRITE;
}
@Override
public void close() {
if (closed) {
return;
}
closed = true;
if (masterSlaveConnectionProvider != null) {
masterSlaveConnectionProvider.close();
masterSlaveConnectionProvider = null;
}
}
public MasterSlaveConnectionProvider getMasterSlaveConnectionProvider() {
return masterSlaveConnectionProvider;
}
@Override
public void setRedisChannelHandler(RedisChannelHandler<K, V> redisChannelHandler) {
}
@Override
public void setAutoFlushCommands(boolean autoFlush) {
masterSlaveConnectionProvider.setAutoFlushCommands(autoFlush);
}
@Override
public void flushCommands() {
masterSlaveConnectionProvider.flushCommands();
}
@Override
public void reset() {
masterSlaveConnectionProvider.reset();
}
/**
* Set from which nodes data is read. The setting is used as default for read operations on this connection. See the
* documentation for {@link ReadFrom} for more information.
*
* @param readFrom the read from setting, must not be {@literal null}
*/
public void setReadFrom(ReadFrom readFrom) {
masterSlaveConnectionProvider.setReadFrom(readFrom);
}
/**
* Gets the {@link ReadFrom} setting for this connection. Defaults to {@link ReadFrom#MASTER} if not set.
*
* @return the read from setting
*/
public ReadFrom getReadFrom() {
return masterSlaveConnectionProvider.getReadFrom();
}
}