/** {@inheritDoc} */ @Override public void filter(@Nullable GridBiPredicate<K, V> filter) { if (!guard.enterBusy()) throw new IllegalStateException("Continuous query can't be changed after it was executed."); try { this.filter = filter; } finally { guard.leaveBusy(); } }
/** {@inheritDoc} */ @Override public void timeInterval(long timeInterval) { A.ensure(timeInterval >= 0, "timeInterval >= 0"); if (!guard.enterBusy()) throw new IllegalStateException("Continuous query can't be changed after it was executed."); try { this.timeInterval = timeInterval; } finally { guard.leaveBusy(); } }
/** {@inheritDoc} */ @Override public void bufferSize(int bufSize) { A.ensure(bufSize > 0, "bufSize > 0"); if (!guard.enterBusy()) throw new IllegalStateException("Continuous query can't be changed after it was executed."); try { this.bufSize = bufSize; } finally { guard.leaveBusy(); } }
/** {@inheritDoc} */ @Override public void callback(GridBiPredicate<UUID, Collection<Map.Entry<K, V>>> cb) { A.notNull(cb, "cb"); if (!guard.enterBusy()) throw new IllegalStateException("Continuous query can't be changed after it was executed."); try { this.cb = cb; } finally { guard.leaveBusy(); } }
/** {@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(); } }