Search in sources :

Example 1 with IgniteSpiCloseableIterator

use of org.apache.ignite.spi.IgniteSpiCloseableIterator in project ignite by apache.

the class GridCacheQueryManager method runQuery.

/**
 * Processes cache query request.
 *
 * @param qryInfo Query info.
 */
@SuppressWarnings("unchecked")
protected void runQuery(GridCacheQueryInfo qryInfo) {
    assert qryInfo != null;
    assert qryInfo.query().type() != SCAN || !qryInfo.local() : qryInfo;
    if (!enterBusy()) {
        if (cctx.localNodeId().equals(qryInfo.senderId()))
            throw new IllegalStateException("Failed to process query request (grid is stopping).");
        // Ignore remote requests when when node is stopping.
        return;
    }
    try {
        boolean loc = qryInfo.local();
        QueryResult<K, V> res = null;
        if (log.isDebugEnabled())
            log.debug("Running query: " + qryInfo);
        boolean rmvIter = true;
        GridCacheQueryAdapter<?> qry = qryInfo.query();
        try {
            // Preparing query closures.
            IgniteClosure<Cache.Entry<K, V>, Object> trans = (IgniteClosure<Cache.Entry<K, V>, Object>) qryInfo.transformer();
            IgniteReducer<Cache.Entry<K, V>, Object> rdc = (IgniteReducer<Cache.Entry<K, V>, Object>) qryInfo.reducer();
            injectResources(trans);
            injectResources(rdc);
            int pageSize = qry.pageSize();
            boolean incBackups = qry.includeBackups();
            String taskName = cctx.kernalContext().task().resolveTaskName(qry.taskHash());
            IgniteSpiCloseableIterator iter;
            GridCacheQueryType type;
            res = loc ? executeQuery(qry, qryInfo.arguments(), trans, loc, qry.subjectId(), taskName, recipient(qryInfo.senderId(), qryInfo.requestId())) : queryResult(qryInfo, taskName);
            if (res == null)
                return;
            iter = res.iterator(recipient(qryInfo.senderId(), qryInfo.requestId()));
            type = res.type();
            final GridCacheAdapter<K, V> cache = cctx.cache();
            if (log.isDebugEnabled())
                log.debug("Received index iterator [iterHasNext=" + iter.hasNext() + ", cacheSize=" + cache.size() + ']');
            int cnt = 0;
            boolean stop = false;
            boolean pageSent = false;
            Collection<Object> data = new ArrayList<>(pageSize);
            AffinityTopologyVersion topVer = cctx.affinity().affinityTopologyVersion();
            final boolean statsEnabled = cctx.statisticsEnabled();
            final boolean readEvt = cctx.events().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
            CacheObjectContext objCtx = cctx.cacheObjectContext();
            while (!Thread.currentThread().isInterrupted()) {
                long start = statsEnabled ? System.nanoTime() : 0L;
                // actual row extracting may happen inside this method.
                if (!iter.hasNext())
                    break;
                Object row0 = iter.next();
                // Query is cancelled.
                if (row0 == null) {
                    onPageReady(loc, qryInfo, null, true, null);
                    break;
                }
                if (type == SCAN)
                    // Scan iterator may return already transformed entry
                    data.add(row0);
                else {
                    IgniteBiTuple<K, V> row = (IgniteBiTuple<K, V>) row0;
                    final K key = row.getKey();
                    V val = row.getValue();
                    if (log.isDebugEnabled()) {
                        ClusterNode primaryNode = cctx.affinity().primaryByKey(key, cctx.affinity().affinityTopologyVersion());
                        log.debug(S.toString("Record", "key", key, true, "val", val, true, "incBackups", incBackups, false, "priNode", primaryNode != null ? U.id8(primaryNode.id()) : null, false, "node", U.id8(cctx.localNode().id()), false));
                    }
                    if (val == null) {
                        if (log.isDebugEnabled())
                            log.debug(S.toString("Unsuitable record value", "val", val, true));
                        continue;
                    }
                    if (statsEnabled) {
                        CacheMetricsImpl metrics = cctx.cache().metrics0();
                        metrics.onRead(true);
                        metrics.addGetTimeNanos(System.nanoTime() - start);
                    }
                    K key0 = null;
                    V val0 = null;
                    if (readEvt && cctx.gridEvents().hasListener(EVT_CACHE_QUERY_OBJECT_READ)) {
                        key0 = (K) CacheObjectUtils.unwrapBinaryIfNeeded(objCtx, key, qry.keepBinary(), false);
                        val0 = (V) CacheObjectUtils.unwrapBinaryIfNeeded(objCtx, val, qry.keepBinary(), false);
                        switch(type) {
                            case SQL:
                                cctx.gridEvents().record(new CacheQueryReadEvent<>(cctx.localNode(), "SQL query entry read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.SQL.name(), cctx.name(), qry.queryClassName(), qry.clause(), null, null, qryInfo.arguments(), qry.subjectId(), taskName, key0, val0, null, null));
                                break;
                            case TEXT:
                                cctx.gridEvents().record(new CacheQueryReadEvent<>(cctx.localNode(), "Full text query entry read.", EVT_CACHE_QUERY_OBJECT_READ, CacheQueryType.FULL_TEXT.name(), cctx.name(), qry.queryClassName(), qry.clause(), null, null, null, qry.subjectId(), taskName, key0, val0, null, null));
                                break;
                        }
                    }
                    if (rdc != null) {
                        if (key0 == null)
                            key0 = (K) CacheObjectUtils.unwrapBinaryIfNeeded(objCtx, key, qry.keepBinary(), false);
                        if (val0 == null)
                            val0 = (V) CacheObjectUtils.unwrapBinaryIfNeeded(objCtx, val, qry.keepBinary(), false);
                        Cache.Entry<K, V> entry = new CacheEntryImpl(key0, val0);
                        // Reduce.
                        if (!rdc.collect(entry) || !iter.hasNext()) {
                            onPageReady(loc, qryInfo, Collections.singletonList(rdc.reduce()), true, null);
                            pageSent = true;
                            break;
                        } else
                            continue;
                    } else
                        data.add(!loc ? new GridCacheQueryResponseEntry<>(key, val) : F.t(key, val));
                }
                if (!loc) {
                    if (++cnt == pageSize || !iter.hasNext()) {
                        boolean finished = !iter.hasNext();
                        onPageReady(loc, qryInfo, data, finished, null);
                        pageSent = true;
                        if (!finished)
                            rmvIter = false;
                        if (!qryInfo.allPages())
                            return;
                        data = new ArrayList<>(pageSize);
                        if (stop)
                            // while
                            break;
                    }
                }
            }
            if (!pageSent) {
                if (rdc == null)
                    onPageReady(loc, qryInfo, data, true, null);
                else
                    onPageReady(loc, qryInfo, Collections.singletonList(rdc.reduce()), true, null);
            }
        } catch (Throwable e) {
            if (X.hasCause(e, ClassNotFoundException.class) && !qry.keepBinary() && cctx.binaryMarshaller() && !cctx.localNode().isClient() && !log.isQuiet()) {
                LT.warn(log, "Suggestion for the cause of ClassNotFoundException");
                LT.warn(log, "To disable, set -D" + IGNITE_QUIET + "=true");
                LT.warn(log, "  ^-- Ignite configured to use BinaryMarshaller but keepBinary is false for " + "request");
                LT.warn(log, "  ^-- Server node need to load definition of data classes. " + "It can be reason of ClassNotFoundException(consider IgniteCache.withKeepBinary to fix)");
                LT.warn(log, "Refer this page for detailed information: " + "https://apacheignite.readme.io/docs/binary-marshaller");
            }
            if (!X.hasCause(e, GridDhtUnreservedPartitionException.class))
                U.error(log, "Failed to run query [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
            onPageReady(loc, qryInfo, null, true, e);
            if (e instanceof Error)
                throw (Error) e;
        } finally {
            if (loc) {
                // Local iterators are always removed.
                if (res != null) {
                    try {
                        res.closeIfNotShared(recipient(qryInfo.senderId(), qryInfo.requestId()));
                    } catch (IgniteCheckedException e) {
                        if (!X.hasCause(e, GridDhtUnreservedPartitionException.class))
                            U.error(log, "Failed to close local iterator [qry=" + qryInfo + ", node=" + cctx.nodeId() + "]", e);
                    }
                }
            } else if (rmvIter)
                removeQueryResult(qryInfo.senderId(), qryInfo.requestId());
        }
    } finally {
        leaveBusy();
    }
}
Also used : IgniteClosure(org.apache.ignite.lang.IgniteClosure) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) IgniteSpiCloseableIterator(org.apache.ignite.spi.IgniteSpiCloseableIterator) CacheMetricsImpl(org.apache.ignite.internal.processors.cache.CacheMetricsImpl) ArrayList(java.util.ArrayList) CacheObjectContext(org.apache.ignite.internal.processors.cache.CacheObjectContext) CacheEntryImpl(org.apache.ignite.internal.processors.cache.CacheEntryImpl) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) ClusterNode(org.apache.ignite.cluster.ClusterNode) IgniteReducer(org.apache.ignite.lang.IgniteReducer) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) CacheObject(org.apache.ignite.internal.processors.cache.CacheObject) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) Cache(javax.cache.Cache) IgniteInternalCache(org.apache.ignite.internal.processors.cache.IgniteInternalCache)

Aggregations

ArrayList (java.util.ArrayList)1 Cache (javax.cache.Cache)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 ClusterNode (org.apache.ignite.cluster.ClusterNode)1 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)1 CacheEntryImpl (org.apache.ignite.internal.processors.cache.CacheEntryImpl)1 CacheMetricsImpl (org.apache.ignite.internal.processors.cache.CacheMetricsImpl)1 CacheObject (org.apache.ignite.internal.processors.cache.CacheObject)1 CacheObjectContext (org.apache.ignite.internal.processors.cache.CacheObjectContext)1 IgniteInternalCache (org.apache.ignite.internal.processors.cache.IgniteInternalCache)1 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)1 IgniteBiTuple (org.apache.ignite.lang.IgniteBiTuple)1 IgniteClosure (org.apache.ignite.lang.IgniteClosure)1 IgniteReducer (org.apache.ignite.lang.IgniteReducer)1 IgniteSpiCloseableIterator (org.apache.ignite.spi.IgniteSpiCloseableIterator)1