use of com.linkedin.databus.core.InvalidEventException in project databus by linkedin.
the class DbusEventCorrupter method makeWritable.
/**
* Converts an event (readable or otherwise) to writable for testing. EEEEEEEVIL!
*
* Note that all DbusEvents are fundamentally just little windows into some
* DbusEventBuffer; the various event classes differ only in the methods they
* expose. So pulling the buffer and offset variables out of a readable and
* using them to construct a writable is effectively the same as typecasting
* the readable to writable (i.e., "const_cast<DbusEventInternalWritable>()",
* so to speak).
*
* @param event DbusEvent to be abused
*/
public static DbusEventInternalWritable makeWritable(DbusEvent event) throws InvalidEventException {
// version is always in the first byte // TODO: add DbusEvent version() accessor? seems like good idea...
byte version = event.getRawBytes().get(0);
ByteBuffer buf;
int pos;
try {
Field reflectedBuf = DbusEventSerializable.class.getDeclaredField("_buf");
Field reflectedPosition = DbusEventSerializable.class.getDeclaredField("_position");
reflectedBuf.setAccessible(true);
reflectedPosition.setAccessible(true);
buf = (ByteBuffer) reflectedBuf.get(event);
pos = reflectedPosition.getInt(event);
} catch (Exception e) {
throw new InvalidEventException(e);
}
return (version == 0) ? new DbusEventV1(buf, pos) : new DbusEventV2(buf, pos);
}
use of com.linkedin.databus.core.InvalidEventException in project databus by linkedin.
the class RelayPullThread method doReadDataEvents.
protected void doReadDataEvents(ConnectionState curState) {
boolean debugEnabled = _log.isDebugEnabled();
boolean enqueueMessage = true;
try {
ChunkedBodyReadableByteChannel readChannel = curState.getReadChannel();
Checkpoint cp = curState.getCheckpoint();
curState.setRelayFellOff(false);
String remoteErrorName = RemoteExceptionHandler.getExceptionName(readChannel);
Throwable knownRemoteError = _remoteExceptionHandler.getException(readChannel);
if (null != knownRemoteError && knownRemoteError instanceof ScnNotFoundException) {
if (toTearConnAfterHandlingResponse()) {
tearConnectionAndEnqueuePickServer();
enqueueMessage = false;
} else {
curState.setRelayFellOff(true);
if (_retriesOnFallOff.getRemainingRetriesNum() > 0) {
_log.error("Got SCNNotFoundException. Retry (" + _retriesOnFallOff.getRetriesNum() + ") out of " + _retriesOnFallOff.getConfig().getMaxRetryNum());
curState.switchToPickServer();
} else {
enqueueMessage = onRelayFellOff(curState, cp, knownRemoteError);
}
}
} else if (null != remoteErrorName) {
if (toTearConnAfterHandlingResponse()) {
tearConnectionAndEnqueuePickServer();
enqueueMessage = false;
} else {
//remote processing error
_log.error("read events error: " + RemoteExceptionHandler.getExceptionMessage(readChannel));
curState.switchToStreamResponseError();
}
} else {
/*DispatcherState dispatchState = curState.getDispatcherState();
dispatchState.switchToDispatchEvents();
_dispatcherThread.addNewStateBlocking(dispatchState);*/
if (debugEnabled)
_log.debug("Sending events to buffer");
DbusEventsStatisticsCollector connCollector = _sourcesConn.getInboundEventsStatsCollector();
if (curState.isSCNRegress()) {
_log.info("SCN Regress requested !! Sending a SCN Regress Message to dispatcher. Curr Ckpt :" + curState.getCheckpoint());
DbusEvent regressEvent = getEventFactory().createSCNRegressEvent(new SCNRegressMessage(curState.getCheckpoint()));
writeEventToRelayDispatcher(curState, regressEvent, "SCN Regress Event from ckpt :" + curState.getCheckpoint());
curState.setSCNRegress(false);
}
UnifiedClientStats unifiedClientStats = _sourcesConn.getUnifiedClientStats();
if (unifiedClientStats != null) {
// failsafe: we're definitely not bootstrapping here
unifiedClientStats.setBootstrappingState(false);
sendHeartbeat(unifiedClientStats);
}
int eventsNum = curState.getDataEventsBuffer().readEvents(readChannel, curState.getListeners(), connCollector);
boolean resetConnection = false;
if (eventsNum > 0) {
_timeSinceEventsSec = System.currentTimeMillis();
cp.checkPoint();
} else {
// check how long it has been since we got some events
if (_remoteExceptionHandler.getPendingEventSize(readChannel) > curState.getDataEventsBuffer().getMaxReadBufferCapacity()) {
// The relay had a pending event that we can never accommodate. This is fatal error.
String err = "ReadBuffer max capacity(" + curState.getDataEventsBuffer().getMaxReadBufferCapacity() + ") is less than event size(" + _remoteExceptionHandler.getPendingEventSize(readChannel) + "). Increase databus.client.connectionDefaults.eventBuffer.maxEventSize and restart.";
_log.fatal(err);
enqueueMessage(LifecycleMessage.createSuspendOnErroMessage(new PendingEventTooLargeException(err)));
return;
} else {
if (_noEventsConnectionResetTimeSec > 0) {
// unless the feature is disabled (<=0)
resetConnection = (System.currentTimeMillis() - _timeSinceEventsSec) / 1000 > _noEventsConnectionResetTimeSec;
if (resetConnection) {
_timeSinceEventsSec = System.currentTimeMillis();
_log.warn("about to reset connection to relay " + curState.getServerInetAddress() + ", because there were no events for " + _noEventsConnectionResetTimeSec + "secs");
}
}
}
}
if (debugEnabled)
_log.debug("Events read: " + eventsNum);
// if it has been too long since we got non-empty responses - the relay may be stuck, try to reconnect
if (toTearConnAfterHandlingResponse() || resetConnection) {
tearConnectionAndEnqueuePickServer();
enqueueMessage = false;
} else {
curState.switchToStreamResponseDone();
resetServerRetries();
}
}
if (enqueueMessage)
enqueueMessage(curState);
} catch (InterruptedException ie) {
_log.warn("interrupted", ie);
curState.switchToStreamResponseError();
enqueueMessage(curState);
} catch (InvalidEventException e) {
_log.error("error reading events from server:" + e, e);
curState.switchToStreamResponseError();
enqueueMessage(curState);
} catch (RuntimeException e) {
_log.error("runtime error reading events from server: " + e, e);
curState.switchToStreamResponseError();
enqueueMessage(curState);
}
}
use of com.linkedin.databus.core.InvalidEventException in project databus by linkedin.
the class RelayPullThread method doPickRelay.
protected void doPickRelay(ConnectionState curState) {
int serversNum = _servers.size();
if (0 == serversNum) {
enqueueMessage(LifecycleMessage.createSuspendOnErroMessage(new DatabusException("No relays specified")));
return;
}
Random rng = new Random();
DatabusRelayConnection relayConn = null;
ServerInfo serverInfo = null;
int retriesLeft;
BackoffTimer originalCounter = _status.getRetriesCounter();
if (curState.isRelayFellOff())
_status.setRetriesCounter(_retriesOnFallOff);
while (null == relayConn && (retriesLeft = _status.getRetriesLeft()) >= 0 && !checkForShutdownRequest()) {
_log.info("picking a relay; retries left:" + retriesLeft + ", Backoff Timer :" + _status.getRetriesCounter() + ", Are we retrying because of SCNNotFoundException : " + curState.isRelayFellOff());
backoffOnPullError();
_curServerIdx = (_curServerIdx < 0) ? rng.nextInt(serversNum) : (_curServerIdx + 1) % serversNum;
Iterator<ServerInfo> setIter = _servers.iterator();
for (int i = 0; i <= _curServerIdx; ++i) serverInfo = setIter.next();
try {
relayConn = _sourcesConn.getRelayConnFactory().createRelayConnection(serverInfo, this, _remoteExceptionHandler);
_log.info("picked a relay:" + serverInfo.toSimpleString());
} catch (Exception e) {
_log.error("Unable to get connection to relay:" + serverInfo.toSimpleString(), e);
}
}
_status.setRetriesCounter(originalCounter);
if (!checkForShutdownRequest()) {
_curServer = serverInfo;
if (null == relayConn) {
if (_currentState.isRelayFellOff()) {
boolean enqueueMessage = false;
try {
enqueueMessage = onRelayFellOff(curState, curState.getCheckpoint(), new ScnNotFoundException("Retries on SCNNotFoundException exhausted !!"));
} catch (InterruptedException ie) {
_log.error("interrupted while processing onRelayFellOff", ie);
curState.switchToPickServer();
enqueueMessage(curState);
} catch (InvalidEventException e) {
_log.error("error trying to notify dispatcher of bootstrapping :" + e.getMessage(), e);
curState.switchToPickServer();
enqueueMessage(curState);
}
if (enqueueMessage)
enqueueMessage(curState);
} else {
// There are no retries left. Invoke an onError callback
try {
_log.info("Puller retries exhausted. Injecting an error event on dispatcher queue to invoke onError callback");
_remoteExceptionHandler.handleException(new PullerRetriesExhaustedException());
} catch (InterruptedException ie) {
_log.error("Interrupted while processing retries exhausted", ie);
} catch (InvalidEventException e) {
_log.error("Error trying to notify dispatcher of puller retries getting exhausted", e);
}
_log.error("Cannot find a relay");
}
} else {
DatabusRelayConnection oldRelayConn = curState.getRelayConnection();
if (null != oldRelayConn) {
resetConnectionAndSetFlag();
}
sendHeartbeat(_sourcesConn.getUnifiedClientStats());
_log.info("Relay Puller switching to request sources");
curState.switchToRequestSources(serverInfo, serverInfo.getAddress(), relayConn);
_lastOpenConnection = relayConn;
enqueueMessage(curState);
}
}
}
use of com.linkedin.databus.core.InvalidEventException in project databus by linkedin.
the class BootstrapPullThread method processBootstrapComplete.
/**
* Update and persist checkpoint at the end of bootstrap phase so that
* the online phase can continue from it.
* @param cp
* @throws IOException
*/
protected void processBootstrapComplete(Checkpoint cp, ConnectionState curState) throws IOException, DatabusException {
logBootstrapPhase(DbusClientMode.BOOTSTRAP_CATCHUP, cp.getBootstrapSnapshotSourceIndex(), cp.getBootstrapCatchupSourceIndex());
_log.info("Bootstrap got completed !! Checkpoint is :" + cp.toString());
/*
* DDS-989
* WindowSCN need not match the bootstrapTargetSCN always when we are catching up multiple sources.
* So set the windowSCN to be that of targetSCN as we are consistent as of targetSCN
*/
cp.setWindowScn(cp.getBootstrapTargetScn());
cp.setPrevScn(cp.getBootstrapTargetScn());
cp.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION);
// clear Bootstrap scns for future bootstraps
cp.resetBootstrap();
DbusEventBuffer eventBuffer = curState.getDataEventsBuffer();
try {
DbusEventInternalReadable cpEvent = getEventFactory().createCheckpointEvent(cp);
boolean success = eventBuffer.injectEvent(cpEvent);
if (!success) {
_log.error("Unable to write bootstrap phase marker");
} else {
//TODO need real partition for partitioned bootstrap
DbusEventInternalReadable eopEvent = curState.createEopEvent(cp, getEventFactory());
success = eventBuffer.injectEvent(eopEvent);
if (!success) {
_log.error("Unable to write bootstrap EOP marker");
}
}
} catch (InvalidEventException iee) {
_log.error("Unable to write bootstrap phase marker", iee);
}
unlockV3Bootstrap();
}
use of com.linkedin.databus.core.InvalidEventException in project databus by linkedin.
the class RemoteExceptionHandler method suspendConnectionOnError.
private void suspendConnectionOnError(Throwable exception) throws InvalidEventException, InterruptedException {
// suspend pull threads
_sourcesConn.getConnectionStatus().suspendOnError(exception);
// send an error event to dispatcher through dbusEventBuffer
DbusEventInternalReadable errorEvent = null;
if (exception instanceof BootstrapDatabaseTooOldException) {
errorEvent = _eventFactory.createErrorEvent(new DbusErrorEvent(exception, DbusEventInternalWritable.BOOTSTRAPTOOOLD_ERROR_SRCID));
} else if (exception instanceof PullerRetriesExhaustedException) {
errorEvent = _eventFactory.createErrorEvent(new DbusErrorEvent(exception, DbusEventInternalWritable.PULLER_RETRIES_EXPIRED));
} else {
throw new InvalidEventException("Got an unrecognizable exception ");
}
byte[] errorEventBytes = new byte[errorEvent.getRawBytes().limit()];
if (LOG.isDebugEnabled()) {
LOG.debug("error event size: " + errorEventBytes.length);
LOG.debug("error event:" + errorEvent.toString());
}
errorEvent.getRawBytes().get(errorEventBytes);
ByteArrayInputStream errIs = new ByteArrayInputStream(errorEventBytes);
ReadableByteChannel errRbc = Channels.newChannel(errIs);
boolean success = false;
int retryCounter = 0;
while (!success && retryCounter < 10) {
String errMsg = "Sending an internal system event to dispatcher. Retry count = " + retryCounter;
DbusPrettyLogUtils.logExceptionAtInfo(errMsg, exception, LOG);
success = _dbusEventBuffer.readEvents(errRbc) > 0 ? true : false;
if (!success) {
LOG.warn("Unable to send an internal system event to dispatcher. Will retry later " + retryCounter);
retryCounter++;
Thread.sleep(1000);
}
}
}
Aggregations