Search in sources :

Example 1 with MySQLClientSession

use of io.mycat.proxy.session.MySQLClientSession 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 MySQLClientSession

use of io.mycat.proxy.session.MySQLClientSession in project Mycat2 by MyCATApache.

the class MySQLAPIImpl method query.

@Override
public void query(String sql, ResultSetCollector collector, MySQLAPIExceptionCallback exceptionCollector) {
    TextResultSetTransforCollector transfor = new TextResultSetTransforCollector(collector);
    TextResultSetHandler queryResultSetTask = new TextResultSetHandler(transfor);
    queryResultSetTask.request(mySQLClientSession, MySQLCommandType.COM_QUERY, sql.getBytes(), new ResultSetCallBack<MySQLClientSession>() {

        @Override
        public void onFinishedSendException(Exception exception, Object sender, Object attr) {
            exceptionCollector.onException(exception, MySQLAPIImpl.this);
        }

        @Override
        public void onFinishedException(Exception exception, Object sender, Object attr) {
            exceptionCollector.onException(exception, MySQLAPIImpl.this);
        }

        @Override
        public void onFinished(boolean monopolize, MySQLClientSession mysql, Object sender, Object attr) {
            exceptionCollector.onFinished(monopolize, MySQLAPIImpl.this);
        }

        @Override
        public void onErrorPacket(ErrorPacketImpl errorPacket, boolean monopolize, MySQLClientSession mysql, Object sender, Object attr) {
            exceptionCollector.onErrorPacket(errorPacket, monopolize, MySQLAPIImpl.this);
        }
    });
}
Also used : TextResultSetTransforCollector(io.mycat.api.collector.TextResultSetTransforCollector) TextResultSetHandler(io.mycat.proxy.handler.backend.TextResultSetHandler) ErrorPacketImpl(io.mycat.beans.mysql.packet.ErrorPacketImpl) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Example 3 with MySQLClientSession

use of io.mycat.proxy.session.MySQLClientSession in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method idleConnectCheck.

private Future<Void> idleConnectCheck() {
    List<MySQLClientSession> mySQLClientSessions = new ArrayList<>(idleSessions);
    List<MySQLClientSession> needCloseConnections;
    int minCon = datasourceConfig.getMinCon();
    if (mySQLClientSessions.size() > minCon) {
        needCloseConnections = mySQLClientSessions.subList(minCon, mySQLClientSessions.size());
    } else {
        needCloseConnections = Collections.emptyList();
    }
    ArrayList<Future> futures = new ArrayList<>(mySQLClientSessions.size());
    for (MySQLClientSession needCloseConnection : needCloseConnections) {
        idleSessions.remove(needCloseConnection);
        needCloseConnection.setIdle(false);
        needCloseConnection.switchNioHandler(null);
        futures.add(removeSession(needCloseConnection, true, "idle check"));
    }
    for (MySQLClientSession mySQLClientSession : mySQLClientSessions) {
        idleSessions.remove(mySQLClientSession);
        mySQLClientSession.setIdle(false);
        mySQLClientSession.switchNioHandler(null);
        futures.add(checkIfNeedHeartBeat(mySQLClientSession));
    }
    return (Future) CompositeFuture.join(futures);
}
Also used : ArrayList(java.util.ArrayList) ScheduledFuture(java.util.concurrent.ScheduledFuture) CompositeFuture(io.vertx.core.CompositeFuture) Future(io.vertx.core.Future) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Example 4 with MySQLClientSession

use of io.mycat.proxy.session.MySQLClientSession 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 5 with MySQLClientSession

use of io.mycat.proxy.session.MySQLClientSession in project Mycat2 by MyCATApache.

the class MySQLDatasourcePool method innerCreateCon.

private Future<MySQLClientSession> innerCreateCon() {
    PromiseInternal<MySQLClientSession> promise = VertxUtil.newPromise();
    new BackendConCreateHandler(this, promise);
    return promise.flatMap(session -> {
        synchronized (allSessions) {
            allSessions.add(session);
        }
        MySQLDatasource datasource = session.getDatasource();
        String sql = datasource.getInitSqlForProxy();
        if (!StringUtil.isEmpty(sql)) {
            PromiseInternal<MySQLClientSession> promiseInternal = VertxUtil.newPromise();
            ResultSetHandler.DEFAULT.request(session, COM_QUERY, sql.getBytes(StandardCharsets.UTF_8), promiseInternal);
            return promiseInternal.onFailure(event -> {
                session.close(false, "initSql fail");
            });
        } else {
            return Future.succeededFuture(session);
        }
    });
}
Also used : BackendConCreateHandler(io.mycat.proxy.handler.backend.BackendConCreateHandler) MySQLDatasource(io.mycat.beans.MySQLDatasource) MySQLClientSession(io.mycat.proxy.session.MySQLClientSession)

Aggregations

MySQLClientSession (io.mycat.proxy.session.MySQLClientSession)9 MycatException (io.mycat.MycatException)3 ReactorEnvThread (io.mycat.proxy.reactor.ReactorEnvThread)3 Future (io.vertx.core.Future)3 ErrorPacketImpl (io.mycat.beans.mysql.packet.ErrorPacketImpl)2 CompositeFuture (io.vertx.core.CompositeFuture)2 PromiseInternal (io.vertx.core.impl.future.PromiseInternal)2 ScheduledFuture (java.util.concurrent.ScheduledFuture)2 TextResultSetTransforCollector (io.mycat.api.collector.TextResultSetTransforCollector)1 MySQLDatasource (io.mycat.beans.MySQLDatasource)1 MySQLCommandType (io.mycat.beans.mysql.MySQLCommandType)1 MySQLErrorCode (io.mycat.beans.mysql.MySQLErrorCode)1 MySQLPacketSplitter (io.mycat.beans.mysql.packet.MySQLPacketSplitter)1 PacketSplitterImpl (io.mycat.beans.mysql.packet.PacketSplitterImpl)1 RequestCallback (io.mycat.proxy.callback.RequestCallback)1 ResultSetCallBack (io.mycat.proxy.callback.ResultSetCallBack)1 BackendConCreateHandler (io.mycat.proxy.handler.backend.BackendConCreateHandler)1 TextResultSetHandler (io.mycat.proxy.handler.backend.TextResultSetHandler)1 NIOJob (io.mycat.proxy.reactor.NIOJob)1 SessionThread (io.mycat.proxy.reactor.SessionThread)1