Search in sources :

Example 1 with ReactorEnvThread

use of io.mycat.proxy.reactor.ReactorEnvThread 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 ReactorEnvThread

use of io.mycat.proxy.reactor.ReactorEnvThread in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method createSession.

public Future<MySQLClientSession> createSession() {
    if (!(Thread.currentThread() instanceof ReactorEnvThread)) {
        return waitForIdleSession(false);
    }
    int limitCount = this.getSessionLimitCount();
    synchronized (this) {
        if (allSessions.size() >= limitCount && idleSessions.isEmpty()) {
            return waitForIdleSession(true);
        }
    }
    if (idleSessions.isEmpty()) {
        Future<MySQLClientSession> future = innerCreateCon();
        return future.recover(new Function<Throwable, Future<MySQLClientSession>>() {

            final AtomicInteger retryCount = new AtomicInteger(0);

            final long startTime = System.currentTimeMillis();

            @Override
            public Future<MySQLClientSession> apply(Throwable t) {
                PromiseInternal<MySQLClientSession> promise = VertxUtil.newPromise();
                long now = System.currentTimeMillis();
                long maxConnectTimeout = MySQLDatasourcePool.this.getMaxConnectTimeout();
                if (retryCount.get() >= limitCount) {
                    promise.tryFail(new MycatException("retry get connection fail:" + getName()));
                } else if (startTime + maxConnectTimeout > now) {
                    promise.tryFail(new MycatException("retry get connection timeout:" + getName()));
                } else {
                    retryCount.incrementAndGet();
                    waitForIdleSession(true).recover(this).onComplete(promise);
                }
                return promise.future();
            }
        });
    } else {
        MySQLClientSession session = idleSessions.removeFirst();
        if (session.checkOpen()) {
            session.setIdle(false);
            session.switchNioHandler(null);
            return Future.succeededFuture(session);
        } else {
            return session.close(false, "has closed").flatMap(unused -> createSession());
        }
    }
}
Also used : ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) MycatException(io.mycat.MycatException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PromiseInternal(io.vertx.core.impl.future.PromiseInternal) ScheduledFuture(java.util.concurrent.ScheduledFuture) CompositeFuture(io.vertx.core.CompositeFuture) Future(io.vertx.core.Future) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Example 3 with ReactorEnvThread

use of io.mycat.proxy.reactor.ReactorEnvThread in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method removeSession.

@Override
public Future<Void> removeSession(MySQLClientSession session, boolean normal, String reason) {
    if (session.getIOThread() == Thread.currentThread()) {
        decrementSessionCounter();
        allSessions.remove(session);
        idleSessions.remove(session);
        session.resetPacket();
        try {
            session.channel().close();
        } catch (Throwable ignore) {
            LOGGER.error("", ignore);
        }
        return Future.succeededFuture();
    }
    PromiseInternal<Void> promise = VertxUtil.newPromise();
    session.getIOThread().addNIOJob(new NIOJob() {

        @Override
        public void run(ReactorEnvThread reactor) throws Exception {
            removeSession(session, normal, reason).onComplete(promise);
        }

        @Override
        public void stop(ReactorEnvThread reactor, Exception hint) {
            removeSession(session, normal, reason).onComplete(promise);
        }

        @Override
        public String message() {
            return "removeSession";
        }
    });
    return promise.future();
}
Also used : ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) NIOJob(io.mycat.proxy.reactor.NIOJob) MycatException(io.mycat.MycatException)

Example 4 with ReactorEnvThread

use of io.mycat.proxy.reactor.ReactorEnvThread in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method addIdleSession.

public final Future<Void> addIdleSession(MySQLClientSession session) {
    if (session.getIOThread() == Thread.currentThread()) {
        if (!session.checkOpen()) {
            return removeSession(session, false, "has close");
        }
        if (session.isMonopolized()) {
            LOGGER.error("sessionId:{} isMonopolized", session.sessionId());
            return removeSession(session, false, "monopolized");
        }
        try {
            /**
             * mycat对应透传模式对mysql session的占用
             * niohandler对应透传以及task类对mysql session的占用
             */
            assert session.getMycat() == null;
            assert !session.hasClosed();
            assert session.currentProxyBuffer() == null;
            assert !session.isIdle();
            session.setCursorStatementId(-1);
            session.resetPacket();
            session.setIdle(true);
            session.switchNioHandler(IdleHandler.INSTANCE);
            session.change2ReadOpts();
            idleSessions.addFirst(session);
            MycatMonitor.onAddIdleMysqlSession(session);
            return VertxUtil.newSuccessPromise();
        } catch (Exception e) {
            LOGGER.error("", e);
            return removeSession(session, false, e.getMessage());
        }
    } else {
        PromiseInternal<Void> promise = VertxUtil.newPromise();
        session.getIOThread().addNIOJob(new NIOJob() {

            @Override
            public void run(ReactorEnvThread reactor) throws Exception {
                addIdleSession(session).onComplete(promise);
            }

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

            @Override
            public String message() {
                return "add idle session";
            }
        });
        return promise.future();
    }
}
Also used : ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) NIOJob(io.mycat.proxy.reactor.NIOJob) MycatException(io.mycat.MycatException)

Example 5 with ReactorEnvThread

use of io.mycat.proxy.reactor.ReactorEnvThread in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method waitForIdleSession.

private Future<MySQLClientSession> waitForIdleSession(boolean wait) {
    PromiseInternal<MySQLClientSession> promise = VertxUtil.newPromise();
    ReactorEnvThread reactorEnvThread;
    if (Thread.currentThread() instanceof ReactorEnvThread) {
        reactorEnvThread = (ReactorEnvThread) Thread.currentThread();
    } else {
        reactorEnvThread = this.server.getReactorManager().getRandomReactor();
    }
    if (wait) {
        ScheduleUtil.getTimer().schedule(() -> {
            nextStageForSession(promise, reactorEnvThread);
        }, datasourceConfig.getMaxConnectTimeout() / datasourceConfig.getMaxRetryCount(), TimeUnit.MILLISECONDS);
    } else {
        nextStageForSession(promise, reactorEnvThread);
    }
    return promise;
}
Also used : ReactorEnvThread(io.mycat.proxy.reactor.ReactorEnvThread) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Aggregations

ReactorEnvThread (io.mycat.proxy.reactor.ReactorEnvThread)7 NIOJob (io.mycat.proxy.reactor.NIOJob)5 MycatException (io.mycat.MycatException)4 MySQLClientSession (io.mycat.proxy.session.MySQLClientSession)3 PromiseInternal (io.vertx.core.impl.future.PromiseInternal)3 MycatReactorThread (io.mycat.proxy.reactor.MycatReactorThread)2 VertxUtil (io.mycat.util.VertxUtil)2 Future (io.vertx.core.Future)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 Wrapper (io.mycat.Wrapper)1 MySQLCommandType (io.mycat.beans.mysql.MySQLCommandType)1 MySQLErrorCode (io.mycat.beans.mysql.MySQLErrorCode)1 ErrorPacketImpl (io.mycat.beans.mysql.packet.ErrorPacketImpl)1 ResultSetCallBack (io.mycat.proxy.callback.ResultSetCallBack)1 NIOHandler (io.mycat.proxy.handler.NIOHandler)1 AsyncResult (io.vertx.core.AsyncResult)1 CompositeFuture (io.vertx.core.CompositeFuture)1 Handler (io.vertx.core.Handler)1 MySQLClient (io.vertx.mysqlclient.MySQLClient)1