代码之家  ›  专栏  ›  技术社区  ›  lmk

点火sqlquery超时和取消-如果/何时引发querycancelledexception

  •  2
  • lmk  · 技术社区  · 6 年前

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

    query cancelled exception的文档还提到,如果查询在执行时被取消或超时,则会引发checked异常, 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.millistices,这是我在初始测试期间实现的,因此很难强制测试超时。

    下面的代码看起来对吗?(我想避免使用游标方法&依赖在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();
            }
        }
    }
    

    谢谢 穆图

    1 回复  |  直到 6 年前
        1
  •  4
  •   Denis Mekhanikov    6 年前

    QueryCancelledException 从方法中抛出 QueryCursor ,包装成 IgniteException ,它是RuntimeException的一个子类。

    在调用 IgniteCache#query(...) 方法。只有在调用querycursor迭代器()方法时才会发生这种情况。

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