use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class ConcurrentSerialGatewaySenderEventProcessor method enqueueEvent.
public void enqueueEvent(EnumListenerEvent operation, EntryEvent event, Object substituteValue, int index) throws CacheException, IOException {
// Get the appropriate gateway
SerialGatewaySenderEventProcessor serialProcessor = this.processors.get(index);
if (sender.getOrderPolicy() == OrderPolicy.KEY || sender.getOrderPolicy() == OrderPolicy.PARTITION) {
// Create copy since the event id will be changed, otherwise the same
// event will be changed for multiple gateways. Fix for bug 44471.
@Released EntryEventImpl clonedEvent = new EntryEventImpl((EntryEventImpl) event);
try {
EventID originalEventId = clonedEvent.getEventId();
if (logger.isDebugEnabled()) {
logger.debug("The original EventId is {}", originalEventId);
}
// PARALLEL_THREAD_BUFFER * (index +1) + originalEventId.getThreadID();
// generating threadId by the algorithm explained above used to clash with
// fakeThreadId generated by putAll
// below is new way to generate threadId so that it doesn't clash with
// any.
long newThreadId = ThreadIdentifier.createFakeThreadIDForParallelGateway(index, originalEventId.getThreadID(), 0);
EventID newEventId = new EventID(originalEventId.getMembershipID(), newThreadId, originalEventId.getSequenceID());
if (logger.isDebugEnabled()) {
logger.debug("{}: Generated event id for event with key={}, index={}, original event id={}, threadId={}, new event id={}, newThreadId={}", this, event.getKey(), index, originalEventId, originalEventId.getThreadID(), newEventId, newThreadId);
}
clonedEvent.setEventId(newEventId);
serialProcessor.enqueueEvent(operation, clonedEvent, substituteValue);
} finally {
clonedEvent.release();
}
} else {
serialProcessor.enqueueEvent(operation, event, substituteValue);
}
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class AbstractGatewaySender method distribute.
public void distribute(EnumListenerEvent operation, EntryEventImpl event, List<Integer> allRemoteDSIds) {
final boolean isDebugEnabled = logger.isDebugEnabled();
// If this gateway is not running, return
if (!isRunning()) {
if (isDebugEnabled) {
logger.debug("Returning back without putting into the gateway sender queue");
}
return;
}
final GatewaySenderStats stats = getStatistics();
stats.incEventsReceived();
if (!checkForDistribution(event, stats)) {
stats.incEventsNotQueued();
return;
}
// not considering this filter
if (!this.filter.enqueueEvent(event)) {
stats.incEventsFiltered();
return;
}
// released by this method or transfers ownership to TmpQueueEvent
@Released EntryEventImpl clonedEvent = new EntryEventImpl(event, false);
boolean freeClonedEvent = true;
try {
Region region = event.getRegion();
setModifiedEventId(clonedEvent);
Object callbackArg = clonedEvent.getRawCallbackArgument();
if (isDebugEnabled) {
// We can't deserialize here for logging purposes so don't
// call getNewValue.
// event.getNewValue(); // to deserialize the value if necessary
logger.debug("{} : About to notify {} to perform operation {} for {} callback arg {}", this.isPrimary(), getId(), operation, clonedEvent, callbackArg);
}
if (callbackArg instanceof GatewaySenderEventCallbackArgument) {
GatewaySenderEventCallbackArgument seca = (GatewaySenderEventCallbackArgument) callbackArg;
if (isDebugEnabled) {
logger.debug("{}: Event originated in {}. My DS id is {}. The remote DS id is {}. The recipients are: {}", this, seca.getOriginatingDSId(), this.getMyDSId(), this.getRemoteDSId(), seca.getRecipientDSIds());
}
if (seca.getOriginatingDSId() == DEFAULT_DISTRIBUTED_SYSTEM_ID) {
if (isDebugEnabled) {
logger.debug("{}: Event originated in {}. My DS id is {}. The remote DS id is {}. The recipients are: {}", this, seca.getOriginatingDSId(), this.getMyDSId(), this.getRemoteDSId(), seca.getRecipientDSIds());
}
seca.setOriginatingDSId(this.getMyDSId());
seca.initializeReceipientDSIds(allRemoteDSIds);
} else {
// if the dispatcher is GatewaySenderEventCallbackDispatcher (which is the case of WBCL),
// skip the below check of remoteDSId.
// Fix for #46517
AbstractGatewaySenderEventProcessor ep = getEventProcessor();
if (ep != null && !(ep.getDispatcher() instanceof GatewaySenderEventCallbackDispatcher)) {
if (seca.getOriginatingDSId() == this.getRemoteDSId()) {
if (isDebugEnabled) {
logger.debug("{}: Event originated in {}. My DS id is {}. It is being dropped as remote is originator.", this, seca.getOriginatingDSId(), getMyDSId());
}
return;
} else if (seca.getRecipientDSIds().contains(this.getRemoteDSId())) {
if (isDebugEnabled) {
logger.debug("{}: Event originated in {}. My DS id is {}. The remote DS id is {}.. It is being dropped as remote ds is already a recipient. Recipients are: {}", this, seca.getOriginatingDSId(), getMyDSId(), this.getRemoteDSId(), seca.getRecipientDSIds());
}
return;
}
}
seca.getRecipientDSIds().addAll(allRemoteDSIds);
}
} else {
GatewaySenderEventCallbackArgument geCallbackArg = new GatewaySenderEventCallbackArgument(callbackArg, this.getMyDSId(), allRemoteDSIds);
clonedEvent.setCallbackArgument(geCallbackArg);
}
if (!this.getLifeCycleLock().readLock().tryLock()) {
synchronized (this.queuedEventsSync) {
if (!this.enqueuedAllTempQueueEvents) {
if (!this.getLifeCycleLock().readLock().tryLock()) {
Object substituteValue = getSubstituteValue(clonedEvent, operation);
this.tmpQueuedEvents.add(new TmpQueueEvent(operation, clonedEvent, substituteValue));
freeClonedEvent = false;
stats.incTempQueueSize();
if (isDebugEnabled) {
logger.debug("Event : {} is added to TempQueue", clonedEvent);
}
return;
}
}
}
if (this.enqueuedAllTempQueueEvents) {
this.getLifeCycleLock().readLock().lock();
}
}
try {
// The sender may have stopped, after we have checked the status in the beginning.
if (!isRunning()) {
if (isDebugEnabled) {
logger.debug("Returning back without putting into the gateway sender queue");
}
return;
}
try {
AbstractGatewaySenderEventProcessor ev = this.eventProcessor;
if (ev == null) {
getStopper().checkCancelInProgress(null);
this.getCache().getDistributedSystem().getCancelCriterion().checkCancelInProgress(null);
// connecting to the other site (bug #40681)
if (ev == null) {
throw new GatewayCancelledException("Event processor thread is gone");
}
}
// Get substitution value to enqueue if necessary
Object substituteValue = getSubstituteValue(clonedEvent, operation);
ev.enqueueEvent(operation, clonedEvent, substituteValue);
} catch (CancelException e) {
logger.debug("caught cancel exception", e);
throw e;
} catch (RegionDestroyedException e) {
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewayImpl_0_AN_EXCEPTION_OCCURRED_WHILE_QUEUEING_1_TO_PERFORM_OPERATION_2_FOR_3, new Object[] { this, getId(), operation, clonedEvent }), e);
} catch (Exception e) {
logger.fatal(LocalizedMessage.create(LocalizedStrings.GatewayImpl_0_AN_EXCEPTION_OCCURRED_WHILE_QUEUEING_1_TO_PERFORM_OPERATION_2_FOR_3, new Object[] { this, getId(), operation, clonedEvent }), e);
}
} finally {
this.getLifeCycleLock().readLock().unlock();
}
} finally {
if (freeClonedEvent) {
// fix for bug 48035
clonedEvent.release();
}
}
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class GatewaySenderEventImpl method release.
@Override
@Released(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE)
public synchronized void release() {
@Released(OffHeapIdentifier.GATEWAY_SENDER_EVENT_IMPL_VALUE) Object vo = this.valueObj;
if (OffHeapHelper.releaseAndTrackOwner(vo, this)) {
this.valueObj = null;
this.valueObjReleased = true;
}
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class LocalRegion method basicBridgePutIfAbsent.
// TODO: fromClient is always null
public Object basicBridgePutIfAbsent(final Object key, Object value, boolean isObject, Object callbackArg, final ClientProxyMembershipID client, boolean fromClient, EntryEventImpl clientEvent) throws TimeoutException, EntryExistsException, CacheWriterException {
EventID eventId = clientEvent.getEventId();
long startPut = CachePerfStats.getStatTime();
if (fromClient) {
// GatewayEventCallbackArgument to store the event id.
if (isGatewaySenderEnabled()) {
callbackArg = new GatewaySenderEventCallbackArgument(callbackArg);
}
}
@Released final EntryEventImpl event = EntryEventImpl.create(this, Operation.PUT_IF_ABSENT, key, null, callbackArg, false, client.getDistributedMember(), true, eventId);
try {
event.setContext(client);
// if this is a replayed operation we may already have a version tag
event.setVersionTag(clientEvent.getVersionTag());
// Set the new value to the input byte[] if it isn't null
if (value != null) {
// in a CachedDeserializable; otherwise store it directly as a byte[]
if (isObject) {
// The value represents an object
event.setSerializedNewValue((byte[]) value);
} else {
// The value does not represent an object
event.setNewValue(value);
}
}
validateArguments(key, event.basicGetNewValue(), callbackArg);
// cannot overwrite an existing key
boolean ifNew = true;
// can create a new key
boolean ifOld = false;
// need the old value if the create fails
boolean requireOldValue = true;
boolean basicPut = basicPut(event, ifNew, ifOld, null, requireOldValue);
getCachePerfStats().endPut(startPut, false);
this.stopper.checkCancelInProgress(null);
// to fix bug 42968 call getRawOldValue instead of getOldValue
Object oldValue = event.getRawOldValueAsHeapObject();
if (oldValue == Token.NOT_AVAILABLE) {
oldValue = AbstractRegion.handleNotAvailable(oldValue);
}
if (basicPut) {
clientEvent.setVersionTag(event.getVersionTag());
clientEvent.isConcurrencyConflict(event.isConcurrencyConflict());
} else if (oldValue == null) {
// this case from successful operation
return Token.INVALID;
}
return oldValue;
} finally {
event.release();
}
}
use of org.apache.geode.internal.offheap.annotations.Released 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;
}
Aggregations