use of org.apache.geode.internal.cache.wan.AbstractGatewaySender.EventWrapper in project geode by apache.
the class SerialGatewaySenderEventProcessor method basicHandleSecondaryEvent.
private void basicHandleSecondaryEvent(final GatewaySenderEventImpl gatewayEvent) {
boolean freeGatewayEvent = true;
try {
GatewaySenderStats statistics = this.sender.getStatistics();
if (!getSender().getGatewayEventFilters().isEmpty()) {
try {
gatewayEvent.initialize();
} catch (Exception e) {
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewayImpl_EVENT_FAILED_TO_BE_INITIALIZED_0, gatewayEvent), e);
}
if (!sender.beforeEnqueue(gatewayEvent)) {
statistics.incEventsFiltered();
return;
}
}
Assert.assertHoldsLock(unprocessedEventsLock, true);
Assert.assertTrue(unprocessedEvents != null);
// @todo add an assertion that !getPrimary()
// now we can safely use the unprocessedEvents field
Long v = this.unprocessedTokens.remove(gatewayEvent.getEventId());
if (v == null) {
// first time for the event
if (logger.isTraceEnabled()) {
logger.trace("{}: fromSecondary event {}:{}->{} added from unprocessed events map", sender.getId(), gatewayEvent.getEventId(), gatewayEvent.getKey(), gatewayEvent.getValueAsString(true));
}
{
EventWrapper mapValue = new EventWrapper(gatewayEvent);
EventWrapper oldv = this.unprocessedEvents.put(gatewayEvent.getEventId(), mapValue);
if (oldv == null) {
freeGatewayEvent = false;
statistics.incUnprocessedEventsAddedBySecondary();
} else {
// put old one back in
this.unprocessedEvents.put(gatewayEvent.getEventId(), oldv);
// already added by secondary (i.e. hub)
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewayImpl_0_THE_UNPROCESSED_EVENTS_MAP_ALREADY_CONTAINED_AN_EVENT_FROM_THE_HUB_1_SO_IGNORING_NEW_EVENT_2, new Object[] { sender.getId(), v, gatewayEvent }));
}
}
} else {
// token already added by primary already removed
if (logger.isTraceEnabled()) {
logger.trace("{}: Secondary created event {}:{}->{} removed from unprocessed events map", sender.getId(), gatewayEvent.getEventId(), gatewayEvent.getKey(), gatewayEvent.getValueAsString(true));
}
statistics.incUnprocessedTokensRemovedBySecondary();
}
reapOld(statistics, false);
} finally {
if (freeGatewayEvent) {
gatewayEvent.release();
}
}
}
use of org.apache.geode.internal.cache.wan.AbstractGatewaySender.EventWrapper in project geode by apache.
the class SerialGatewaySenderEventProcessor method reapOld.
/**
* Call to check if a cleanup of tokens needs to be done
*/
private void reapOld(final GatewaySenderStats statistics, boolean forceEventReap) {
synchronized (this.unprocessedEventsLock) {
if (uncheckedCount > REAP_THRESHOLD) {
// only check every X events
uncheckedCount = 0;
long now = System.currentTimeMillis();
if (!forceEventReap && this.unprocessedTokens.size() > REAP_THRESHOLD) {
Iterator<Map.Entry<EventID, Long>> it = this.unprocessedTokens.entrySet().iterator();
int count = 0;
while (it.hasNext()) {
Map.Entry<EventID, Long> me = it.next();
long meValue = me.getValue().longValue();
if (meValue <= now) {
// @todo log fine level message here
// it has expired so remove it
it.remove();
count++;
} else {
// all done try again
break;
}
}
if (count > 0) {
// statistics.incUnprocessedTokensRemovedByTimeout(count);
}
}
if (forceEventReap || this.unprocessedEvents.size() > REAP_THRESHOLD) {
Iterator<Map.Entry<EventID, EventWrapper>> it = this.unprocessedEvents.entrySet().iterator();
int count = 0;
while (it.hasNext()) {
Map.Entry<EventID, EventWrapper> me = it.next();
EventWrapper ew = me.getValue();
if (ew.timeout <= now) {
// @todo log fine level message here
// it has expired so remove it
it.remove();
ew.event.release();
count++;
} else {
// all done try again
break;
}
}
if (count > 0) {
// statistics.incUnprocessedEventsRemovedByTimeout(count);
}
}
} else {
uncheckedCount++;
}
}
}
use of org.apache.geode.internal.cache.wan.AbstractGatewaySender.EventWrapper in project geode by apache.
the class SerialGatewaySenderEventProcessor method basicHandlePrimaryEvent.
protected void basicHandlePrimaryEvent(final GatewaySenderEventImpl gatewayEvent) {
if (this.sender.isPrimary()) {
// no need to do anything if we have become the primary
return;
}
GatewaySenderStats statistics = this.sender.getStatistics();
// Get the event from the map
synchronized (unprocessedEventsLock) {
if (this.unprocessedEvents == null)
return;
// now we can safely use the unprocessedEvents field
EventWrapper ew = this.unprocessedEvents.remove(gatewayEvent.getEventId());
if (ew == null) {
// first time for the event
if (logger.isTraceEnabled()) {
logger.trace("{}: fromPrimary event {} : {}->{} added to unprocessed token map", sender.getId(), gatewayEvent.getEventId(), gatewayEvent.getKey(), gatewayEvent.getValueAsString(true));
}
{
Long mapValue = Long.valueOf(System.currentTimeMillis() + AbstractGatewaySender.TOKEN_TIMEOUT);
Long oldv = this.unprocessedTokens.put(gatewayEvent.getEventId(), mapValue);
if (oldv == null) {
statistics.incUnprocessedTokensAddedByPrimary();
} else {
// its ok for oldv to be non-null
// this shouldn't happen anymore @todo add an assertion here
}
}
} else {
// removed (it already was above)
if (logger.isTraceEnabled()) {
logger.trace("{}: Primary create/update event {}:{}->{} remove from unprocessed events map", sender.getId(), gatewayEvent.getEventId(), gatewayEvent.getKey(), gatewayEvent.getValueAsString(true));
}
ew.event.release();
statistics.incUnprocessedEventsRemovedByPrimary();
}
reapOld(statistics, false);
}
}
use of org.apache.geode.internal.cache.wan.AbstractGatewaySender.EventWrapper in project geode by apache.
the class SerialGatewaySenderEventProcessor method handleFailover.
/**
* Handle failover. This method is called when a secondary <code>GatewaySender</code> becomes a
* primary <code>GatewaySender</code>.
*
* Once this secondary becomes the primary, it must:
* <ul>
* <li>Remove the queue's CacheListener
* <li>Process the map of unprocessed events (those it has seen but the previous primary had not
* yet processed before it crashed). These will include both queued and unqueued events. Remove
* from the queue any events that were already sent
* <li>Clear the unprocessed events map
* </ul>
*/
protected void handleFailover() {
/*
* We must hold this lock while we're processing these maps to prevent us from handling a
* secondary event while failover occurs. See enqueueEvent
*/
synchronized (this.unprocessedEventsLock) {
// Remove the queue's CacheListener
this.queue.removeCacheListener();
this.unprocessedTokens = null;
// Process the map of unprocessed events
logger.info(LocalizedMessage.create(LocalizedStrings.GatewayImpl_GATEWAY_FAILOVER_INITIATED_PROCESSING_0_UNPROCESSED_EVENTS, this.unprocessedEvents.size()));
GatewaySenderStats statistics = this.sender.getStatistics();
if (!this.unprocessedEvents.isEmpty()) {
// do a reap for bug 37603
// to get rid of timed out events
reapOld(statistics, true);
// now iterate over the region queue to figure out what unprocessed
// events are already in the queue
{
Iterator it = this.queue.getRegion().values().iterator();
while (it.hasNext() && !stopped()) {
Object o = it.next();
if (o != null && o instanceof GatewaySenderEventImpl) {
GatewaySenderEventImpl ge = (GatewaySenderEventImpl) o;
EventWrapper unprocessedEvent = this.unprocessedEvents.remove(ge.getEventId());
if (unprocessedEvent != null) {
unprocessedEvent.event.release();
if (this.unprocessedEvents.isEmpty()) {
break;
}
}
}
}
}
// now for every unprocessed event add it to the end of the queue
{
Iterator<Map.Entry<EventID, EventWrapper>> it = this.unprocessedEvents.entrySet().iterator();
while (it.hasNext()) {
if (stopped())
break;
Map.Entry<EventID, EventWrapper> me = it.next();
EventWrapper ew = me.getValue();
GatewaySenderEventImpl gatewayEvent = ew.event;
// Initialize each gateway event. This initializes the key,
// value
// and callback arg based on the EntryEvent.
// TODO:wan70, remove dependencies from old code
gatewayEvent.initialize();
// Verify that they GatewayEventCallbackArgument is initialized.
// If not, initialize it. It won't be initialized if a client to
// this GatewayHub VM was the creator of this event. This Gateway
// will be the first one to process it. If will be initialized if
// this event was sent to this Gateway from another GatewayHub
// (either directly or indirectly).
GatewaySenderEventCallbackArgument seca = gatewayEvent.getSenderCallbackArgument();
if (seca.getOriginatingDSId() == GatewaySender.DEFAULT_DISTRIBUTED_SYSTEM_ID) {
seca.setOriginatingDSId(sender.getMyDSId());
seca.initializeReceipientDSIds(Collections.singletonList(sender.getRemoteDSId()));
}
it.remove();
boolean queuedEvent = false;
try {
queuedEvent = queuePrimaryEvent(gatewayEvent);
} catch (IOException ex) {
if (!stopped()) {
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewayImpl_EVENT_DROPPED_DURING_FAILOVER_0, gatewayEvent), ex);
}
} catch (CacheException ex) {
if (!stopped()) {
logger.warn(LocalizedMessage.create(LocalizedStrings.GatewayImpl_EVENT_DROPPED_DURING_FAILOVER_0, gatewayEvent), ex);
}
} finally {
if (!queuedEvent) {
gatewayEvent.release();
}
}
}
}
// Clear the unprocessed events map
statistics.clearUnprocessedMaps();
}
// Iterate the entire queue and mark all events as possible
// duplicate
logger.info(LocalizedMessage.create(LocalizedStrings.GatewayImpl_0__MARKING__1__EVENTS_AS_POSSIBLE_DUPLICATES, new Object[] { getSender(), Integer.valueOf(this.queue.size()) }));
Iterator it = this.queue.getRegion().values().iterator();
while (it.hasNext() && !stopped()) {
Object o = it.next();
if (o != null && o instanceof GatewaySenderEventImpl) {
GatewaySenderEventImpl ge = (GatewaySenderEventImpl) o;
ge.setPossibleDuplicate(true);
}
}
releaseUnprocessedEvents();
}
// synchronized
}
use of org.apache.geode.internal.cache.wan.AbstractGatewaySender.EventWrapper in project geode by apache.
the class SerialGatewaySenderEventProcessor method basicHandlePrimaryDestroy.
/**
* Just remove the event from the unprocessed events map if it is present. This method added to
* fix bug 37603
*/
protected void basicHandlePrimaryDestroy(final GatewaySenderEventImpl gatewayEvent) {
if (this.sender.isPrimary()) {
// no need to do anything if we have become the primary
return;
}
GatewaySenderStats statistics = this.sender.getStatistics();
// Get the event from the map
synchronized (unprocessedEventsLock) {
if (this.unprocessedEvents == null)
return;
// now we can safely use the unprocessedEvents field
EventWrapper ew = this.unprocessedEvents.remove(gatewayEvent.getEventId());
if (ew != null) {
ew.event.release();
statistics.incUnprocessedEventsRemovedByPrimary();
}
}
}
Aggregations