package fm.liu.timo.server.session.handler;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.pmw.tinylog.Logger;
import fm.liu.timo.config.ErrorCode;
import fm.liu.timo.mysql.packet.ErrorPacket;
import fm.liu.timo.net.connection.BackendConnection;
import fm.liu.timo.server.session.Session;
/**
* @author liuhuanting
*/
public class CommitHandler extends SessionResultHandler {
private final ConcurrentHashMap<Integer, Boolean> results = new ConcurrentHashMap<>();
public CommitHandler(Session session, Collection<BackendConnection> cons) {
this.session = session;
this.count = new AtomicInteger(cons.size());
for (BackendConnection con : cons) {
results.put(con.getDatanodeID(), false);
}
}
@Override
public void ok(byte[] ok, BackendConnection con) {
results.replace(con.getDatanodeID(), true);
if (decrement()) {
if (failed()) {
error();
return;
}
session.clear();
session.getFront().write(ok);
recycleResources();
}
}
private void error() {
session.clear();
StringBuilder success = new StringBuilder();
StringBuilder failed = new StringBuilder();
for (Entry<Integer, Boolean> entry : results.entrySet()) {
if (entry.getValue()) {
if (success.length() > 0) {
success.append(",");
}
success.append(entry.getKey());
} else {
if (failed.length() > 0) {
failed.append(",");
}
failed.append(entry.getKey());
}
}
StringBuilder msg = new StringBuilder("transaction error. success nodes: {");
msg.append(success.toString()).append("}, failed nodes :{").append(failed.toString())
.append(". error message is :").append(this.errMsg);
session.getFront().writeErrMessage(ErrorCode.ER_YES, msg.toString());
recycleResources();
}
@Override
public void error(byte[] error, BackendConnection con) {
ErrorPacket err = new ErrorPacket();
err.read(error);
String message = new String(err.message);
Logger.warn("error :{} received from :{} when commit", con, message);
this.setFail(err.errno, message);
session.release(con);
if (decrement()) {
error();
}
}
@Override
public void field(byte[] header, List<byte[]> fields, byte[] eof, BackendConnection con) {}
@Override
public void row(byte[] row, BackendConnection con) {}
@Override
public void eof(byte[] eof, BackendConnection con) {}
@Override
public void close(String reason) {
this.setFail(ErrorCode.ER_YES, reason);
if (decrement()) {
error();
}
}
}