use of org.apache.geode.internal.cache.tier.sockets.VersionedObjectList in project geode by apache.
the class PutAll80 method writeReply.
protected void writeReply(Message origMsg, VersionedObjectList response, ServerConnection servConn) throws IOException {
servConn.getCache().getCancelCriterion().checkCancelInProgress(null);
ChunkedMessage replyMsg = servConn.getChunkedResponseMessage();
replyMsg.setMessageType(MessageType.RESPONSE);
replyMsg.setTransactionId(origMsg.getTransactionId());
int listSize = (response == null) ? 0 : response.size();
if (response != null) {
response.setKeys(null);
}
if (logger.isDebugEnabled()) {
logger.debug("sending chunked response header. version list size={}{}", listSize, (logger.isTraceEnabled() ? " list=" + response : ""));
}
replyMsg.sendHeader();
if (listSize > 0) {
int chunkSize = 2 * MAXIMUM_CHUNK_SIZE;
// Chunker will stream over the list in its toData method
VersionedObjectList.Chunker chunk = new VersionedObjectList.Chunker(response, chunkSize, false, false);
for (int i = 0; i < listSize; i += chunkSize) {
boolean lastChunk = (i + chunkSize >= listSize);
replyMsg.setNumberOfParts(1);
replyMsg.setMessageType(MessageType.RESPONSE);
replyMsg.setLastChunk(lastChunk);
replyMsg.setTransactionId(origMsg.getTransactionId());
replyMsg.addObjPart(chunk);
if (logger.isDebugEnabled()) {
logger.debug("sending chunk at index {} last chunk={} numParts={}", i, lastChunk, replyMsg.getNumberOfParts());
}
replyMsg.sendChunk(servConn);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("sending only header");
}
replyMsg.addObjPart(null);
replyMsg.setLastChunk(true);
replyMsg.sendChunk(servConn);
}
servConn.setAsTrue(RESPONDED);
if (logger.isTraceEnabled()) {
logger.trace("{}: rpl tx: {}", servConn.getName(), origMsg.getTransactionId());
}
}
use of org.apache.geode.internal.cache.tier.sockets.VersionedObjectList in project geode by apache.
the class LocalRegion method basicRemoveAll.
VersionedObjectList basicRemoveAll(final Collection<Object> keys, final DistributedRemoveAllOperation removeAllOp, final List<VersionTag> retryVersions) {
final boolean isDebugEnabled = logger.isDebugEnabled();
final boolean isTraceEnabled = logger.isTraceEnabled();
final EntryEventImpl event = removeAllOp.getBaseEvent();
EventID eventId = event.getEventId();
if (eventId == null && generateEventID()) {
// We need to "reserve" the eventIds for the entries in map here
event.reserveNewEventId(this.cache.getDistributedSystem(), keys.size());
eventId = event.getEventId();
}
verifyRemoveAllKeys(keys);
VersionedObjectList proxyResult = null;
boolean partialResult = false;
RuntimeException runtimeException = null;
if (hasServerProxy()) {
// send message to bridge server
if (isTX()) {
TXStateProxyImpl txState = (TXStateProxyImpl) this.cache.getTxManager().getTXState();
txState.getRealDeal(null, this);
}
try {
proxyResult = getServerProxy().removeAll(keys, eventId, event.getCallbackArgument());
if (isDebugEnabled) {
logger.debug("removeAll received response from server: {}", proxyResult);
}
} catch (PutAllPartialResultException e) {
// adjust the map to only add succeeded entries, then apply the adjustedMap
proxyResult = e.getSucceededKeysAndVersions();
partialResult = true;
if (isDebugEnabled) {
logger.debug("removeAll in client encountered a BulkOpPartialResultException: {}{}. Adjusted keys are: {}", e.getMessage(), getLineSeparator(), proxyResult.getKeys());
}
Throwable txException = e.getFailure();
while (txException != null) {
if (txException instanceof TransactionException) {
runtimeException = (RuntimeException) txException;
break;
}
txException = txException.getCause();
}
if (runtimeException == null) {
runtimeException = new ServerOperationException(LocalizedStrings.Region_RemoveAll_Applied_PartialKeys_At_Server_0.toLocalizedString(getFullPath()), e.getFailure());
}
}
}
final VersionedObjectList succeeded = new VersionedObjectList(keys.size(), true, this.concurrencyChecksEnabled);
// If this is a transactional removeAll, we will not have version information as it is only
// generated at commit
// so treat transactional removeAll as if the server is not versioned.
// If we have no storage then act as if the server is not versioned.
final boolean serverIsVersioned = proxyResult != null && proxyResult.regionIsVersioned() && !isTX() && getDataPolicy().withStorage();
if (!serverIsVersioned && !partialResult) {
// since the server is not versioned and we do not have a partial result
// get rid of the proxyResult info returned by the server.
proxyResult = null;
}
lockRVVForBulkOp();
try {
try {
int size = proxyResult == null ? keys.size() : proxyResult.size();
if (isInternalRegion()) {
if (isTraceEnabled) {
logger.trace("size of removeAll result is {} keys are {} proxyResult is {}", size, keys, proxyResult);
} else {
if (isTraceEnabled) {
logger.trace("size of removeAll result is {} keys are {} proxyResult is {}", size, keys, proxyResult);
}
}
} else {
if (isTraceEnabled) {
logger.trace("size of removeAll result is {} keys are {} proxyResult is {}", size, keys, proxyResult);
}
}
final PutAllPartialResult partialKeys = new PutAllPartialResult(size);
final Iterator iterator;
final boolean isVersionedResults;
if (proxyResult != null) {
iterator = proxyResult.iterator();
isVersionedResults = true;
} else {
iterator = keys.iterator();
isVersionedResults = false;
}
// TODO: refactor this mess
Runnable task = new Runnable() {
@Override
public void run() {
int offset = 0;
VersionTagHolder tagHolder = new VersionTagHolder();
while (iterator.hasNext()) {
stopper.checkCancelInProgress(null);
tagHolder.setVersionTag(null);
Object key;
VersionTag versionTag = null;
if (isVersionedResults) {
Map.Entry mapEntry = (Map.Entry) iterator.next();
key = mapEntry.getKey();
versionTag = ((VersionedObjectList.Entry) mapEntry).getVersionTag();
if (isDebugEnabled) {
logger.debug("removeAll key {} version={}", key, versionTag);
}
if (versionTag == null) {
if (isDebugEnabled) {
logger.debug("removeAll found invalid version tag, which means the entry is not found at server for key={}.", key);
}
succeeded.addKeyAndVersion(key, null);
continue;
}
// No need for special handling here in removeAll.
// We can just remove this key from the client with versionTag set to null.
} else {
key = iterator.next();
if (isTraceEnabled) {
logger.trace("removeAll {}", key);
}
}
try {
if (serverIsVersioned) {
if (isDebugEnabled) {
logger.debug("associating version tag with {} version={}", key, versionTag);
}
// If we have received a version tag from a server, add it to the event
tagHolder.setVersionTag(versionTag);
tagHolder.setFromServer(true);
} else if (retryVersions != null) {
VersionTag versionTag1 = retryVersions.get(offset);
if (versionTag1 != null) {
// If this is a retried event, and we have a version tag for the retry,
// add it to the event.
tagHolder.setVersionTag(versionTag1);
}
}
basicEntryRemoveAll(key, removeAllOp, offset, tagHolder);
// now we must check again since the cache may have closed during
// distribution causing this process to not receive and queue the
// event for clients
stopper.checkCancelInProgress(null);
succeeded.addKeyAndVersion(key, tagHolder.getVersionTag());
} catch (Exception ex) {
partialKeys.saveFailedKey(key, ex);
}
offset++;
}
}
};
syncBulkOp(task, eventId);
if (partialKeys.hasFailure()) {
// Bug 51725: Now succeeded contains an order key list, may be missing the version tags.
// Save reference of succeeded into partialKeys. The succeeded may be modified by
// postRemoveAll() to fill in the version tags.
partialKeys.setSucceededKeysAndVersions(succeeded);
logger.info(LocalizedMessage.create(LocalizedStrings.Region_RemoveAll_Applied_PartialKeys_0_1, new Object[] { getFullPath(), partialKeys }));
if (isDebugEnabled) {
logger.debug(partialKeys.detailString());
}
if (runtimeException == null) {
// if received exception from server first, ignore local exception
if (removeAllOp.isBridgeOperation()) {
if (partialKeys.getFailure() instanceof CancelException) {
runtimeException = (RuntimeException) partialKeys.getFailure();
} else if (partialKeys.getFailure() instanceof LowMemoryException) {
// fix for #43589
throw partialKeys.getFailure();
} else {
runtimeException = new PutAllPartialResultException(partialKeys);
if (isDebugEnabled) {
logger.debug("basicRemoveAll: {}", partialKeys.detailString());
}
}
} else {
throw partialKeys.getFailure();
}
}
}
} catch (LowMemoryException lme) {
throw lme;
} catch (RuntimeException ex) {
runtimeException = ex;
} catch (Exception ex) {
runtimeException = new RuntimeException(ex);
} finally {
removeAllOp.getBaseEvent().release();
removeAllOp.freeOffHeapResources();
}
getDataView().postRemoveAll(removeAllOp, succeeded, this);
} finally {
unlockRVVForBulkOp();
}
if (runtimeException != null) {
throw runtimeException;
}
return succeeded;
}
use of org.apache.geode.internal.cache.tier.sockets.VersionedObjectList in project geode by apache.
the class LocalRegion method basicGetAll.
// TODO: refactor basicGetAll
@Override
Map basicGetAll(Collection keys, Object callback) {
final boolean isDebugEnabled = logger.isDebugEnabled();
final boolean isTraceEnabled = logger.isTraceEnabled();
if (isDebugEnabled) {
logger.debug("Processing getAll request for: {}", keys);
}
discoverJTA();
Map allResults = new HashMap();
if (hasServerProxy()) {
// Some of our implementation expects a list of keys so make sure it is a list
List keysList;
if (keys instanceof List) {
keysList = (List) keys;
} else {
keysList = new ArrayList(keys);
}
// We only need to do this if this region has local storage
if (getTXState() == null && hasStorage()) {
if (keysList == keys) {
// Create a copy of the collection of keys
// to keep the original collection intact
keysList = new ArrayList(keys);
}
for (Iterator iterator = keysList.iterator(); iterator.hasNext(); ) {
Object key = iterator.next();
Object value;
Region.Entry entry = accessEntry(key, true);
if (entry != null && (value = entry.getValue()) != null) {
allResults.put(key, value);
iterator.remove();
}
}
if (isDebugEnabled) {
logger.debug("Added local results for getAll request: {}", allResults);
}
}
// Send the rest of the keys to the server (if necessary)
if (!keysList.isEmpty()) {
VersionedObjectList remoteResults = getServerProxy().getAll(keysList, callback);
if (isDebugEnabled) {
logger.debug("remote getAll results are {}", remoteResults);
}
// Add remote results to local cache and all results if successful
for (VersionedObjectList.Iterator it = remoteResults.iterator(); it.hasNext(); ) {
VersionedObjectList.Entry entry = it.next();
Object key = entry.getKey();
boolean notOnServer = entry.isKeyNotOnServer();
// in 8.0 we added transfer of tombstones with RI/getAll results for bug #40791
boolean createTombstone = false;
if (notOnServer) {
createTombstone = entry.getVersionTag() != null && this.concurrencyChecksEnabled;
allResults.put(key, null);
if (isDebugEnabled) {
logger.debug("Added remote result for missing key: {}", key);
}
if (!createTombstone) {
continue;
}
}
Object value;
if (createTombstone) {
// the value is null in this case, so use TOKEN_TOMBSTONE
value = Token.TOMBSTONE;
} else {
value = entry.getObject();
}
if (value instanceof Throwable) {
continue;
}
// The following basicPutEntry needs to be done
// even if we do not have storage so that the
// correct events will be delivered to any callbacks we have.
long startPut = CachePerfStats.getStatTime();
validateKey(key);
@Released EntryEventImpl event = EntryEventImpl.create(this, Operation.LOCAL_LOAD_CREATE, key, value, callback, false, getMyId(), true);
try {
event.setFromServer(true);
event.setVersionTag(entry.getVersionTag());
if (!alreadyInvalid(key, event)) {
// bug #47716 - don't update if it's already here & invalid
TXStateProxy txState = this.cache.getTXMgr().internalSuspend();
try {
basicPutEntry(event, 0L);
} catch (ConcurrentCacheModificationException e) {
if (isDebugEnabled) {
logger.debug("getAll result for {} not stored in cache due to concurrent modification", key, e);
}
} finally {
this.cache.getTXMgr().internalResume(txState);
}
getCachePerfStats().endPut(startPut, event.isOriginRemote());
}
if (!createTombstone) {
allResults.put(key, value);
if (isTraceEnabled) {
logger.trace("Added remote result for getAll request: {}, {}", key, value);
}
}
} finally {
event.release();
}
}
}
} else {
// functionality. It needs to be rewritten more efficiently.
for (Object key : keys) {
try {
allResults.put(key, get(key, callback));
} catch (Exception e) {
logger.warn(LocalizedMessage.create(LocalizedStrings.LocalRegion_THE_FOLLOWING_EXCEPTION_OCCURRED_ATTEMPTING_TO_GET_KEY_0, key), e);
}
}
}
return allResults;
}
use of org.apache.geode.internal.cache.tier.sockets.VersionedObjectList in project geode by apache.
the class LocalRegion method basicImportPutAll.
// TODO: return value is never used
public VersionedObjectList basicImportPutAll(Map map, boolean skipCallbacks) {
long startPut = CachePerfStats.getStatTime();
@Released EntryEventImpl event = EntryEventImpl.create(this, Operation.PUTALL_CREATE, null, null, null, true, getMyId(), !skipCallbacks);
try {
DistributedPutAllOperation putAllOp = new DistributedPutAllOperation(event, map.size(), false);
try {
VersionedObjectList result = basicPutAll(map, putAllOp, null);
getCachePerfStats().endPutAll(startPut);
return result;
} finally {
putAllOp.freeOffHeapResources();
}
} finally {
event.release();
}
}
use of org.apache.geode.internal.cache.tier.sockets.VersionedObjectList in project geode by apache.
the class LocalRegion method basicBridgeRemoveAll.
/**
* Called on a bridge server when it has a received a removeAll command from a client.
*
* @param keys a collection of the keys we are putting
* @param retryVersions a collection of version tags. If the client is retrying a key then that
* keys slot will be non-null in this collection. Note that keys and retryVersions are
* parallel lists.
* @param callbackArg callback argument from client
*/
public VersionedObjectList basicBridgeRemoveAll(List<Object> keys, ArrayList<VersionTag> retryVersions, ClientProxyMembershipID memberId, EventID eventId, Object callbackArg) throws TimeoutException, CacheWriterException {
long startOp = CachePerfStats.getStatTime();
if (isGatewaySenderEnabled()) {
callbackArg = new GatewaySenderEventCallbackArgument(callbackArg);
}
@Released final EntryEventImpl event = EntryEventImpl.create(this, Operation.REMOVEALL_DESTROY, null, null, /* new value */
callbackArg, false, /* origin remote */
memberId.getDistributedMember(), true, /* generateCallbacks */
eventId);
try {
event.setContext(memberId);
DistributedRemoveAllOperation removeAllOp = new DistributedRemoveAllOperation(event, keys.size(), true);
try {
VersionedObjectList result = basicRemoveAll(keys, removeAllOp, retryVersions);
getCachePerfStats().endRemoveAll(startOp);
return result;
} finally {
removeAllOp.freeOffHeapResources();
}
} finally {
event.release();
}
}
Aggregations