private void removeExpiredBulkOperations(EventTracker tracker, long now, long expirationTime) { for (Iterator<Map.Entry<ThreadIdentifier, BulkOperationHolder>> entryIterator = tracker.getRecordedBulkOpVersionTags().entrySet().iterator(); entryIterator.hasNext();) { Map.Entry<ThreadIdentifier, BulkOperationHolder> entry = entryIterator.next(); BulkOperationHolder evh = entry.getValue(); if (evh.expire(now, expirationTime)) { if (traceEnabled) { logger.trace("{} sweeper: removing bulkOp {}", tracker.getName(), entry.getKey()); } entryIterator.remove(); } } } }
/** * record the event's sequenceId in Region's event state to prevent replay. */ @Override public void recordEvent(InternalCacheEvent event) { getEventTracker().recordEvent(event); }
/** * tries to find the version tag for a replayed client event * * @return the version tag, if known. Null if not */ public VersionTag findVersionTagForClientBulkOp(EventID eventId) { return getEventTracker().findVersionTagForBulkOp(eventId); }
private void removeExpiredSequenceTracker(EventTracker tracker, long now, long expirationTime) { for (Iterator<Map.Entry<ThreadIdentifier, EventSequenceNumberHolder>> entryIterator = tracker.getRecordedEvents().entrySet().iterator(); entryIterator.hasNext();) { Map.Entry<ThreadIdentifier, EventSequenceNumberHolder> entry = entryIterator.next(); EventSequenceNumberHolder evh = entry.getValue(); if (evh.expire(now, expirationTime)) { if (traceEnabled) { logger.trace("{} sweeper: removing {}", tracker.getName(), entry.getKey()); } entryIterator.remove(); } } }
@Override protected DistributedRegion createAndDefineRegion(boolean isConcurrencyChecksEnabled, RegionAttributes ra, InternalRegionArguments ira, GemFireCacheImpl cache) { BucketRegion br = new BucketRegion("testRegion", ra, null, cache, ira); // it is necessary to set the event tracker to initialized, since initialize() in not being // called on the instantiated region br.getEventTracker().setInitialized(); // since br is a real bucket region object, we need to tell mockito to monitor it br = spy(br); // doNothing().when(dm).addMembershipListener(any()); doNothing().when(br).distributeUpdateOperation(any(), anyLong()); doNothing().when(br).distributeDestroyOperation(any()); doNothing().when(br).distributeInvalidateOperation(any()); doNothing().when(br).distributeUpdateEntryVersionOperation(any()); doNothing().when(br).checkForPrimary(); doNothing().when(br).handleWANEvent(any()); doReturn(false).when(br).needWriteLock(any()); return br; }
private void markEventAsDuplicate(EntryEventImpl event) { event.setPossibleDuplicate(true); if (getConcurrencyChecksEnabled() && event.getVersionTag() == null) { if (event.isBulkOpInProgress()) { event.setVersionTag(getEventTracker().findVersionTagForBulkOp(event.getEventId())); } else { event.setVersionTag(getEventTracker().findVersionTagForSequence(event.getEventId())); } } }
@Test public void retriedBulkOpGetsSavedVersionTag() { DistributedRegion region = prepare(true, true); DistributedMember member = mock(DistributedMember.class); ClientProxyMembershipID memberId = mock(ClientProxyMembershipID.class); byte[] memId = {1, 2, 3}; long threadId = 1; long retrySeqId = 1; ThreadIdentifier tid = new ThreadIdentifier(memId, threadId); EventID retryEventID = new EventID(memId, threadId, retrySeqId); boolean skipCallbacks = true; int size = 2; recordPutAllEvents(region, memId, threadId, skipCallbacks, member, memberId, size); EventTracker eventTracker = region.getEventTracker(); ConcurrentMap<ThreadIdentifier, BulkOperationHolder> map = eventTracker.getRecordedBulkOpVersionTags(); BulkOperationHolder holder = map.get(tid); EntryEventImpl retryEvent = EntryEventImpl.create(region, Operation.PUTALL_CREATE, "key1", "value1", null, false, member, !skipCallbacks, retryEventID); retryEvent.setContext(memberId); retryEvent.setPutAllOperation(mock(DistributedPutAllOperation.class)); region.hasSeenEvent(retryEvent); assertTrue(retryEvent.getVersionTag().equals(holder.getEntryVersionTags().get(retryEventID))); }
@Override public void invokeTXCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event, final boolean callDispatchListenerEvent) { if (logger.isDebugEnabled()) { logger.debug("BR.invokeTXCallbacks for event {}", event); } // bucket events may make it to this point even though the bucket is still // initializing. We can't block while initializing or a GII state flush // may hang, so we avoid notifying the bucket if (this.isInitialized()) { boolean callThem = callDispatchListenerEvent; if (event.isPossibleDuplicate() && getEventTracker().isInitialImageProvider(event.getDistributedMember())) { callThem = false; } super.invokeTXCallbacks(eventType, event, callThem); } @Released final EntryEventImpl prevent = createEventForPR(event); try { this.partitionedRegion.invokeTXCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false); } finally { prevent.release(); } }
/** * has the Region's event state seen this event? * * @return true if the Region's event state has seen the event */ @Override public boolean hasSeenEvent(EntryEventImpl event) { return getEventTracker().hasSeenEvent(event); }
/** * retrieve a deep copy of the Region's event state. This is used for getInitialImage. The result * is installed in the receiver of the image. */ public Map<? extends DataSerializable, ? extends DataSerializable> getEventState() { return getEventTracker().getState(); }
/** * tries to find the version tag for a event * * @return the version tag, if known. Null if not */ @Override public VersionTag findVersionTagForEvent(EventID eventId) { return getEventTracker().findVersionTagForSequence(eventId); }
@Override public void run2() { long now = System.currentTimeMillis(); long expirationTime = now - lifetimeInMillis; synchronized (trackers) { for (EventTracker tracker : trackers) { if (traceEnabled) { logger.trace("{} sweeper: starting", tracker.getName()); } removeExpiredSequenceTracker(tracker, now, expirationTime); removeExpiredBulkOperations(tracker, now, expirationTime); if (traceEnabled) { logger.trace("{} sweeper: done", tracker.getName()); } } } }
public GatewaySenderEventImpl addEvent(Object key) { this.bucketRegionQueue.getEventTracker().setInitialized(); this.bucketRegionQueue.entries.disableLruUpdateCallback(); GatewaySenderEventImpl event = mock(GatewaySenderEventImpl.class); this.bucketRegionQueue.entries.initialImagePut(key, 0, event, false, false, null, null, false); this.bucketRegionQueue.entries.enableLruUpdateCallback(); return event; }
@Override public void invokePutCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event, final boolean callDispatchListenerEvent, boolean notifyGateways) { if (logger.isTraceEnabled()) { logger.trace("invoking put callbacks on bucket for event {}", event); } // bucket events may make it to this point even though the bucket is still // initializing. We can't block while initializing or a GII state flush // may hang, so we avoid notifying the bucket if (this.isInitialized()) { boolean callThem = callDispatchListenerEvent; if (callThem && event.isPossibleDuplicate() && this.getEventTracker().isInitialImageProvider(event.getDistributedMember())) { callThem = false; } super.invokePutCallbacks(eventType, event, callThem, notifyGateways); } @Released final EntryEventImpl prevent = createEventForPR(event); try { this.partitionedRegion.invokePutCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false, false); } finally { prevent.release(); } }
/** * has the Region's event state seen this event? Most checks should use the method that takes an * Event, not an ID, but with transactions we do not have an event at the time the check needs to * be made. Consequently, this method may cause events to be recorded that would otherwise be * ignored. * * @param eventID the identifier of the event * @return true if the Region's event state has seen the event */ @Override public boolean hasSeenEvent(EventID eventID) { return getEventTracker().hasSeenEvent(eventID); }
((LocalRegion) this.newRegion).getEventTracker().setInitialized(); return; ((LocalRegion) this.newRegion).getEventTracker().setInitialized(); if (((LocalRegion) this.newRegion).isUsedForPartitionedRegionBucket()) { if (logger.isDebugEnabled()) {
protected void recordPutAllEvents(DistributedRegion region, byte[] memId, long threadId, boolean skipCallbacks, DistributedMember member, ClientProxyMembershipID memberId, int size) { EntryEventImpl[] events = new EntryEventImpl[size]; EventTracker eventTracker = region.getEventTracker(); for (int i = 0; i < size; i++) { events[i] = EntryEventImpl.create(region, Operation.PUTALL_CREATE, "key" + i, "value" + i, null, false, member, !skipCallbacks, new EventID(memId, threadId, i + 1)); events[i].setContext(memberId); events[i].setVersionTag(mock(VersionTag.class)); eventTracker.recordEvent(events[i]); } }
@Override public void invokeDestroyCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event, final boolean callDispatchListenerEvent, boolean notifyGateways) { // bucket events may make it to this point even though the bucket is still // initializing. We can't block while initializing or a GII state flush // may hang, so we avoid notifying the bucket if (this.isInitialized()) { boolean callThem = callDispatchListenerEvent; if (event.isPossibleDuplicate() && this.getEventTracker().isInitialImageProvider(event.getDistributedMember())) { callThem = false; } super.invokeDestroyCallbacks(eventType, event, callThem, notifyGateways); } @Released final EntryEventImpl prevent = createEventForPR(event); try { this.partitionedRegion.invokeDestroyCallbacks(eventType, prevent, this.partitionedRegion.isInitialized() ? callDispatchListenerEvent : false, false); } finally { prevent.release(); } }
@Override public boolean hasSeenEvent(EntryEventImpl event) { boolean isDuplicate = false; isDuplicate = getEventTracker().hasSeenEvent(event); if (isDuplicate) { markEventAsDuplicate(event); } else { // bug #48205 - a retried PR operation may already have a version assigned to it // in another VM if (event.isPossibleDuplicate() && event.getRegion().getConcurrencyChecksEnabled() && event.getVersionTag() == null && event.getEventId() != null) { boolean isBulkOp = event.getOperation().isPutAll() || event.getOperation().isRemoveAll(); VersionTag tag = FindVersionTagOperation.findVersionTag(event.getRegion(), event.getEventId(), isBulkOp); event.setVersionTag(tag); } } return isDuplicate; }
getEventTracker().setInitialized();