序
本文主要研究一下claudb的server command
SelectCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/SelectCommand.java
@ReadOnly
@Command("select")
@ParamLength(1)
public class SelectCommand implements DBCommand {
@Override
public RedisToken execute(Database db, Request request) {
try {
getSessionState(request.getSession()).setCurrentDB(parseCurrentDB(request));
return responseOk();
} catch (NumberFormatException e) {
return error("ERR invalid DB index");
}
}
private int parseCurrentDB(Request request) {
return parseInt(request.getParam(0).toString());
}
}
SelectCommand实现了DBCommand接口,其execute方法执行getSessionState(request.getSession()).setCurrentDB(parseCurrentDB(request))
SyncCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/SyncCommand.java
@ReadOnly
@Command("sync")
public class SyncCommand implements DBCommand {
private MasterReplication master;
@Override
public RedisToken execute(Database db, Request request) {
try {
DBServerContext server = getClauDB(request.getServerContext());
ByteBufferOutputStream output = new ByteBufferOutputStream();
server.exportRDB(output);
if (master == null) {
master = new MasterReplication(server);
master.start();
}
master.addSlave(request.getSession().getId());
return string(new SafeString(output.toByteArray()));
} catch (IOException e) {
return error("ERROR replication error");
}
}
}
SyncCommand实现了DBCommand接口,其execute方法先通过getClauDB获取server,然后执行server.exportRDB(output)、master.addSlave(request.getSession().getId()),然后返回string(new SafeString(output.toByteArray()))
SlaveOfCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/SlaveOfCommand.java
@ReadOnly
@Command("slaveof")
@ParamLength(2)
public class SlaveOfCommand implements DBCommand {
private SlaveReplication slave;
@Override
public RedisToken execute(Database db, Request request) {
String host = request.getParam(0).toString();
String port = request.getParam(1).toString();
boolean stopCurrent = "NO".equals(host) && "ONE".equals(port);
if (slave == null) {
if (!stopCurrent) {
startReplication(request, host, port);
}
} else {
slave.stop();
if (!stopCurrent) {
startReplication(request, host, port);
}
}
return responseOk();
}
private void startReplication(Request request, String host, String port) {
slave = new SlaveReplication(
getClauDB(request.getServerContext()), request.getSession(), host, Integer.parseInt(port));
slave.start();
}
}
SlaveOfCommand实现了DBCommand接口,其execute方法在非stopCurrent的条件下执行startReplication;startReplication方法创建SlaveReplication,然后执行slave.start()
RoleCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/RoleCommand.java
@ReadOnly
@Command("role")
public class RoleCommand implements DBCommand {
@Override
public RedisToken execute(Database db, Request request) {
DBServerState serverState = getServerState(request.getServerContext());
Database adminDatabase = getAdminDatabase(request.getServerContext());
return serverState.isMaster() ? master(adminDatabase) : slave(adminDatabase);
}
private RedisToken slave(Database adminDatabase) {
ImmutableMap hash = adminDatabase.getHash(safeString("master"));
return array(string("slave"),
string(hash.get(safeString("host")).get()),
integer(hash.get(safeString("port")).map(port -> parseInt(port.toString())).get()),
string(hash.get(safeString("state")).get()), integer(0));
}
private RedisToken master(Database adminDatabase) {
return array(string("master"), integer(0), array(slaves(adminDatabase)));
}
private ImmutableList slaves(Database adminDatabase) {
DatabaseValue value = adminDatabase.getOrDefault(safeKey("slaves"), DatabaseValue.EMPTY_SET);
ImmutableList set = value.getSet().asList().sort(SafeString::compareTo);
return set.map(SafeString::toString)
.map(slave -> slave.split(":"))
.map(slave -> array(string(slave[0]), string(slave[1]), string("0"))).asList();
}
}
RoleCommand实现了DBCommand接口,其execute方法先获取serverState及adminDatabase,然后根据serverState.isMaster()返回master(adminDatabase)或slave(adminDatabase)
FlushDBCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/FlushDBCommand.java
@Command("flushdb")
public class FlushDBCommand implements DBCommand {
@Override
public RedisToken execute(Database db, Request request) {
db.clear();
return responseOk();
}
}
FlushDBCommand实现了DBCommand接口,其execute方法执行db.clear()
DatabaseSizeCommand
claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/server/DatabaseSizeCommand.java
@Command("dbsize")
public class DatabaseSizeCommand implements DBCommand {
@Override
public RedisToken execute(Database db, Request request) {
return integer(db.size());
}
}
DatabaseSizeCommand实现了DBCommand接口,其execute方法返回integer(db.size())
小结
claudb server相关的command有SelectCommand、SyncCommand、SlaveOfCommand、RoleCommand、FlushDBCommand、DatabaseSizeCommand
doc