点燃SqlQuery超时和取消-如果/何时引发QueryCancelledException

时间:2018-07-16 08:11:13

标签: java ignite gridgain

正如该文档所建议的,可以通过设置https://ignite.apache.org/releases/2.4.0/javadoc/org/apache/ignite/cache/query/SqlQuery.html#setTimeout-int-java.util.concurrent.TimeUnit-

来设置执行SqlQuery时的超时时间

QueryCancelledException的文档还提到,如果在执行https://ignite.apache.org/releases/2.4.0/javadoc/org/apache/ignite/cache/query/QueryCancelledException.html

时取消查询或使查询超时,则会引发检查的异常。

这里提到的相同方法是取消/超时长时间运行的查询的一种方法, https://apacheignite-sql.readme.io/v2.4/docs/query-cancellation

但是奇怪的是,所有IgniteCache.query(..)方法的Java文档,https://ignite.apache.org/releases/2.4.0/javadoc/org/apache/ignite/IgniteCache.html#query-org.apache.ignite.cache.query.Query-都没有声明此已检查的异常或就此引发任何已检查的异常(与QueryCursor.getAll()相同)方法)导致在哪里以及如何为查询超时编写处理代码。

我对下面的代码进行了编码,但是无法使查询超时以快速测试我的代码路径的那部分并查看其是否正确。我希望在IgniteCache.query(..)方法和QueryCursor.getAll()及其相关方法中都会引发该异常。

显然,SqlQuery.setTimeout(int timeout,TimeUnit timeUnit)的最小超时粒度是TimeUnit.MILLISECONDS,我在初始测试期间就意识到了这一点,因此很难强制进行超时测试。

下面的代码看起来正确吗? (我想避免使用游标方法,并依赖在try-with-resources内部调用的IgniteCache.query(..)来检测超时)。这样行吗?

@Scheduled(fixedDelayString = "${checkInterval}", initialDelayString = "${checkDelay}")
private final void monitorHealth() {
    if(!isReady) {
        return;
    }
    try (QueryCursor<Entry<Integer, FabricInfo>> cursor = fabricInfoCache.query(SQL_QUERY)) {
        cursor.iterator();
        // Reset the query time out counter..
        if(retryCount != 0) {
            retryCount = 0;
            LOGGER.warn("Client health check query executed without getting timed out before the configured maximum number of timeout retries was reached. Reseting retryCount to zero.");
        }
    } catch (Exception e) {
        if(e.getCause() instanceof QueryCancelledException) {
            retryCount++;
            LOGGER.warn("Client health check query timed out for the {} time.", retryCount);

            if(retryCount > QUERY_MAX_RETRIES_VALUE) {
                // Query timed out the maximum number of times..
                LOGGER.error("Client health check query timed out repeatedly for the maximum number of times configured : {}. Initating a disconnect-reconnect.", retryCount);
                reconnectAction();
            }
        } else {
            if (e.getCause() instanceof IgniteClientDisconnectedException) {
                LOGGER.error("Client health check query failed due to client node getting disconnected from cluster. Initating a disconnect-reconnect.", e.getCause());
            } else {
                // Treat other failures like CacheStoppedException, etc same as IgniteClientDisconnectedException...
                LOGGER.error("Client health check query failed. Initating a disconnect-reconnect.", e.getCause());
            }
            reconnectAction();
        }
    }
}

谢谢 Muthu

1 个答案:

答案 0 :(得分:4)

QueryCancelledException是从QueryCursor的方法引发的,并包装到IgniteException中,该方法是RuntimeException的子类。

在调用IgniteCache#query(...)方法之后,查询不会立即执行。只会在调用QueryCursor#iterator()方法时发生。

例如,您可以查看Ignite项目中的以下测试,该测试检查是否遵守查询取消和超时:IgniteCacheLocalQueryCancelOrTimeoutSelfTest