use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class MultiNodeExecutor method execute0.
/**
* 执行
*/
private void execute0(RouteResultsetNode rrn, Channel c, boolean autocommit, BlockingSession ss, int flag) {
ServerConnection sc = ss.getSource();
if (isFail.get() || sc.isClosed()) {
c.setRunning(false);
handleFailure(ss, rrn, null);
return;
}
try {
// 执行并等待返回
BinaryPacket bin = ((MySQLChannel) c).execute(rrn, sc, autocommit);
// 接收和处理数据
final ReentrantLock lock = MultiNodeExecutor.this.lock;
lock.lock();
try {
switch(bin.data[0]) {
case ErrorPacket.FIELD_COUNT:
c.setRunning(false);
handleFailure(ss, rrn, new BinaryErrInfo((MySQLChannel) c, bin, sc, rrn));
break;
case OkPacket.FIELD_COUNT:
OkPacket ok = new OkPacket();
ok.read(bin);
affectedRows += ok.affectedRows;
// set lastInsertId
if (ok.insertId > 0) {
insertId = (insertId == 0) ? ok.insertId : Math.min(insertId, ok.insertId);
}
c.setRunning(false);
handleSuccessOK(ss, rrn, autocommit, ok);
break;
default:
// HEADER|FIELDS|FIELD_EOF|ROWS|LAST_EOF
final MySQLChannel mc = (MySQLChannel) c;
if (fieldEOF) {
for (; ; ) {
bin = mc.receive();
switch(bin.data[0]) {
case ErrorPacket.FIELD_COUNT:
c.setRunning(false);
handleFailure(ss, rrn, new BinaryErrInfo(mc, bin, sc, rrn));
return;
case EOFPacket.FIELD_COUNT:
handleRowData(rrn, c, ss);
return;
default:
continue;
}
}
} else {
// HEADER
bin.packetId = ++packetId;
List<MySQLPacket> headerList = new LinkedList<MySQLPacket>();
headerList.add(bin);
for (; ; ) {
bin = mc.receive();
switch(bin.data[0]) {
case ErrorPacket.FIELD_COUNT:
c.setRunning(false);
handleFailure(ss, rrn, new BinaryErrInfo(mc, bin, sc, rrn));
return;
case EOFPacket.FIELD_COUNT:
// FIELD_EOF
bin.packetId = ++packetId;
for (MySQLPacket packet : headerList) {
buffer = packet.write(buffer, sc);
}
headerList = null;
buffer = bin.write(buffer, sc);
fieldEOF = true;
handleRowData(rrn, c, ss);
return;
default:
// FIELDS
bin.packetId = ++packetId;
switch(flag) {
case RouteResultset.REWRITE_FIELD:
StringBuilder fieldName = new StringBuilder();
fieldName.append("Tables_in_").append(ss.getSource().getSchema());
FieldPacket field = PacketUtil.getField(bin, fieldName.toString());
headerList.add(field);
break;
default:
headerList.add(bin);
}
}
}
}
}
} finally {
lock.unlock();
}
} catch (final IOException e) {
c.close();
handleFailure(ss, rrn, new SimpleErrInfo(e, ErrorCode.ER_YES, sc, rrn));
} catch (final RuntimeException e) {
c.close();
handleFailure(ss, rrn, new SimpleErrInfo(e, ErrorCode.ER_YES, sc, rrn));
}
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class MultiNodeExecutor method handleNext.
/**
* 处理下一个任务
*/
private void handleNext(final RouteResultsetNode rrn, final Channel c, final BlockingSession ss) {
final ServerConnection sc = ss.getSource();
sc.getProcessor().getExecutor().execute(new Runnable() {
@Override
public void run() {
final ReentrantLock lock = MultiNodeExecutor.this.lock;
lock.lock();
try {
handleRowData(rrn, c, ss);
} catch (final IOException e) {
c.close();
handleFailure(ss, rrn, new SimpleErrInfo(e, ErrorCode.ER_YES, sc, rrn));
} catch (final RuntimeException e) {
c.close();
handleFailure(ss, rrn, new SimpleErrInfo(e, ErrorCode.ER_YES, sc, rrn));
} finally {
lock.unlock();
}
}
});
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class MultiNodeExecutor method newExecute.
/**
* 新通道的执行
*/
private void newExecute(final RouteResultsetNode rrn, final boolean autocommit, final BlockingSession ss, final int flag) {
final ServerConnection sc = ss.getSource();
// 检查数据节点是否存在
CobarConfig conf = CobarServer.getInstance().getConfig();
final MySQLDataNode dn = conf.getDataNodes().get(rrn.getName());
if (dn == null) {
handleFailure(ss, rrn, new SimpleErrInfo(new UnknownDataNodeException("Unknown dataNode '" + rrn.getName() + "'"), ErrorCode.ER_BAD_DB_ERROR, sc, rrn));
return;
}
// 提交执行任务
sc.getProcessor().getExecutor().execute(new Runnable() {
@Override
public void run() {
// 取得数据通道
int i = rrn.getReplicaIndex();
Channel c = null;
try {
c = (i == DEFAULT_REPLICA_INDEX) ? dn.getChannel() : dn.getChannel(i);
} catch (final Exception e) {
handleFailure(ss, rrn, new SimpleErrInfo(e, ErrorCode.ER_BAD_DB_ERROR, sc, rrn));
return;
}
c.setRunning(true);
Channel old = ss.getTarget().put(rrn, c);
if (old != null && c != old) {
old.close();
}
// 执行
execute0(rrn, c, autocommit, ss, flag);
}
});
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class MultiNodeExecutor method handleSuccessEOF.
/**
* @throws nothing never throws any exception
*/
private void handleSuccessEOF(BlockingSession ss, BinaryPacket bin) {
if (decrementCountAndIsZero()) {
if (isFail.get()) {
notifyFailure(ss);
return;
}
try {
ServerConnection source = ss.getSource();
if (source.isAutocommit()) {
ss.release();
}
// LAST_EOF
bin.packetId = ++packetId;
source.write(bin.write(buffer, source));
} catch (Exception e) {
LOGGER.warn("exception happens in success notification: " + ss.getSource(), e);
}
}
}
use of com.alibaba.cobar.server.ServerConnection in project cobar by alibaba.
the class CommitNodeHandler method okResponse.
@Override
public void okResponse(byte[] ok, MySQLConnection conn) {
conn.setRunning(false);
if (decrementCountBy(1)) {
if (isFail.get() || session.closed()) {
notifyError((byte) 1);
} else {
session.releaseConnections();
if (okPacket == null) {
ServerConnection source = session.getSource();
source.write(ok);
} else {
okPacket.write(session.getSource());
}
}
}
}
Aggregations