use of org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable in project ignite by apache.
the class GridMapQueryExecutor method reservePartitions.
/**
* @param cacheIds Cache IDs.
* @param topVer Topology version.
* @param explicitParts Explicit partitions list.
* @param reserved Reserved list.
* @return {@code true} If all the needed partitions successfully reserved.
* @throws IgniteCheckedException If failed.
*/
private boolean reservePartitions(@Nullable List<Integer> cacheIds, AffinityTopologyVersion topVer, final int[] explicitParts, List<GridReservable> reserved) throws IgniteCheckedException {
assert topVer != null;
if (F.isEmpty(cacheIds))
return true;
Collection<Integer> partIds = wrap(explicitParts);
for (int i = 0; i < cacheIds.size(); i++) {
GridCacheContext<?, ?> cctx = ctx.cache().context().cacheContext(cacheIds.get(i));
if (// Cache was not found, probably was not deployed yet.
cctx == null)
return false;
if (cctx.isLocal() || !cctx.rebalanceEnabled())
continue;
// For replicated cache topology version does not make sense.
final MapReservationKey grpKey = new MapReservationKey(cctx.name(), cctx.isReplicated() ? null : topVer);
GridReservable r = reservations.get(grpKey);
if (explicitParts == null && r != null) {
// Try to reserve group partition if any and no explicits.
if (r != MapReplicatedReservation.INSTANCE) {
if (!r.reserve())
// We need explicit partitions here -> retry.
return false;
reserved.add(r);
}
} else {
// Try to reserve partitions one by one.
int partsCnt = cctx.affinity().partitions();
if (cctx.isReplicated()) {
// Check all the partitions are in owning state for replicated cache.
if (r == null) {
// Check only once.
for (int p = 0; p < partsCnt; p++) {
GridDhtLocalPartition part = partition(cctx, p);
// We don't need to reserve partitions because they will not be evicted in replicated caches.
if (part == null || part.state() != OWNING)
return false;
}
// Mark that we checked this replicated cache.
reservations.putIfAbsent(grpKey, MapReplicatedReservation.INSTANCE);
}
} else {
// Reserve primary partitions for partitioned cache (if no explicit given).
if (explicitParts == null)
partIds = cctx.affinity().primaryPartitions(ctx.localNodeId(), topVer);
for (int partId : partIds) {
GridDhtLocalPartition part = partition(cctx, partId);
if (part == null || part.state() != OWNING || !part.reserve())
return false;
reserved.add(part);
// Double check that we are still in owning state and partition contents are not cleared.
if (part.state() != OWNING)
return false;
}
if (explicitParts == null) {
// We reserved all the primary partitions for cache, attempt to add group reservation.
GridDhtPartitionsReservation grp = new GridDhtPartitionsReservation(topVer, cctx, "SQL");
if (grp.register(reserved.subList(reserved.size() - partIds.size(), reserved.size()))) {
if (reservations.putIfAbsent(grpKey, grp) != null)
throw new IllegalStateException("Reservation already exists.");
grp.onPublish(new CI1<GridDhtPartitionsReservation>() {
@Override
public void apply(GridDhtPartitionsReservation r) {
reservations.remove(grpKey, r);
}
});
}
}
}
}
}
return true;
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable in project ignite by apache.
the class GridDhtPartitionsReservation method register.
/**
* Registers all the given partitions for this reservation.
*
* @param parts Partitions.
* @return {@code true} If registration succeeded and this reservation can be published.
*/
public boolean register(Collection<? extends GridReservable> parts) {
assert !F.isEmpty(parts) : "empty partitions list";
GridDhtLocalPartition[] arr = new GridDhtLocalPartition[parts.size()];
int i = 0;
int prevPart = -1;
// Most probably it is a sorted list.
boolean sorted = true;
for (GridReservable part : parts) {
arr[i] = (GridDhtLocalPartition) part;
if (sorted) {
// Make sure it will be a sorted array.
int id = arr[i].id();
if (id <= prevPart)
sorted = false;
prevPart = id;
}
i++;
}
if (!sorted)
Arrays.sort(arr);
i = 0;
prevPart = -1;
// Register in correct sort order.
for (GridDhtLocalPartition part : arr) {
if (prevPart == part.id())
throw new IllegalStateException("Duplicated partitions.");
prevPart = part.id();
if (!part.addReservation(this)) {
if (i != 0)
throw new IllegalStateException("Trying to reserve different sets of partitions for the same topology version.");
return false;
}
i++;
}
if (!this.parts.compareAndSet(null, arr))
throw new IllegalStateException("Partitions can be registered only once.");
assert reservations.get() != -1 : "all the partitions must be reserved before register, we can't be invalidated";
return true;
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable in project ignite by apache.
the class ComputeJobView method affinityCacheIds.
/**
* @return Comma separated list of cache identifiers or {@code null} for non affinity call.
*/
@Order(5)
public String affinityCacheIds() {
GridReservable res = job.getPartsReservation();
if (!(res instanceof GridJobProcessor.PartitionsReservation))
return null;
int[] ids = ((GridJobProcessor.PartitionsReservation) res).getCacheIds();
if (ids == null || ids.length == 0)
return null;
StringJoiner joiner = new StringJoiner(",");
for (int id : ids) joiner.add(Integer.toString(id));
return joiner.toString();
}
use of org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable in project ignite by apache.
the class RetryCauseMessageSelfTest method testGrpReservationFailureMessage.
/**
* Failed to reserve partitions for query (group reservation failed)
*/
@Test
public void testGrpReservationFailureMessage() {
final GridMapQueryExecutor mapQryExec = GridTestUtils.getFieldValue(h2Idx, IgniteH2Indexing.class, "mapQryExec");
final ConcurrentMap<PartitionReservationKey, GridReservable> reservations = reservations(h2Idx);
GridTestUtils.setFieldValue(h2Idx, "mapQryExec", new MockGridMapQueryExecutor() {
@Override
public void onQueryRequest(ClusterNode node, GridH2QueryRequest qryReq) throws IgniteCheckedException {
final PartitionReservationKey grpKey = new PartitionReservationKey(ORG, null);
reservations.put(grpKey, new GridReservable() {
@Override
public boolean reserve() {
return false;
}
@Override
public void release() {
}
});
startedExecutor.onQueryRequest(node, qryReq);
}
}.insertRealExecutor(mapQryExec));
SqlQuery<String, Person> qry = new SqlQuery<String, Person>(Person.class, JOIN_SQL).setArgs("Organization #0");
qry.setDistributedJoins(true);
try {
personCache.query(qry).getAll();
} catch (CacheException e) {
assertTrue(e.getMessage().contains("Failed to reserve partitions for query (group reservation failed) ["));
return;
} finally {
GridTestUtils.setFieldValue(h2Idx, "mapQryExec", mapQryExec);
}
fail();
}
Aggregations