本文次要钻研一下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<SafeString, SafeString> 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<RedisToken> slaves(Database adminDatabase) {    DatabaseValue value = adminDatabase.getOrDefault(safeKey("slaves"), DatabaseValue.EMPTY_SET);    ImmutableList<SafeString> 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

  • SelectCommand