use of org.apache.geode.distributed.internal.ServerLocation in project geode by apache.
the class PutAllOp method execute.
/**
* Does a region put on a server using connections from the given pool to communicate with the
* server.
*
* @param pool the pool to use to communicate with the server.
* @param region the name of the region to do the putAll on
* @param map the Map of keys and values to put
* @param eventId the event id for this putAll
*/
public static VersionedObjectList execute(ExecutablePool pool, Region region, Map map, EventID eventId, boolean skipCallbacks, int retryAttempts, Object callbackArg) {
ClientMetadataService cms = ((LocalRegion) region).getCache().getClientMetadataService();
Map<ServerLocation, HashSet> serverToFilterMap = cms.getServerToFilterMap(map.keySet(), region, true);
if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {
AbstractOp op = new PutAllOpImpl(region, map, eventId, ((PoolImpl) pool).getPRSingleHopEnabled(), skipCallbacks, callbackArg);
op.initMessagePart();
return (VersionedObjectList) pool.execute(op);
}
List callableTasks = constructAndGetPutAllTasks(region, map, eventId, skipCallbacks, serverToFilterMap, (PoolImpl) pool, callbackArg);
final boolean isDebugEnabled = logger.isDebugEnabled();
if (isDebugEnabled) {
logger.debug("PutAllOp#execute : Number of putAll tasks is : {}", callableTasks.size());
}
HashMap<ServerLocation, RuntimeException> failedServers = new HashMap<ServerLocation, RuntimeException>();
PutAllPartialResult result = new PutAllPartialResult(map.size());
try {
Map<ServerLocation, Object> results = SingleHopClientExecutor.submitBulkOp(callableTasks, cms, (LocalRegion) region, failedServers);
for (Map.Entry<ServerLocation, Object> entry : results.entrySet()) {
Object value = entry.getValue();
if (value instanceof PutAllPartialResultException) {
PutAllPartialResultException pap = (PutAllPartialResultException) value;
if (isDebugEnabled) {
logger.debug("PutAll SingleHop encountered PutAllPartialResultException exception: {}, failedServers are {}", pap, failedServers.keySet());
}
result.consolidate(pap.getResult());
} else {
if (value != null) {
VersionedObjectList list = (VersionedObjectList) value;
result.addKeysAndVersions(list);
}
}
}
} catch (RuntimeException ex) {
if (isDebugEnabled) {
logger.debug("single-hop putAll encountered unexpected exception: ", ex);
}
throw ex;
}
if (!failedServers.isEmpty()) {
if (retryAttempts == 0) {
throw failedServers.values().iterator().next();
}
// add them to the partial result set
if (result.getSucceededKeysAndVersions().size() == 0) {
// if there're failed servers, we need to save the succeed keys in submitPutAll
// if retry succeeded, everything is ok, otherwise, the saved "succeeded
// keys" should be consolidated into PutAllPartialResultException
// succeedKeySet is used to send back to client in PartialResult case
// so it's not a must to use LinkedHashSet
Set succeedKeySet = new LinkedHashSet();
Set<ServerLocation> serverSet = serverToFilterMap.keySet();
for (ServerLocation server : serverSet) {
if (!failedServers.containsKey(server)) {
succeedKeySet.addAll(serverToFilterMap.get(server));
}
}
// save succeedKeys, but if retries all succeeded, discard the PutAllPartialResult
result.addKeys(succeedKeySet);
}
// send maps for the failed servers one by one instead of merging
// them into one big map. The reason is, we have to keep the same event
// ids for each sub map. There is a unit test in PutAllCSDUnitTest for
// the otherwise case.
boolean oneSubMapRetryFailed = false;
Set<ServerLocation> failedServerSet = failedServers.keySet();
for (ServerLocation failedServer : failedServerSet) {
// Throwable failedServers.values().iterator().next();
RuntimeException savedRTE = failedServers.get(failedServer);
if (savedRTE instanceof PutAllPartialResultException) {
// will not retry for PutAllPartialResultException
// but it means at least one sub map ever failed
oneSubMapRetryFailed = true;
continue;
}
Map newMap = new LinkedHashMap();
Set keySet = serverToFilterMap.get(failedServer);
for (Object key : keySet) {
newMap.put(key, map.get(key));
}
try {
VersionedObjectList v = PutAllOp.execute(pool, region, newMap, eventId, skipCallbacks, true, callbackArg);
if (v == null) {
result.addKeys(keySet);
} else {
result.addKeysAndVersions(v);
}
} catch (PutAllPartialResultException pre) {
oneSubMapRetryFailed = true;
if (logger.isDebugEnabled()) {
logger.debug("Retry failed with PutAllPartialResultException: {} Before retry: {}", pre, result.getKeyListString());
}
result.consolidate(pre.getResult());
} catch (Exception rte) {
oneSubMapRetryFailed = true;
Object firstKey = newMap.keySet().iterator().next();
result.saveFailedKey(firstKey, rte);
}
}
// If all retries succeeded, the PRE in first tries can be ignored
if (oneSubMapRetryFailed && result.hasFailure()) {
PutAllPartialResultException pre = new PutAllPartialResultException(result);
throw pre;
}
}
return result.getSucceededKeysAndVersions();
}
use of org.apache.geode.distributed.internal.ServerLocation in project geode by apache.
the class ExecuteFunctionOp method constructAndGetFunctionTasks.
static List constructAndGetFunctionTasks(final PoolImpl pool, final String functionId, Object args, MemberMappedArgument memberMappedArg, byte hasResult, ResultCollector rc, boolean isFnSerializationReqd, boolean isHA, boolean optimizeForWrite, UserAttributes properties) {
final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
List<ServerLocation> servers = pool.getConnectionSource().getAllServers();
for (ServerLocation server : servers) {
final AbstractOp op = new ExecuteFunctionOpImpl(functionId, args, memberMappedArg, hasResult, rc, isFnSerializationReqd, isHA, optimizeForWrite, (byte) 0, null, /* onGroups does not use single-hop for now */
false, false);
SingleHopOperationCallable task = new SingleHopOperationCallable(server, pool, op, properties);
tasks.add(task);
}
return tasks;
}
use of org.apache.geode.distributed.internal.ServerLocation in project geode by apache.
the class ExecuteRegionFunctionSingleHopOp method constructAndGetExecuteFunctionTasks.
static List<SingleHopOperationCallable> constructAndGetExecuteFunctionTasks(String region, ServerRegionFunctionExecutor serverRegionExecutor, final Map<ServerLocation, ? extends HashSet> serverToFilterMap, final PoolImpl pool, final String functionId, byte hasResult, ResultCollector rc, ClientMetadataService cms, boolean allBucket, boolean isHA, boolean optimizeForWrite) {
final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(serverToFilterMap.keySet());
if (logger.isDebugEnabled()) {
logger.debug("Constructing tasks for the servers {}", servers);
}
for (ServerLocation server : servers) {
ServerRegionFunctionExecutor executor = (ServerRegionFunctionExecutor) serverRegionExecutor.withFilter(serverToFilterMap.get(server));
AbstractOp op = new ExecuteRegionFunctionSingleHopOpImpl(region, functionId, executor, rc, hasResult, new HashSet<String>(), allBucket, isHA, optimizeForWrite);
SingleHopOperationCallable task = new SingleHopOperationCallable(new ServerLocation(server.getHostName(), server.getPort()), pool, op, UserAttributes.userAttributes.get());
tasks.add(task);
}
return tasks;
}
use of org.apache.geode.distributed.internal.ServerLocation in project geode by apache.
the class ExplicitConnectionSourceImpl method findServer.
@Override
public synchronized ServerLocation findServer(Set excludedServers) {
if (PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
return null;
}
ServerLocation nextServer;
int startIndex = nextServerIndex;
do {
nextServer = (ServerLocation) serverList.get(nextServerIndex);
if (++nextServerIndex >= serverList.size()) {
nextServerIndex = 0;
}
if (!excludedServers.contains(nextServer)) {
return nextServer;
}
} while (nextServerIndex != startIndex);
return null;
}
use of org.apache.geode.distributed.internal.ServerLocation in project geode by apache.
the class ExplicitConnectionSourceImpl method findDurableQueues.
private List findDurableQueues(Set excludedServers, int numServers) {
ArrayList durableServers = new ArrayList();
ArrayList otherServers = new ArrayList();
logger.debug("ExplicitConnectionSource - looking for durable queue");
for (Iterator itr = serverList.iterator(); itr.hasNext(); ) {
ServerLocation server = (ServerLocation) itr.next();
if (excludedServers.contains(server)) {
continue;
}
// the pool will automatically create a connection to this server
// and store it for future use.
Boolean hasQueue;
try {
hasQueue = (Boolean) pool.executeOn(server, HasQueueOp.SINGLETON);
} catch (GemFireSecurityException e) {
throw e;
} catch (Exception e) {
if (e.getCause() instanceof GemFireSecurityException) {
throw (GemFireSecurityException) e.getCause();
}
if (logger.isDebugEnabled()) {
logger.debug("Unabled to check for durable queue on server {}: {}", server, e);
}
continue;
}
if (hasQueue != null) {
if (hasQueue.booleanValue()) {
if (logger.isDebugEnabled()) {
logger.debug("Durable queue found on {}", server);
}
durableServers.add(server);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Durable queue was not found on {}", server);
}
otherServers.add(server);
}
}
}
int remainingServers = numServers - durableServers.size();
if (remainingServers > otherServers.size()) {
remainingServers = otherServers.size();
}
// but that's ok because we already shuffled the list in our constructor.
if (remainingServers > 0) {
durableServers.addAll(otherServers.subList(0, remainingServers));
nextQueueIndex = remainingServers % serverList.size();
}
if (logger.isDebugEnabled()) {
logger.debug("found {} servers out of {}", durableServers.size(), numServers);
}
return durableServers;
}
Aggregations