/** @return Nodes to execute on. */ private Collection<GridNode> nodes() { GridCacheMode cacheMode = cctx.config().getCacheMode(); switch (cacheMode) { case LOCAL: if (prj != null) U.warn( log, "Ignoring query projection because it's executed over LOCAL cache " + "(only local node will be queried): " + this); return Collections.singletonList(cctx.localNode()); case REPLICATED: if (prj != null) return nodes(cctx, prj); GridCacheDistributionMode mode = cctx.config().getDistributionMode(); return mode == PARTITIONED_ONLY || mode == NEAR_PARTITIONED ? Collections.singletonList(cctx.localNode()) : Collections.singletonList(F.rand(nodes(cctx, null))); case PARTITIONED: return nodes(cctx, prj); default: throw new IllegalStateException("Unknown cache distribution mode: " + cacheMode); } }
/** * @param rmtReducer Optional reducer. * @param rmtTransform Optional transformer. * @param args Arguments. * @return Future. */ @SuppressWarnings("IfMayBeConditional") private <R> GridCacheQueryFuture<R> execute( @Nullable GridReducer<T, R> rmtReducer, @Nullable GridClosure<T, R> rmtTransform, @Nullable Object... args) { Collection<GridNode> nodes = nodes(); cctx.checkSecurity(GridSecurityPermission.CACHE_READ); if (F.isEmpty(nodes)) return new GridCacheQueryErrorFuture<>( cctx.kernalContext(), new GridEmptyProjectionException("There are no data nodes for cache: " + cctx.namexx())); if (log.isDebugEnabled()) log.debug("Executing query [query=" + this + ", nodes=" + nodes + ']'); if (cctx.deploymentEnabled()) { try { cctx.deploy().registerClasses(filter, rmtReducer, rmtTransform); cctx.deploy().registerClasses(args); } catch (GridException e) { return new GridCacheQueryErrorFuture<>(cctx.kernalContext(), e); } } if (subjId == null) subjId = cctx.localNodeId(); taskHash = cctx.kernalContext().job().currentTaskNameHash(); GridCacheQueryBean bean = new GridCacheQueryBean( this, (GridReducer<Object, Object>) rmtReducer, (GridClosure<Object, Object>) rmtTransform, args); GridCacheQueryManager qryMgr = cctx.queries(); boolean loc = nodes.size() == 1 && F.first(nodes).id().equals(cctx.localNodeId()); if (type == SQL_FIELDS) return (GridCacheQueryFuture<R>) (loc ? qryMgr.queryFieldsLocal(bean) : qryMgr.queryFieldsDistributed(bean, nodes)); else return (GridCacheQueryFuture<R>) (loc ? qryMgr.queryLocal(bean) : qryMgr.queryDistributed(bean, nodes)); }
/** * @param cctx Context. * @param type Query type. * @param clsName Class name. * @param clause Clause. * @param filter Scan filter. * @param incMeta Include metadata flag. * @param keepPortable Keep portable flag. * @param prjPred Cache projection filter. */ public GridCacheQueryAdapter( GridCacheContext<?, ?> cctx, GridCacheQueryType type, @Nullable GridPredicate<GridCacheEntry<Object, Object>> prjPred, @Nullable String clsName, @Nullable String clause, @Nullable GridBiPredicate<Object, Object> filter, boolean incMeta, boolean keepPortable) { assert cctx != null; assert type != null; this.cctx = cctx; this.type = type; this.clsName = clsName; this.clause = clause; this.prjPred = prjPred; this.filter = filter; this.incMeta = incMeta; this.keepPortable = keepPortable; log = cctx.logger(getClass()); pageSize = DFLT_PAGE_SIZE; timeout = 0; keepAll = true; incBackups = false; dedup = false; prj = null; metrics = new GridCacheQueryMetricsAdapter(); }
/** * @param ctx Cache context. * @param topic Topic for ordered messages. * @param prjPred Projection predicate. */ GridCacheContinuousQueryAdapter( GridCacheContext<K, V> ctx, Object topic, @Nullable GridPredicate<GridCacheEntry<K, V>> prjPred) { assert ctx != null; assert topic != null; this.ctx = ctx; this.topic = topic; this.prjPred = prjPred; log = ctx.logger(getClass()); }
/** {@inheritDoc} */ @Override public void close() throws GridException { closeLock.lock(); try { if (routineId == null) throw new IllegalStateException("Can't cancel query that was not executed."); ctx.kernalContext().continuous().stopRoutine(routineId).get(); } finally { closeLock.unlock(); } }
/** * @param res Query result. * @param err Error or {@code null} if query executed successfully. * @param startTime Start time. * @param duration Duration. */ public void onExecuted(Object res, Throwable err, long startTime, long duration) { boolean fail = err != null; // Update own metrics. metrics.onQueryExecute(duration, fail); // Update metrics in query manager. cctx.queries().onMetricsUpdate(duration, fail); if (log.isDebugEnabled()) log.debug( "Query execution finished [qry=" + this + ", startTime=" + startTime + ", duration=" + duration + ", fail=" + fail + ", res=" + res + ']'); }
/** {@inheritDoc} */ @Override public void execute(@Nullable GridProjection prj) throws GridException { if (cb == null) throw new IllegalStateException("Mandatory local callback is not set for the query: " + this); if (prj == null) prj = ctx.grid(); prj = prj.forCache(ctx.name()); if (prj.nodes().isEmpty()) throw new GridTopologyException("Failed to execute query (projection is empty): " + this); GridCacheMode mode = ctx.config().getCacheMode(); if (mode == LOCAL || mode == REPLICATED) { Collection<GridNode> nodes = prj.nodes(); GridNode node = nodes.contains(ctx.localNode()) ? ctx.localNode() : F.rand(nodes); assert node != null; if (nodes.size() > 1 && !ctx.cache().isDrSystemCache()) { if (node.id().equals(ctx.localNodeId())) U.warn( log, "Continuous query for " + mode + " cache can be run only on local node. " + "Will execute query locally: " + this); else U.warn( log, "Continuous query for " + mode + " cache can be run only on single node. " + "Will execute query on remote node [qry=" + this + ", node=" + node + ']'); } prj = prj.forNode(node); } closeLock.lock(); try { if (routineId != null) throw new IllegalStateException("Continuous query can't be executed twice."); guard.block(); GridContinuousHandler hnd = new GridCacheContinuousQueryHandler<>(ctx.name(), topic, cb, filter, prjPred); routineId = ctx.kernalContext() .continuous() .startRoutine(hnd, bufSize, timeInterval, autoUnsubscribe, prj.predicate()) .get(); } finally { closeLock.unlock(); } }
/** @throws GridException If query is invalid. */ public void validate() throws GridException { if (type != SCAN && !cctx.config().isQueryIndexEnabled()) throw new GridException("Indexing is disabled for cache: " + cctx.cache().name()); }