use of org.apache.ignite.lang.IgniteInClosure in project ignite by apache.
the class DataStreamerImpl method load0.
/**
* @param entries Entries.
* @param resFut Result future.
* @param activeKeys Active keys.
* @param remaps Remaps count.
*/
private void load0(Collection<? extends DataStreamerEntry> entries, final GridFutureAdapter<Object> resFut, @Nullable final Collection<KeyCacheObjectWrapper> activeKeys, final int remaps) {
try {
assert entries != null;
final boolean remap = remaps > 0;
if (!remap) {
// Failed data should be processed prior to new data.
acquireRemapSemaphore();
}
if (!isWarningPrinted) {
synchronized (this) {
if (!allowOverwrite() && !isWarningPrinted) {
U.warn(log, "Data streamer will not overwrite existing cache entries for better performance " + "(to change, set allowOverwrite to true)");
}
isWarningPrinted = true;
}
}
Map<ClusterNode, Collection<DataStreamerEntry>> mappings = new HashMap<>();
boolean initPda = ctx.deploy().enabled() && jobPda == null;
GridCacheAdapter cache = ctx.cache().internalCache(cacheName);
if (cache == null)
throw new IgniteCheckedException("Cache not created or already destroyed.");
GridCacheContext cctx = cache.context();
GridCacheGateway gate = null;
AffinityTopologyVersion topVer;
if (!cctx.isLocal())
topVer = ctx.cache().context().exchange().lastTopologyFuture().get();
else
topVer = ctx.cache().context().exchange().readyAffinityVersion();
List<List<ClusterNode>> assignments = cctx.affinity().assignments(topVer);
if (!allowOverwrite() && !cctx.isLocal()) {
// Cases where cctx required.
gate = cctx.gate();
gate.enter();
}
try {
for (DataStreamerEntry entry : entries) {
List<ClusterNode> nodes;
try {
KeyCacheObject key = entry.getKey();
assert key != null;
if (initPda) {
if (cacheObjCtx.addDeploymentInfo())
jobPda = new DataStreamerPda(key.value(cacheObjCtx, false), entry.getValue() != null ? entry.getValue().value(cacheObjCtx, false) : null, rcvr);
else if (rcvr != null)
jobPda = new DataStreamerPda(rcvr);
initPda = false;
}
if (key.partition() == -1)
key.partition(cctx.affinity().partition(key, false));
nodes = nodes(key, topVer, cctx);
} catch (IgniteCheckedException e) {
resFut.onDone(e);
return;
}
if (F.isEmpty(nodes)) {
resFut.onDone(new ClusterTopologyException("Failed to map key to node " + "(no nodes with cache found in topology) [infos=" + entries.size() + ", cacheName=" + cacheName + ']'));
return;
}
for (ClusterNode node : nodes) {
Collection<DataStreamerEntry> col = mappings.get(node);
if (col == null)
mappings.put(node, col = new ArrayList<>());
col.add(entry);
}
}
for (final Map.Entry<ClusterNode, Collection<DataStreamerEntry>> e : mappings.entrySet()) {
final UUID nodeId = e.getKey().id();
Buffer buf = bufMappings.get(nodeId);
if (buf == null) {
Buffer old = bufMappings.putIfAbsent(nodeId, buf = new Buffer(e.getKey()));
if (old != null)
buf = old;
}
final Collection<DataStreamerEntry> entriesForNode = e.getValue();
IgniteInClosure<IgniteInternalFuture<?>> lsnr = new IgniteInClosure<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> t) {
try {
t.get();
if (activeKeys != null) {
for (DataStreamerEntry e : entriesForNode) activeKeys.remove(new KeyCacheObjectWrapper(e.getKey()));
if (activeKeys.isEmpty())
resFut.onDone();
} else {
assert entriesForNode.size() == 1;
// That has been a single key,
// so complete result future right away.
resFut.onDone();
}
} catch (IgniteClientDisconnectedCheckedException e1) {
if (log.isDebugEnabled())
log.debug("Future finished with disconnect error [nodeId=" + nodeId + ", err=" + e1 + ']');
resFut.onDone(e1);
} catch (IgniteCheckedException e1) {
if (log.isDebugEnabled())
log.debug("Future finished with error [nodeId=" + nodeId + ", err=" + e1 + ']');
if (cancelled) {
resFut.onDone(new IgniteCheckedException("Data streamer has been cancelled: " + DataStreamerImpl.this, e1));
} else if (remaps + 1 > maxRemapCnt) {
resFut.onDone(new IgniteCheckedException("Failed to finish operation (too many remaps): " + remaps, e1));
} else {
try {
remapSem.acquire();
final Runnable r = new Runnable() {
@Override
public void run() {
try {
if (cancelled)
closedException();
load0(entriesForNode, resFut, activeKeys, remaps + 1);
} catch (Throwable ex) {
resFut.onDone(new IgniteCheckedException("DataStreamer remapping failed. ", ex));
} finally {
remapSem.release();
}
}
};
dataToRemap.add(r);
if (!remapOwning.get() && remapOwning.compareAndSet(false, true)) {
ctx.closure().callLocalSafe(new GPC<Boolean>() {
@Override
public Boolean call() {
boolean locked = true;
while (locked || !dataToRemap.isEmpty()) {
if (!locked && !remapOwning.compareAndSet(false, true))
return false;
try {
Runnable r = dataToRemap.poll();
if (r != null)
r.run();
} finally {
if (!dataToRemap.isEmpty())
locked = true;
else {
remapOwning.set(false);
locked = false;
}
}
}
return true;
}
}, true);
}
} catch (InterruptedException e2) {
resFut.onDone(e2);
}
}
}
}
};
GridCompoundFuture opFut = new SilentCompoundFuture();
opFut.listen(lsnr);
final List<GridFutureAdapter<?>> futs;
try {
futs = buf.update(entriesForNode, topVer, assignments, opFut, remap);
opFut.markInitialized();
} catch (IgniteInterruptedCheckedException e1) {
resFut.onDone(e1);
return;
}
if (ctx.discovery().node(nodeId) == null) {
if (bufMappings.remove(nodeId, buf)) {
final Buffer buf0 = buf;
waitAffinityAndRun(new Runnable() {
@Override
public void run() {
buf0.onNodeLeft();
if (futs != null) {
Throwable ex = new ClusterTopologyCheckedException("Failed to wait for request completion (node has left): " + nodeId);
for (int i = 0; i < futs.size(); i++) futs.get(i).onDone(ex);
}
}
}, ctx.discovery().topologyVersion(), false);
}
}
}
} finally {
if (gate != null)
gate.leave();
}
} catch (Exception ex) {
resFut.onDone(new IgniteCheckedException("DataStreamer data loading failed.", ex));
}
}
use of org.apache.ignite.lang.IgniteInClosure in project ignite by apache.
the class GridFutureListenPerformanceTest method main.
/**
* @param args Args.
* @throws InterruptedException If failed.
*/
public static void main(String[] args) throws InterruptedException {
final LongAdder cnt = new LongAdder();
final ConcurrentLinkedDeque<GridFutureAdapter<Object>> futs = new ConcurrentLinkedDeque<>();
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Thread statThread = new Thread() {
@SuppressWarnings("BusyWait")
@Override
public void run() {
while (!done) {
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {
return;
}
System.out.println(new Date() + " Notifications per sec: " + (cnt.sumThenReset() / 5));
}
}
};
statThread.setDaemon(true);
statThread.start();
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
pool.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
Random rnd = new Random();
while (!done) {
for (int j = 0; j < rnd.nextInt(10); j++) {
GridFutureAdapter<Object> fut = new GridFutureAdapter<>();
futs.add(fut);
for (int k = 1; k < rnd.nextInt(3); k++) {
fut.listen(new IgniteInClosure<IgniteInternalFuture<Object>>() {
@Override
public void apply(IgniteInternalFuture<Object> t) {
try {
t.get();
} catch (IgniteCheckedException e) {
e.printStackTrace();
}
cnt.increment();
}
});
}
}
GridFutureAdapter<Object> fut;
while ((fut = futs.poll()) != null) fut.onDone();
}
return null;
}
});
}
Thread.sleep(5 * 60 * 1000);
done = true;
}
use of org.apache.ignite.lang.IgniteInClosure in project ignite by apache.
the class GridScheduleSelfTest method testScheduleRunnable.
/**
* @throws Exception If failed.
*/
@Test
public void testScheduleRunnable() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
SchedulerFuture<?> fut = null;
// 1 minute frequency.
long freq = 60;
// 2 seconds delay.
long delay = 2;
try {
// Execute 2 times after 2 seconds delay every minute.
fut = grid(0).scheduler().scheduleLocal(new Runnable() {
@Override
public void run() {
latch.countDown();
info(">>> EXECUTING SCHEDULED RUNNABLE! <<<");
}
}, "{2, 2} * * * * *");
assert !fut.isDone();
assert !fut.isCancelled();
assert fut.last() == null;
final AtomicInteger notifyCnt = new AtomicInteger();
fut.listen(new CI1<IgniteFuture<?>>() {
@Override
public void apply(IgniteFuture<?> e) {
notifyCnt.incrementAndGet();
}
});
final SchedulerFuture<?> fut0 = fut;
// noinspection ThrowableNotThrown
assertThrows(log, new Callable<Object>() {
@Override
public Object call() throws Exception {
fut0.listenAsync(new IgniteInClosure<IgniteFuture<?>>() {
@Override
public void apply(IgniteFuture<?> fut) {
// No-op
}
}, null);
return null;
}
}, NullPointerException.class, null);
fut.listenAsync(new IgniteInClosure<IgniteFuture<?>>() {
@Override
public void apply(IgniteFuture<?> fut) {
assertEquals(Thread.currentThread().getName(), CUSTOM_THREAD_NAME);
notifyCnt.incrementAndGet();
}
}, exec);
// noinspection ThrowableNotThrown
assertThrows(log, new Callable<Object>() {
@Override
public Object call() throws Exception {
fut0.chainAsync(new IgniteClosure<IgniteFuture<?>, String>() {
@Override
public String apply(IgniteFuture<?> fut) {
return null;
}
}, null);
return null;
}
}, NullPointerException.class, null);
IgniteFuture<String> chained1 = fut.chainAsync(new IgniteClosure<IgniteFuture<?>, String>() {
@Override
public String apply(IgniteFuture<?> fut) {
assertEquals(Thread.currentThread().getName(), CUSTOM_THREAD_NAME);
fut.get();
return "done-custom";
}
}, exec);
long timeTillRun = freq + delay;
info("Going to wait for the first run: " + timeTillRun);
latch.await(timeTillRun, SECONDS);
assertEquals(0, latch.getCount());
assert !fut.isDone();
assert !fut.isCancelled();
assert fut.last() == null;
assertFalse(chained1.isDone());
info("Going to wait for 2nd run: " + timeTillRun);
// Wait until scheduling will be finished.
Thread.sleep(timeTillRun * 1000);
assert fut.isDone();
assert notifyCnt.get() == 2 * 2;
assert !fut.isCancelled();
assert fut.last() == null;
assertEquals("done-custom", chained1.get());
assertTrue(chained1.isDone());
} finally {
assert fut != null;
fut.cancel();
}
}
use of org.apache.ignite.lang.IgniteInClosure in project ignite by apache.
the class IgniteFutureImplTest method testChainError.
/**
* @throws Exception If failed.
*/
@Test
public void testChainError() throws Exception {
{
GridFutureAdapter<String> fut0 = new GridFutureAdapter<>();
IgniteFutureImpl<String> fut = createFuture(fut0);
final IgniteException err0 = new IgniteException("test error");
final AtomicBoolean chainedPassed = new AtomicBoolean();
IgniteFuture<Integer> chained = fut.chain(new C1<IgniteFuture<String>, Integer>() {
@Override
public Integer apply(IgniteFuture<String> fut) {
try {
fut.get();
fail();
return -1;
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
chainedPassed.set(true);
throw err;
}
}
});
final AtomicBoolean lsnrPassed = new AtomicBoolean();
IgniteInClosure<? super IgniteFuture<Integer>> lsnr1 = new CI1<IgniteFuture<Integer>>() {
@Override
public void apply(IgniteFuture<Integer> fut) {
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
lsnrPassed.set(true);
}
}
};
chained.listen(lsnr1);
fut0.onDone(err0);
assertTrue(chainedPassed.get());
assertTrue(lsnrPassed.get());
try {
chained.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
}
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
}
}
{
GridFutureAdapter<String> fut0 = new GridFutureAdapter<>();
IgniteFutureImpl<String> fut = createFuture(fut0);
final IgniteCheckedException err0 = new IgniteCheckedException("test error");
final AtomicBoolean chainedPassed = new AtomicBoolean();
IgniteFuture<Integer> chained = fut.chain(new C1<IgniteFuture<String>, Integer>() {
@Override
public Integer apply(IgniteFuture<String> fut) {
try {
fut.get();
fail();
return -1;
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
chainedPassed.set(true);
throw err;
}
}
});
final AtomicBoolean lsnrPassed = new AtomicBoolean();
IgniteInClosure<? super IgniteFuture<Integer>> lsnr1 = new CI1<IgniteFuture<Integer>>() {
@Override
public void apply(IgniteFuture<Integer> fut) {
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
lsnrPassed.set(true);
}
}
};
chained.listen(lsnr1);
fut0.onDone(err0);
assertTrue(chainedPassed.get());
assertTrue(lsnrPassed.get());
try {
chained.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
}
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
}
}
}
use of org.apache.ignite.lang.IgniteInClosure in project ignite by apache.
the class IgniteFutureImplTest method testListenersOnError.
/**
* @throws Exception If failed.
*/
@Test
public void testListenersOnError() throws Exception {
{
GridFutureAdapter<String> fut0 = new GridFutureAdapter<>();
IgniteFutureImpl<String> fut = createFuture(fut0);
final IgniteException err0 = new IgniteException("test error");
final AtomicBoolean passed = new AtomicBoolean();
IgniteInClosure<? super IgniteFuture<String>> lsnr1 = new CI1<IgniteFuture<String>>() {
@Override
public void apply(IgniteFuture<String> fut) {
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
passed.set(true);
}
}
};
fut.listen(lsnr1);
fut0.onDone(err0);
assertTrue(passed.get());
}
{
GridFutureAdapter<String> fut0 = new GridFutureAdapter<>();
IgniteFutureImpl<String> fut = createFuture(fut0);
final IgniteCheckedException err0 = new IgniteCheckedException("test error");
final AtomicBoolean passed = new AtomicBoolean();
IgniteInClosure<? super IgniteFuture<String>> lsnr1 = new CI1<IgniteFuture<String>>() {
@Override
public void apply(IgniteFuture<String> fut) {
try {
fut.get();
fail();
} catch (IgniteException | CacheException err) {
assertExpectedException(err, err0);
passed.set(true);
}
}
};
fut.listen(lsnr1);
fut0.onDone(err0);
assertTrue(passed.get());
}
}
Aggregations