use of org.apache.geode.internal.cache.ha.ThreadIdentifier in project geode by apache.
the class QueueStateImpl method verifyIfDuplicate.
public boolean verifyIfDuplicate(EventID eid, boolean addToMap) {
ThreadIdentifier tid = new ThreadIdentifier(eid.getMembershipID(), eid.getThreadID());
long seqId = eid.getSequenceID();
SequenceIdAndExpirationObject seo = null;
// while the objects are being expired
synchronized (this.threadIdToSequenceId) {
seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(tid);
if (seo != null && seo.getSequenceId() >= seqId) {
if (logger.isDebugEnabled()) {
logger.debug(" got a duplicate entry with EventId {}. Ignoring the entry", eid);
}
// bug #41289: send ack to this server since it's sending old events
seo.setAckSend(false);
// seo.getSequenceId()));
return true;
} else if (addToMap) {
ThreadIdentifier real_tid = new ThreadIdentifier(eid.getMembershipID(), ThreadIdentifier.getRealThreadIDIncludingWan(eid.getThreadID()));
if (ThreadIdentifier.isPutAllFakeThreadID(eid.getThreadID())) {
// it's a putAll
seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(real_tid);
if (seo != null && seo.getSequenceId() >= seqId) {
if (logger.isDebugEnabled()) {
logger.debug("got a duplicate putAll entry with eventId {}. Other operation with same thread id and bigger seqno {} has happened. Ignoring the entry", eid, seo.getSequenceId());
}
// bug #41289: send ack to servers that send old events
seo.setAckSend(false);
return true;
} else {
// save the seqno for real thread id into a putAllSequenceId
this.threadIdToSequenceId.remove(real_tid);
this.threadIdToSequenceId.put(real_tid, seo == null ? new SequenceIdAndExpirationObject(-1, seqId) : new SequenceIdAndExpirationObject(seo.getSequenceId(), seqId));
// save seqno for tid
// here tid!=real_tid, for fake tid, putAllSeqno should be 0
this.threadIdToSequenceId.remove(tid);
this.threadIdToSequenceId.put(tid, new SequenceIdAndExpirationObject(seqId, -1));
}
} else {
// non-putAll operation:
// check putAllSeqno for real thread id
// if request's seqno is smaller, reject
// otherwise, update the seqno for tid
seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(real_tid);
if (seo != null && seo.getPutAllSequenceId() >= seqId) {
if (logger.isDebugEnabled()) {
logger.debug("got a duplicate non-putAll entry with eventId {}. One putAll operation with same real thread id and bigger seqno {} has happened. Ignoring the entry", eid, seo.getPutAllSequenceId());
}
// bug #41289: send ack to servers that send old events
seo.setAckSend(false);
return true;
} else {
// here tid==real_tid
this.threadIdToSequenceId.remove(tid);
this.threadIdToSequenceId.put(tid, seo == null ? new SequenceIdAndExpirationObject(seqId, -1) : new SequenceIdAndExpirationObject(seqId, seo.getPutAllSequenceId()));
}
}
}
}
return false;
}
use of org.apache.geode.internal.cache.ha.ThreadIdentifier in project geode by apache.
the class CacheClientNotifier method processDispatchedMessage.
/**
* Adds or updates entry in the dispatched message map when client sends an ack.
*
* @return success
*/
public boolean processDispatchedMessage(ClientProxyMembershipID proxyId, EventID eid) {
boolean success = false;
CacheClientProxy proxy = getClientProxy(proxyId);
if (proxy != null) {
HARegionQueue harq = proxy.getHARegionQueue();
harq.addDispatchedMessage(new ThreadIdentifier(eid.getMembershipID(), eid.getThreadID()), eid.getSequenceID());
success = true;
}
return success;
}
use of org.apache.geode.internal.cache.ha.ThreadIdentifier in project geode by apache.
the class EventTracker method recordEvent.
/** record the event's threadid/sequenceid to prevent replay */
public void recordEvent(InternalCacheEvent event) {
EventID eventID = event.getEventId();
if (ignoreEvent(event, eventID)) {
// not tracked
return;
}
LocalRegion lr = (LocalRegion) event.getRegion();
ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(), eventID.getThreadID());
VersionTag tag = null;
if (lr.getServerProxy() == null) /* && event.hasClientOrigin() */
{
// clients do not need to
// store version tags for
// replayed events
tag = event.getVersionTag();
RegionVersionVector v = ((LocalRegion) event.getRegion()).getVersionVector();
// bug #46453 - make sure ID references are canonical before storing
if (v != null && tag != null) {
tag.setMemberID(v.getCanonicalId(tag.getMemberID()));
if (tag.getPreviousMemberID() != null) {
tag.setPreviousMemberID(v.getCanonicalId(tag.getPreviousMemberID()));
}
}
}
EventSeqnoHolder newEvh = new EventSeqnoHolder(eventID.getSequenceID(), tag);
if (logger.isTraceEnabled()) {
logger.trace("region event tracker recording {}", event);
}
recordSeqno(membershipID, newEvh);
// recordedBulkOpVersionTags
if (lr.getConcurrencyChecksEnabled() && (event.getOperation().isPutAll() || event.getOperation().isRemoveAll()) && lr.getServerProxy() == null) {
recordBulkOpEvent(event, membershipID);
}
}
use of org.apache.geode.internal.cache.ha.ThreadIdentifier in project geode by apache.
the class EventTracker method syncBulkOp.
/**
* A routine to provide synchronization running based on <memberShipID, threadID> of the
* requesting client
*
* @param r - a Runnable to wrap the processing of the bulk op
* @param eventID - the base event ID of the bulk op
*
* @since GemFire 5.7
*/
public void syncBulkOp(Runnable r, EventID eventID) {
Assert.assertTrue(eventID != null);
ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(), eventID.getThreadID());
Object opSyncObj = null;
do {
opSyncObj = recordedBulkOps.putIfAbsent(membershipID, new Object());
if (opSyncObj == null) {
opSyncObj = recordedBulkOps.get(membershipID);
}
} while (opSyncObj == null);
synchronized (opSyncObj) {
try {
recordBulkOpStart(membershipID, eventID);
// Perform the bulk op
r.run();
} finally {
recordedBulkOps.remove(membershipID);
}
}
}
use of org.apache.geode.internal.cache.ha.ThreadIdentifier in project geode by apache.
the class EventTracker method hasSeenEvent.
public boolean hasSeenEvent(EventID eventID, InternalCacheEvent tagHolder) {
ThreadIdentifier membershipID = new ThreadIdentifier(eventID.getMembershipID(), eventID.getThreadID());
// if (membershipID == null || eventID == null) {
// return false;
// }
EventSeqnoHolder evh = recordedEvents.get(membershipID);
if (evh == null) {
return false;
}
synchronized (evh) {
if (evh.removed || evh.lastSeqno < eventID.getSequenceID()) {
return false;
}
// during normal operation during bucket region initialization
if (logger.isTraceEnabled(LogMarker.DISTRIBUTION_BRIDGE_SERVER)) {
logger.trace(LogMarker.DISTRIBUTION_BRIDGE_SERVER, "Cache encountered replay of event with ID {}. Highest recorded for this source is {}", eventID, evh.lastSeqno);
}
// bug #44956 - recover version tag for duplicate event
if (evh.lastSeqno == eventID.getSequenceID() && tagHolder != null && evh.versionTag != null) {
((EntryEventImpl) tagHolder).setVersionTag(evh.versionTag);
}
return true;
}
// synchronized
}
Aggregations