/*
* Copyright 2008-2108 amoeba.meidusa.com
*
* This program is free software; you can redistribute it and/or modify it under the terms of
* the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU AFFERO GENERAL PUBLIC LICENSE for more details.
* You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package com.meidusa.amoeba.mysql.handler;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.meidusa.amoeba.context.ProxyRuntimeContext;
import com.meidusa.amoeba.mysql.handler.session.CommandStatus;
import com.meidusa.amoeba.mysql.handler.session.ConnectionStatuts;
import com.meidusa.amoeba.mysql.handler.session.SessionStatus;
import com.meidusa.amoeba.mysql.net.CommandInfo;
import com.meidusa.amoeba.mysql.net.MysqlClientConnection;
import com.meidusa.amoeba.mysql.net.MysqlConnection;
import com.meidusa.amoeba.mysql.net.MysqlServerConnection;
import com.meidusa.amoeba.mysql.net.packet.CommandPacket;
import com.meidusa.amoeba.mysql.net.packet.ErrorPacket;
import com.meidusa.amoeba.mysql.net.packet.MysqlPacketBuffer;
import com.meidusa.amoeba.mysql.net.packet.OkPacket;
import com.meidusa.amoeba.mysql.net.packet.QueryCommandPacket;
import com.meidusa.amoeba.net.Connection;
import com.meidusa.amoeba.net.MessageHandler;
import com.meidusa.amoeba.net.Sessionable;
import com.meidusa.amoeba.net.packet.AbstractPacketBuffer;
import com.meidusa.amoeba.net.packet.PacketBuffer;
import com.meidusa.amoeba.net.poolable.ObjectPool;
import com.meidusa.amoeba.net.poolable.PoolableObject;
import com.meidusa.amoeba.parser.statement.CallStatement;
import com.meidusa.amoeba.parser.statement.DMLStatement;
import com.meidusa.amoeba.parser.statement.Statement;
import com.meidusa.amoeba.util.Reporter;
import com.meidusa.amoeba.util.StringUtil;
/**
*
* @author <a href=mailto:piratebase@sina.com>Struct chen</a>
*
*/
public abstract class CommandMessageHandler implements MessageHandler,Sessionable,Reporter.SubReporter {
static Logger logger = Logger.getLogger(CommandMessageHandler.class);
protected MysqlClientConnection source;
private boolean completed;
private long createTime;
private long timeout;
private long endTime;
private boolean ended = false;
protected CommandQueue commandQueue;
private boolean forceEnded = false;
private ObjectPool[] pools;
private CommandInfo info = new CommandInfo();
protected byte commandType;
protected Map<Connection,MessageHandler> handlerMap = Collections.synchronizedMap(new HashMap<Connection,MessageHandler>());
private PacketBuffer buffer = new AbstractPacketBuffer(10240);
private boolean started;
private long lastTimeMillis = System.currentTimeMillis();
private ErrorPacket errorPacket;
protected Statement statment;
private QueryCommandPacket command = new QueryCommandPacket();
public CommandMessageHandler(final MysqlClientConnection source,byte[] query,Statement statment, ObjectPool[] pools,long timeout){
commandQueue = new CommandQueue(source,statment);
command.init(query,source);
this.pools = pools;
info.setBuffer(query);
info.setMain(true);
this.statment = statment;
this.source = source;
this.createTime = System.currentTimeMillis();
this.timeout = timeout;
}
public boolean isMultiplayer(){
return commandQueue.isMultiple();
}
/**
* �жϱ�handled��Connection ��Ϣ�����Ƿ����
* @return
*/
public boolean isCompleted(){
return completed;
}
/**
* ��Ҫ��Ϊ�˷�������� �� �ͻ������ӵĻ���һ�£����磬��ǰ��schema ��charset�ȣ�
*
* �ڷ���������֮ǰ��Ԥ����Ҫ����һЩ������������sourceConnection��destConnection ��ǰ��database��һ�£���Ҫ����init_db Command
* Ϊ�˼��ٸ��Ӷȣ�ֻҪһ��Connection��Ҫ���������ô�������Ӷ����뷢��һ����ͬ�����
*
* @param sourceMysql
* @param destMysqlConn
*/
//TODO ��Ҫ�����Ż�
protected void appendPreMainCommand(){
Set<MysqlServerConnection> connSet = commandQueue.connStatusMap.keySet();
final MysqlConnection sourceMysql =(MysqlConnection) source;
for(Connection destConn : connSet){
MysqlConnection destMysqlConn = (MysqlConnection)destConn;
if(!StringUtil.equalsIgnoreCase(sourceMysql.getSchema(), destMysqlConn.getSchema())){
if(sourceMysql.getSchema() != null){
QueryCommandPacket selectDBCommand = new QueryCommandPacket();
selectDBCommand.query = sourceMysql.getSchema();
selectDBCommand.command = QueryCommandPacket.COM_INIT_DB;
byte[] buffer = selectDBCommand.toByteBuffer(destMysqlConn).array();
CommandInfo info = new CommandInfo();
info.setBuffer(buffer);
info.setMain(false);
info.setRunnable(new Runnable(){
public void run() {
Set<MysqlServerConnection> connSet = commandQueue.connStatusMap.keySet();
for(Connection conn : connSet){
((MysqlConnection)conn).setSchema(sourceMysql.getSchema());
}
}
});
commandQueue.appendCommand(info,true);
}
}
if(sourceMysql.getCharset()!= null &&
!StringUtil.equalsIgnoreCase(sourceMysql.getCharset(),destMysqlConn.getCharset())){
QueryCommandPacket charsetCommand = new QueryCommandPacket();
charsetCommand.query = "set names " + sourceMysql.getCharset();
charsetCommand.command = QueryCommandPacket.COM_QUERY;
byte[] buffer = charsetCommand.toByteBuffer(sourceMysql).array();
CommandInfo info = new CommandInfo();
info.setBuffer(buffer);
info.setMain(false);
info.setRunnable(new Runnable(){
public void run() {
Set<MysqlServerConnection> connSet = commandQueue.connStatusMap.keySet();
for(Connection conn : connSet){
((MysqlConnection)conn).setCharset(sourceMysql.getCharset());
}
}
});
commandQueue.appendCommand(info,true);
}
if(sourceMysql.isAutoCommit() != destMysqlConn.isAutoCommit()){
QueryCommandPacket charsetCommand = new QueryCommandPacket();
charsetCommand.query = "set autocommit = " + (sourceMysql.isAutoCommit()?1:0);
charsetCommand.command = QueryCommandPacket.COM_QUERY;
byte[] buffer = charsetCommand.toByteBuffer(sourceMysql).array();
CommandInfo info = new CommandInfo();
info.setBuffer(buffer);
info.setMain(false);
info.setRunnable(new Runnable(){
public void run() {
Set<MysqlServerConnection> connSet = commandQueue.connStatusMap.keySet();
for(Connection conn : connSet){
((MysqlConnection)conn).setAutoCommit(sourceMysql.isAutoCommit());
}
}
});
commandQueue.appendCommand(info,true);
}
}
}
/**
* this method will be invoked after main command response completed
* @param conn
*/
protected void afterCommand(MysqlServerConnection conn,CommandStatus commStatus){
}
public synchronized void handleMessage(Connection fromConn) {
byte[] message = null;
lastTimeMillis = System.currentTimeMillis();
if(fromConn == source){
while((message = fromConn.getInQueue().getNonBlocking()) != null){
CommandInfo info = new CommandInfo();
info.setBuffer(message);
info.setMain(true);
if(!commandQueue.appendCommand(info,false)){
dispatchMessageFrom(source,message);
}
logger.error("handle message from client after session started,handler="+this+", packet=\n"+StringUtil.dumpAsHex(message, message.length));
}
}else{
while((message = fromConn.getInQueue().getNonBlocking()) != null){
//�ж������Ƿ������
CommandStatus commStatus = commandQueue.checkResponseCompleted(fromConn, message);
if(CommandStatus.AllCompleted == commStatus || CommandStatus.ConnectionCompleted == commStatus){
//��¼ prepared statement ID ���� close statement
afterCommand((MysqlServerConnection)fromConn,commStatus);
if(commandQueue.currentCommand.isMain() || this.ended){
//mysqlServer connection return to pool
releaseConnection(fromConn);
}
if(this.ended){
return;
}
}
if(CommandStatus.AllCompleted == commStatus){
ConnectionStatuts fromConnStatus = commandQueue.connStatusMap.get(fromConn);
try{
/**
* ����ǿͻ��������������:
* 1�������Ƕ�̨server�ģ���Ҫ���кϲ�����
* 2����̨serverֱ��д�����ͻ���
*/
if(commandQueue.currentCommand.isMain()){
commandQueue.mainCommandExecuted = true;
if(commandQueue.isMultiple()){
if(fromConnStatus.isMerged){
List<byte[]> list = this.mergeMessages();
if(list != null){
for(byte[] buffer : list){
dispatchMessageFrom(fromConn,buffer);
}
}
}
}else{
dispatchMessageFrom(fromConn,message);
}
}else{
//����������Ժس�����Ϣ���������ǰ��session
Collection<ConnectionStatuts> connectionStatutsSet = commandQueue.connStatusMap.values();
for(ConnectionStatuts connStatus : connectionStatutsSet){
//���Ƿ�ÿ�����������ص����ݰ���û���쳣��Ϣ��
if(connStatus.errorPacket != null){
this.commandQueue.currentCommand.setStatusCode(connStatus.statusCode);
if(!commandQueue.mainCommandExecuted){
dispatchMessageFrom(connStatus.conn,connStatus.errorPacket.toByteBuffer(connStatus.conn).array());
if(source.isAutoCommit()){
this.endSession(false);
}
}else{
if(logger.isDebugEnabled()){
byte[] commandBuffer = commandQueue.currentCommand.getBuffer();
StringBuffer buffer = new StringBuffer();
buffer.append("Current Command Execute Error:\n");
buffer.append(StringUtil.dumpAsHex(commandBuffer,commandBuffer.length));
buffer.append("\n error Packet:\n");
buffer.append(connStatus.errorPacket.toString());
logger.debug(buffer.toString());
}
}
return;
}
}
}
}finally{
if(fromConnStatus.isMerged){
afterCommandCompleted(commandQueue.currentCommand);
}
}
}else{
if(commandQueue.currentCommand.isMain()){
if(!commandQueue.isMultiple()){
dispatchMessageFrom(fromConn,message);
}
}
}
}
}
}
/**
* ��һ�����������ʱ������������ݰ������ҳ��Է�����һ��command
* ���������û������������ǰ�ػ�
* @param oldCommand ��ǰ��command
*/
protected synchronized void afterCommandCompleted(CommandInfo oldCommand){
if(this.commandQueue.currentCommand != oldCommand){
return;
}
if(oldCommand.getRunnable()!= null){
oldCommand.getRunnable().run();
}
commandQueue.clearAllBuffer();
//��һ����������һ�����ݰ������ǰ������Ӷ�����ɾ����
commandQueue.sessionInitQueryQueue.remove(0);
if(!ended){
startNextCommand();
}
}
//�ж��Ƿ���Ҫ����������һ���ͻ�������
//������һ������
protected synchronized void startNextCommand(){
if(commandQueue.currentCommand != null && (commandQueue.currentCommand.getStatusCode() & SessionStatus.ERROR) >0){
if(source.isAutoCommit()){
this.endSession(false);
}
return;
}
if(!this.ended && commandQueue.tryNextCommandTuple()){
commandType = commandQueue.currentCommand.getBuffer()[4];
Collection<ConnectionStatuts> connSet = commandQueue.connStatusMap.values();
boolean commandCompleted = commandQueue.currentCommand.getCompletedCount().get() == commandQueue.connStatusMap.size();
boolean isProcedure = false;
if(statment instanceof DMLStatement){
DMLStatement dmlStatement = (DMLStatement)statment;
isProcedure = dmlStatement.isProcedure();
}
for(ConnectionStatuts status : connSet){
if(commandQueue.currentCommand.isMain() && isProcedure){
status.setCommandType(commandType,true);
}else{
status.setCommandType(commandType,false);
}
}
dispatchMessageFrom(source,commandQueue.currentCommand.getBuffer());
if(commandCompleted){
afterCommandCompleted(commandQueue.currentCommand);
}
}else{
if(source.isAutoCommit()){
this.endSession(false);
}
}
}
/**
* <pre>
* �κ���handler������Ҫ���͵�Ŀ�����ӵ����ݰ��������ø÷������ͳ�ȥ��
* �ӷ������˷���������Ϣ���ͻ��ˣ����ߴӿͻ��˷����������mysql server��
*
* �����Ҫ���͵���Ϣ��2�֣�
* 1���ӿͻ��˷���������Ϣ
* 2��reponse��ǰ����Ҫ����ǿͻ��˷���������������Ǹ�proxy�ڲ���������������ݰ�
* ����2�����ݰ�ͨ��dispatchMessage �������ͳ�ȥ�ġ�
* ���ڲ��������������ݰ������� afterCommandCompleted()֮�� ����ConnectionStatus.buffers�б��档
* commandQueue.clearAllBuffer() �Ժ�buffers �������
* </pre>
* @param fromServer �Ƿ��Ǵ�mysql server �˷�������
* @param message ��Ϣ����
*/
protected void dispatchMessageFrom(Connection fromConn,byte[] message){
if(fromConn != source){
dispatchMessageTo(source,message);
}else{
Collection<MysqlServerConnection> connSet = commandQueue.connStatusMap.keySet();
for(Connection conn : connSet){
dispatchMessageTo(conn,message);
}
}
}
/**
* ���������һЩ������ƣ�����С���ݰ�Ƶ������ ϵͳwrite, CommandMessageHandler��������������ͨ���÷����������ݰ�
* @param toConn
* @param message
*/
protected void dispatchMessageTo(Connection toConn,byte[] message){
if(toConn == source){
if(message != null){
appendBufferToWrite(message,buffer,toConn,false);
}else{
appendBufferToWrite(message,buffer,toConn,true);
}
}else{
toConn.postMessage(message);
}
}
/**
* ����д���ݵ�Ŀ�ĵ�
* @param byts
* @param buffer
* @param conn
* @param writeNow
* @return
*/
private synchronized boolean appendBufferToWrite(byte[] byts,PacketBuffer buffer,Connection conn,boolean writeNow){
if(byts == null){
if(buffer.getPosition()>0){
conn.postMessage(buffer.toByteBuffer());
buffer.reset();
}
return true;
}else{
if(writeNow || buffer.remaining() < byts.length){
if(buffer.getPosition()>0){
buffer.writeBytes(byts);
conn.postMessage(buffer.toByteBuffer());
buffer.reset();
}else{
conn.postMessage(byts);
}
return true;
}else{
buffer.writeBytes(byts);
return true;
}
}
}
protected synchronized void releaseConnection(Connection conn){
MessageHandler handler = handlerMap.remove(conn);
if(handler != null){
conn.setMessageHandler(handler);
}
if(conn instanceof MysqlServerConnection){
PoolableObject pooledObject = (PoolableObject)conn;
if(pooledObject.getObjectPool() != null && pooledObject.isActive()){
try {
pooledObject.getObjectPool().returnObject(conn);
if(logger.isDebugEnabled()){
logger.debug("connection:"+conn+" return to pool");
}
} catch (Exception e) {
}
}
}
}
/**
* �رո�messageHandler ���һָ��������messageHandler��handle��Connection
*/
protected void releaseAllCompletedConnection(){
Set<Map.Entry<Connection,MessageHandler>> handlerSet = handlerMap.entrySet();
for(Map.Entry<Connection,MessageHandler> entry:handlerSet){
MessageHandler handler = entry.getValue();
Connection connection = entry.getKey();
ConnectionStatuts status = this.commandQueue.connStatusMap.get(connection);
if(this.commandQueue.currentCommand == null || !isStarted() || (status != null && (status.statusCode & SessionStatus.COMPLETED)>0)){
connection.setMessageHandler(handler);
if(!connection.isClosed()){
if(connection instanceof MysqlServerConnection){
PoolableObject pooledObject = (PoolableObject)connection;
if(pooledObject.getObjectPool() != null){
try {
pooledObject.getObjectPool().returnObject(connection);
if(logger.isDebugEnabled()){
logger.debug("connection:"+connection+" return to pool");
}
} catch (Exception e) {
}
}
}
}
}else{
}
}
}
/**
* �ϲ������˵���Ϣ�����͵��ͻ���
* ֻ���ڶ����ӵ��������Ҫ�������ݰ��ۺϣ��ۺ��Ժ���һ�����ݰ�ͨ�� {@link #dispatchMessageFrom(Connection, byte[])}�������ͳ�ȥ,
* һ��һ������ֱ��ͨ��{@link #dispatchMessageFrom(Connection, byte[])} ���� ֱ�ӷ��ͳ�ȥ,������Ҫmerge��
* @return
*/
protected synchronized List<byte[]> mergeMessages(){
if(this.commandQueue.currentCommand.isMerged()){
return null;
}
this.commandQueue.currentCommand.setMerged(true);
Collection<ConnectionStatuts> connectionStatutsSet = commandQueue.connStatusMap.values();
/**
* ��ʾ�Ƿؾ��в�ѯ���������
*/
boolean isSelectQuery = true;
boolean isCall = false;
List<byte[]> buffers = null;
List<byte[]> returnList = new ArrayList<byte[]>();
for(ConnectionStatuts connStatus : connectionStatutsSet){
//���Ƿ�ÿ�����������ص����ݰ���û���쳣��Ϣ��
if(connStatus.buffers.size() ==0){
for(ConnectionStatuts connStatus1 : connectionStatutsSet){
StringBuffer buffer = new StringBuffer();
buffer.append("<---connection="+connStatus1.conn.getInetAddress()+"=="+connStatus1.conn.getInetAddress()+"------->\n");
for(byte[] buf : connStatus1.buffers){
buffer.append(StringUtil.dumpAsHex(buf,buf.length)+"\n");
buffer.append("------------\n");
}
buffer.append("<----error Packet:"+connStatus1.conn.getInetAddress()+"------>\n");
logger.error(buffer.toString());
}
continue;
}
buffers = connStatus.buffers;
if((connStatus.statusCode & SessionStatus.ERROR) >0){
return buffers;
}
}
if(commandQueue.statment instanceof DMLStatement){
DMLStatement dmlStatement = (DMLStatement)commandQueue.statment;
if(this.commandQueue.currentCommand.isMain()){
isCall = dmlStatement.isProcedure();
}
}
//�������ж��Ƿ��Ǹ��²������Dz�ѯ����
if(!isCall){
isSelectQuery = MysqlPacketBuffer.isEofPacket(buffers.get(buffers.size()-1));
}else{
isSelectQuery = !MysqlPacketBuffer.isOkPacket(buffers.get(0));
}
if(isSelectQuery){
//��ǰ��packetId
byte paketId = 0;
//����field��Ϣ
for(byte[] buffer : buffers){
if(MysqlPacketBuffer.isEofPacket(buffer)){
returnList.add(buffer);
paketId = buffer[3];
break;
}else{
returnList.add(buffer);
paketId = buffer[3];
}
}
paketId += 1;
//����rows���ݰ�
for(ConnectionStatuts connStatus : connectionStatutsSet){
boolean rowStart = false;
boolean isRowEnd = false;
for(byte[] buffer : connStatus.buffers){
if(!rowStart){
if(MysqlPacketBuffer.isEofPacket(buffer)){
rowStart = true;
}else{
continue;
}
}else{
if(!MysqlPacketBuffer.isEofPacket(buffer)){
if(!isRowEnd){
buffer[3] = paketId;
paketId += 1;
returnList.add(buffer);
}
}else{
isRowEnd = true;
}
}
}
}
if(!isCall){
byte[] eofBuffer = buffers.get(buffers.size()-1);
eofBuffer[3] = paketId;
returnList.add(eofBuffer);
}else{
byte[] eofBuffer = buffers.get(buffers.size()-2);
eofBuffer[3] = paketId;
returnList.add(eofBuffer);
paketId ++;
byte[] okBuffer = buffers.get(buffers.size()-1);
okBuffer[3] = paketId;
returnList.add(okBuffer);
}
}else{
OkPacket ok = new OkPacket();
StringBuffer strbuffer = new StringBuffer();
for(ConnectionStatuts connStatus : connectionStatutsSet){
byte[] buffer = connStatus.buffers.get(connStatus.buffers.size()-1);
OkPacket connOK = new OkPacket();
connOK.init(buffer,connStatus.conn);
ok.affectedRows +=connOK.affectedRows;
ok.insertId =connOK.insertId;
ok.packetId = 1;
strbuffer.append(connOK.message);
ok.warningCount +=connOK.warningCount;
}
ok.message = strbuffer.toString();
returnList.add(ok.toByteBuffer(source).array());
}
return returnList;
}
protected abstract ConnectionStatuts newConnectionStatuts(Connection conn);
public boolean isStarted(){
return this.started;
}
public synchronized void startSession() throws Exception {
if(logger.isInfoEnabled()){
logger.info("session start[type="+this.command.command+"]:ip="+this.source.getSocketId()+",handlerId="+this.hashCode()
+",time="+(System.currentTimeMillis()-createTime)
+",sql="+(this.statment ==null?null:this.statment.getSql()));
}
for(ObjectPool pool:pools){
MysqlServerConnection conn;
conn = (MysqlServerConnection)pool.borrowObject();
handlerMap.put(conn, conn.getMessageHandler());
if(conn.getMessageHandler() instanceof CommandMessageHandler){
logger.error("current handler="+conn.getMessageHandler().toString()+",");
}
conn.setMessageHandler(this);
commandQueue.connStatusMap.put(conn, newConnectionStatuts(conn));
}
this.started = true;
appendPreMainCommand();
this.commandQueue.appendCommand(info, true);
startNextCommand();
}
public boolean checkIdle(long now) {
if(timeout >0){
return (now - createTime)>timeout;
}else{
if(ended){
/**
* �����session�Ѿ���������ʱ���serverConnection�˻��ڵȴ��������ݷ��ʡ����ҳ���15s,����Ҫ�����еĻỰ
* �������ڸ���ԭ����ɷ�������û�з������ݻ����Ѿ������ĻỰ��ServerConnection������Pool�С�
*/
return (now - endTime)>15000;
}else{
return (now - lastTimeMillis) > ProxyRuntimeContext.getInstance().getRuntimeContext().getQueryTimeout() * 1000;
}
}
}
public void endSession(boolean force) {
if(!isEnded()){
synchronized (this) {
if(!ended){
forceEnded = force;
endTime = System.currentTimeMillis();
ended = true;
}else{
return;
}
}
}
this.releaseAllCompletedConnection();
if(!this.commandQueue.mainCommandExecuted){
StringBuffer buffer = new StringBuffer();
buffer.append("<<---client connection="+source.getSocketId()+",source handler ischanged="+(source.getMessageHandler()==this)+",\n session Handler="+this+"----->>\n");
for(Map.Entry<MysqlServerConnection, ConnectionStatuts> entry : commandQueue.connStatusMap.entrySet()){
if((entry.getValue().statusCode & SessionStatus.COMPLETED) == 0){
buffer.append("<----start-connection="+entry.getKey().getSocketId()
+",queueSize="+entry.getKey().getInQueueSize()
+",manager="+entry.getKey().getConnectionManager().getName()
+",managerRunning="+entry.getKey().getConnectionManager().isRunning()
+",selectorOpened="+entry.getKey().getConnectionManager().getSelector().isOpen()+"-------\n");
for(byte[] buf : entry.getValue().buffers){
buffer.append(StringUtil.dumpAsHex(buf,buf.length)+"\n");
buffer.append("\n");
}
buffer.append("<----end connection:"+entry.getKey().getSocketId()+"------>\n");
}else{
buffer.append("<----start -- end Packet:"+entry.getKey().getSocketId()+",COMPLETED = true------>\n");
}
if(force){
entry.getKey().postClose(null);
}
logger.error(buffer.toString());
}
if(this.errorPacket == null){
errorPacket = new ErrorPacket();
errorPacket.errno = 10000;
errorPacket.packetId = 2;
errorPacket.serverErrorMessage = " session was killed!!";
this.dispatchMessageTo(source, errorPacket.toByteBuffer(source).array());
logger.warn("session was killed!!",new Exception());
}
source.postClose(null);
}else{
if(logger.isInfoEnabled()){
logger.info("session end[type="+this.command.command+"]:ip="+this.source.getSocketId()
+",handlerId="+this.hashCode()
+",sql="+(this.statment ==null?null:this.statment.getSql()));
}
}
this.dispatchMessageTo(source,null);
}
public synchronized boolean isEnded() {
return this.ended;
}
public void appendReport(StringBuilder buffer, long now, long sinceLast,boolean reset,Level level) {
buffer.append(" -- MessageHandler:").append("multiple Size:").append(commandQueue.connStatusMap.size());
if(commandQueue.currentCommand != null){
buffer.append(",currentCommand completedCount:");
buffer.append(commandQueue.currentCommand.getCompletedCount()).append("\n");
}else{
buffer.append("\n");
}
}
public String toString(){
StringBuffer buffer = new StringBuffer();
buffer.append("class=").append(this.getClass().getName());
buffer.append(",createTime=").append(createTime);
buffer.append(",endTime=").append(this.endTime);
buffer.append(",lastTimeMillis=").append(this.lastTimeMillis);
buffer.append(",ended=").append(this.ended );
buffer.append(",forceEnded=").append(this.forceEnded );
buffer.append(",started=").append(this.started );
buffer.append(",ServerConnectionSize=").append(this.handlerMap.size());
if(commandQueue.currentCommand != null){
buffer.append(",currentCommand[").append("CompletedCount=").append(this.commandQueue.currentCommand != null ?this.commandQueue.currentCommand.getCompletedCount().get():"");
buffer.append(",buffer=\n").append(StringUtil.dumpAsHex(commandQueue.currentCommand.getBuffer(),commandQueue.currentCommand.getBuffer().length));
}
buffer.append(", sql=").append(statment!= null?statment.getSql():"null");
return buffer.toString();
}
}