Search in sources :

Example 1 with ResultSetCallBack

use of io.mycat.proxy.callback.ResultSetCallBack in project Mycat2 by MyCATApache.

the class RowSetQuery method runTextQuery.

public static PromiseInternal<SqlResult<Void>> runTextQuery(String curSql, MySQLClientSession mySQLClientSession, StreamMysqlCollector collectorArg) {
    if (mySQLClientSession.getCurNIOHandler() != null) {
        throw new IllegalArgumentException();
    }
    PromiseInternal<SqlResult<Void>> promise = VertxUtil.newPromise();
    if (mySQLClientSession.getIOThread() == Thread.currentThread()) {
        VertxMycatTextCollector<Object, Object> resultSetHandler = new VertxMycatTextCollector<Object, Object>((Collector) collectorArg);
        if (LOGGER.isDebugEnabled()) {
            if (curSql.startsWith("XA ROLLBACK")) {
                LOGGER.debug("session id:{} sql:{}", mySQLClientSession.sessionId(), curSql, new Throwable());
            }
            LOGGER.debug("session id:{} sql:{}", mySQLClientSession.sessionId(), curSql);
        }
        resultSetHandler.request(mySQLClientSession, MySQLCommandType.COM_QUERY, curSql.getBytes(), new ResultSetCallBack<MySQLClientSession>() {

            @Override
            public void onFinishedSendException(Exception exception, Object sender, Object attr) {
                MycatException mycatException = new MycatException(MySQLErrorCode.ER_UNKNOWN_ERROR, exception.getMessage());
                LOGGER.error("session id:{} sql:{}", mySQLClientSession.sessionId(), curSql, mycatException);
                promise.tryFail(mycatException);
            }

            @Override
            public void onFinishedException(Exception exception, Object sender, Object attr) {
                MycatException mycatException = new MycatException(MySQLErrorCode.ER_UNKNOWN_ERROR, exception.getMessage());
                LOGGER.error("session id:{} sql:{}", mySQLClientSession.sessionId(), curSql, mycatException);
                promise.tryFail(mycatException);
            }

            @Override
            public void onFinished(boolean monopolize, MySQLClientSession mysql, Object sender, Object attr) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("onFinished session id:{} sql:{}", mySQLClientSession.sessionId(), curSql);
                }
                MySqlResult<Void> mySqlResult = new MySqlResult<>(resultSetHandler.getRowCount(), resultSetHandler.getAffectedRows(), resultSetHandler.getLastInsertId(), null, Optional.ofNullable(resultSetHandler.getRowResultDecoder()).map(i -> i.rowDesc).map(i -> i.columnDescriptor()).orElse(Collections.emptyList()));
                promise.complete(mySqlResult);
            }

            @Override
            public void onErrorPacket(ErrorPacketImpl errorPacket, boolean monopolize, MySQLClientSession mysql, Object sender, Object attr) {
                MycatException mycatException = new MycatException(errorPacket.getErrorCode(), errorPacket.getErrorMessageString());
                LOGGER.error("onErrorPacket session id:{} sql:{}", mySQLClientSession.sessionId(), curSql, mycatException);
                promise.tryFail(mycatException);
            }
        });
    } else {
        mySQLClientSession.getIOThread().addNIOJob(new NIOJob() {

            @Override
            public void run(ReactorEnvThread reactor) throws Exception {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.error("nio job session id:{} sql:{}", mySQLClientSession.sessionId(), curSql, new Throwable());
                }
                runTextQuery(curSql, mySQLClientSession, collectorArg).onComplete(promise);
            }

            @Override
            public void stop(ReactorEnvThread reactor, Exception reason) {
                promise.tryFail(reason);
            }

            @Override
            public String message() {
                return "proxy query text result set";
            }
        });
    }
    return promise;
}
Also used : MySQLClient(io.vertx.mysqlclient.MySQLClient) LoggerFactory(org.slf4j.LoggerFactory) MySQLRowDesc(io.vertx.mysqlclient.impl.MySQLRowDesc) Function(java.util.function.Function) NIOJob(io.mycat.proxy.reactor.NIOJob) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession) MySQLCommandType(io.mycat.beans.mysql.MySQLCommandType) ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) StreamMysqlCollector(io.vertx.mysqlclient.impl.codec.StreamMysqlCollector) SqlResult(io.vertx.sqlclient.SqlResult) ErrorPacketImpl(io.mycat.beans.mysql.packet.ErrorPacketImpl) MySQLErrorCode(io.mycat.beans.mysql.MySQLErrorCode) RowSet(io.vertx.sqlclient.RowSet) AsyncResult(io.vertx.core.AsyncResult) Collector(java.util.stream.Collector) PromiseInternal(io.vertx.core.impl.future.PromiseInternal) Logger(org.slf4j.Logger) MycatException(io.mycat.MycatException) Query(io.vertx.sqlclient.Query) VertxUtil(io.mycat.util.VertxUtil) Future(io.vertx.core.Future) Row(io.vertx.sqlclient.Row) VertxRowSetImpl(io.vertx.mysqlclient.impl.codec.VertxRowSetImpl) Optional(java.util.Optional) Handler(io.vertx.core.Handler) Collections(java.util.Collections) ResultSetCallBack(io.mycat.proxy.callback.ResultSetCallBack) ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) MycatException(io.mycat.MycatException) SqlResult(io.vertx.sqlclient.SqlResult) NIOJob(io.mycat.proxy.reactor.NIOJob) MycatException(io.mycat.MycatException) ErrorPacketImpl(io.mycat.beans.mysql.packet.ErrorPacketImpl) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Example 2 with ResultSetCallBack

use of io.mycat.proxy.callback.ResultSetCallBack in project Mycat2 by MyCATApache.

the class ResultSetHandler method onSocketRead.

// /**
// * 该方法可能会被重写
// */
// default void onFinishedCollect(MySQLClientSession mysql, boolean success, String errorMessage) {
// ResultSetCallBack callBack = mysql.getCallBackAndReset();
// assert callBack != null;
// if (success) {
// callBack.onFinishedCollect(mysql, this, true, getResult(), null);
// } else {
// callBack.onFinishedCollect(mysql, this, false, errorMessage, null);
// }
// }
/**
 * 读事件处理
 */
@Override
default void onSocketRead(MySQLClientSession mysql) {
    assert mysql.getCurNIOHandler() == this;
    if (!mysql.checkOpen()) {
        ResultSetCallBack callBackAndReset = mysql.getCallBack();
        ClosedChannelException closedChannelException = new ClosedChannelException();
        onException(mysql, closedChannelException);
        callBackAndReset.onFinishedException(closedChannelException, this, null);
        return;
    }
    try {
        MySQLPacketResolver resolver = mysql.getBackendPacketResolver();
        ProxyBuffer proxyBuffer = mysql.currentProxyBuffer();
        proxyBuffer.newBufferIfNeed();
        if (!mysql.readFromChannel()) {
            return;
        }
        mysql.setRequestSuccess(true);
        int totalPacketEndIndex = proxyBuffer.channelReadEndIndex();
        MySQLPacket mySQLPacket = (MySQLPacket) proxyBuffer;
        boolean isResponseFinished = false;
        ErrorPacketImpl errorPacket = null;
        while (mysql.readProxyPayloadFully()) {
            MySQLPayloadType type = mysql.getBackendPacketResolver().getMySQLPayloadType();
            isResponseFinished = mysql.isResponseFinished();
            MySQLPacket payload = mysql.currentProxyPayload();
            int startPos = payload.packetReadStartIndex();
            int endPos = payload.packetReadEndIndex();
            switch(type) {
                case REQUEST:
                    this.onRequest(mySQLPacket, startPos, endPos);
                    break;
                case LOAD_DATA_REQUEST:
                    this.onLoadDataRequest(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_COM_QUERY:
                    this.onRequestComQuery(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_SEND_LONG_DATA:
                    this.onPrepareLongData(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_PREPARE:
                    this.onReqeustPrepareStatement(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_COM_STMT_CLOSE:
                    this.onRequestComStmtClose(mySQLPacket, startPos, endPos);
                    break;
                case FIRST_ERROR:
                    {
                        ErrorPacketImpl packet = new ErrorPacketImpl();
                        errorPacket = packet;
                        packet.readPayload(mySQLPacket);
                        this.onFirstError(packet);
                        break;
                    }
                case FIRST_OK:
                    MycatMonitor.onResultSetEnd(mysql);
                    this.onOk(mySQLPacket, startPos, endPos);
                    break;
                case FIRST_EOF:
                    this.onEof(mySQLPacket, startPos, endPos);
                    break;
                case COLUMN_COUNT:
                    this.onColumnCount(resolver.getColumnCount());
                    break;
                case COLUMN_DEF:
                    this.onColumnDef(mySQLPacket, startPos, endPos);
                    break;
                case COLUMN_EOF:
                    this.onColumnDefEof(mySQLPacket, startPos, endPos);
                    break;
                case TEXT_ROW:
                    this.onTextRow(mySQLPacket, startPos, endPos);
                    break;
                case BINARY_ROW:
                    this.onBinaryRow(mySQLPacket, startPos, endPos);
                    break;
                case ROW_EOF:
                case ROW_OK:
                    MycatMonitor.onResultSetEnd(mysql);
                    this.onRowOk(mySQLPacket, startPos, endPos);
                    break;
                case ROW_ERROR:
                    ErrorPacketImpl packet = new ErrorPacketImpl();
                    errorPacket = packet;
                    packet.readPayload(mySQLPacket);
                    this.onRowError(packet, startPos, endPos);
                    break;
                case PREPARE_OK:
                    this.onPrepareOk(resolver);
                    break;
                case PREPARE_OK_PARAMER_DEF:
                    this.onPrepareOkParameterDef(mySQLPacket, startPos, endPos);
                    break;
                case PREPARE_OK_COLUMN_DEF:
                    this.onPrepareOkColumnDef(mySQLPacket, startPos, endPos);
                    break;
                case PREPARE_OK_COLUMN_DEF_EOF:
                    this.onPrepareOkColumnDefEof(resolver);
                    break;
                case PREPARE_OK_PARAMER_DEF_EOF:
                    this.onPrepareOkParameterDefEof(resolver);
                    break;
            }
            mysql.resetCurrentProxyPayload();
            proxyBuffer.channelReadEndIndex(totalPacketEndIndex);
            if (isResponseFinished) {
                break;
            }
            assert mysql.getCurNIOHandler() == this;
            MySQLPacketResolver packetResolver = mysql.getBackendPacketResolver();
            mySQLPacket.packetReadStartIndex(packetResolver.getEndPos());
        }
        if (isResponseFinished) {
            ByteBuffer allocate = ByteBuffer.allocate(8192);
            if (mysql.channel().read(allocate) > 0) {
                throw new IllegalArgumentException();
            }
            boolean responseFinished = mysql.isResponseFinished();
            mysql.getBackendPacketResolver().setState(MySQLPacketResolver.ComQueryState.QUERY_PACKET);
            ResultSetCallBack callBackAndReset = mysql.getCallBack();
            mysql.setCallBack(null);
            onFinishedCollect(mysql);
            onClear(mysql);
            if (errorPacket == null) {
                callBackAndReset.onFinished(mysql.isMonopolized(), mysql, this, null);
            } else {
                callBackAndReset.onErrorPacket(errorPacket, mysql.isMonopolized(), mysql, this, null);
            }
            return;
        }
    } catch (Exception e) {
        LOGGER.error("", e);
        ResultSetCallBack callBackAndReset = mysql.getCallBack();
        Objects.requireNonNull(callBackAndReset);
        mysql.setCallBack(null);
        if (mysql.isRequestSuccess()) {
            MycatMonitor.onResultSetReadException(mysql, e);
            onFinishedCollectException(mysql, e);
            onException(mysql, e);
            callBackAndReset.onFinishedException(e, this, null);
            return;
        } else {
            MycatMonitor.onResultSetWriteException(mysql, e);
            onFinishedCollectException(mysql, e);
            onException(mysql, e);
            callBackAndReset.onFinishedSendException(e, this, null);
            return;
        }
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) MySQLPayloadType(io.mycat.proxy.packet.MySQLPayloadType) MySQLPacket(io.mycat.beans.mysql.packet.MySQLPacket) ResultSetCallBack(io.mycat.proxy.callback.ResultSetCallBack) ProxyBuffer(io.mycat.beans.mysql.packet.ProxyBuffer) MySQLPacketResolver(io.mycat.proxy.packet.MySQLPacketResolver) ByteBuffer(java.nio.ByteBuffer) ErrorPacketImpl(io.mycat.beans.mysql.packet.ErrorPacketImpl) MycatException(io.mycat.MycatException) ClosedChannelException(java.nio.channels.ClosedChannelException)

Example 3 with ResultSetCallBack

use of io.mycat.proxy.callback.ResultSetCallBack in project Mycat2 by MyCATApache.

the class ResultSetHandler method request.

/**
 * @param packetData 包含报文头部的完整报文(不是payload)
 */
default void request(MySQLClientSession mysql, byte[] packetData, ResultSetCallBack<MySQLClientSession> callBack) {
    try {
        mysql.setCallBack(callBack);
        mysql.switchNioHandler(this);
        assert (mysql.currentProxyBuffer() == null);
        mysql.setCurrentProxyBuffer(new ProxyBufferImpl(mysql.getIOThread().getBufPool()));
        mysql.prepareReveiceResponse();
        mysql.writeProxyBufferToChannel(packetData);
    } catch (Exception e) {
        MycatMonitor.onResultSetWriteException(mysql, e);
        ResultSetCallBack callBackAndReset = mysql.getCallBack();
        onFinishedCollectException(mysql, e);
        onException(mysql, e);
        callBackAndReset.onFinishedException(e, this, null);
    }
}
Also used : ProxyBufferImpl(io.mycat.proxy.buffer.ProxyBufferImpl) ResultSetCallBack(io.mycat.proxy.callback.ResultSetCallBack) MycatException(io.mycat.MycatException) ClosedChannelException(java.nio.channels.ClosedChannelException)

Aggregations

MycatException (io.mycat.MycatException)3 ResultSetCallBack (io.mycat.proxy.callback.ResultSetCallBack)3 ErrorPacketImpl (io.mycat.beans.mysql.packet.ErrorPacketImpl)2 ClosedChannelException (java.nio.channels.ClosedChannelException)2 MySQLCommandType (io.mycat.beans.mysql.MySQLCommandType)1 MySQLErrorCode (io.mycat.beans.mysql.MySQLErrorCode)1 MySQLPacket (io.mycat.beans.mysql.packet.MySQLPacket)1 ProxyBuffer (io.mycat.beans.mysql.packet.ProxyBuffer)1 ProxyBufferImpl (io.mycat.proxy.buffer.ProxyBufferImpl)1 MySQLPacketResolver (io.mycat.proxy.packet.MySQLPacketResolver)1 MySQLPayloadType (io.mycat.proxy.packet.MySQLPayloadType)1 NIOJob (io.mycat.proxy.reactor.NIOJob)1 ReactorEnvThread (io.mycat.proxy.reactor.ReactorEnvThread)1 MySQLClientSession (io.mycat.proxy.session.MySQLClientSession)1 VertxUtil (io.mycat.util.VertxUtil)1 AsyncResult (io.vertx.core.AsyncResult)1 Future (io.vertx.core.Future)1 Handler (io.vertx.core.Handler)1 PromiseInternal (io.vertx.core.impl.future.PromiseInternal)1 MySQLClient (io.vertx.mysqlclient.MySQLClient)1