use of org.apache.jackrabbit.oak.spi.commit.BackgroundObserver in project jackrabbit-oak by apache.
the class BundlingConfigHandler method registerObserver.
private void registerObserver(Observable observable, Executor executor) {
backgroundObserver = new BackgroundObserver(this, executor, 5);
observerRegistration = observable.addObserver(backgroundObserver);
}
use of org.apache.jackrabbit.oak.spi.commit.BackgroundObserver in project jackrabbit-oak by apache.
the class NodeStateSolrServersObserverService method activate.
@Activate
protected void activate(ComponentContext componentContext) throws Exception {
boolean enabled = PropertiesUtil.toBoolean(componentContext.getProperties().get(ENABLED), false);
if (enabled) {
BundleContext bundleContext = componentContext.getBundleContext();
Whiteboard whiteboard = new OsgiWhiteboard(bundleContext);
executor = new WhiteboardExecutor();
executor.start(whiteboard);
backgroundObserver = new BackgroundObserver(nodeStateSolrServersObserver, executor, 5);
regs.add(bundleContext.registerService(Observer.class.getName(), backgroundObserver, null));
}
}
use of org.apache.jackrabbit.oak.spi.commit.BackgroundObserver in project jackrabbit-oak by apache.
the class LuceneIndexProviderService method registerLocalIndexObserver.
private void registerLocalIndexObserver(BundleContext bundleContext, IndexTracker tracker, Map<String, ?> config) {
if (!hybridIndex) {
log.info("Hybrid indexing feature disabled");
return;
}
int queueSize = PropertiesUtil.toInteger(config.get(PROP_HYBRID_QUEUE_SIZE), PROP_HYBRID_QUEUE_SIZE_DEFAULT);
documentQueue = new DocumentQueue(queueSize, tracker, getExecutorService(), statisticsProvider);
LocalIndexObserver localIndexObserver = new LocalIndexObserver(documentQueue, statisticsProvider);
regs.add(bundleContext.registerService(Observer.class.getName(), localIndexObserver, null));
int observerQueueSize = 1000;
int builderMaxSize = 5000;
regs.add(bundleContext.registerService(JournalPropertyService.class.getName(), new LuceneJournalPropertyService(builderMaxSize), null));
ExternalObserverBuilder builder = new ExternalObserverBuilder(documentQueue, tracker, statisticsProvider, getExecutorService(), observerQueueSize);
log.info("Configured JournalPropertyBuilder with max size {} and backed by BackgroundObserver " + "with queue size {}", builderMaxSize, observerQueueSize);
Observer observer = builder.build();
externalIndexObserver = builder.getBackgroundObserver();
regs.add(bundleContext.registerService(Observer.class.getName(), observer, null));
oakRegs.add(registerMBean(whiteboard, BackgroundObserverMBean.class, externalIndexObserver.getMBean(), BackgroundObserverMBean.TYPE, "LuceneExternalIndexObserver queue stats"));
log.info("Hybrid indexing enabled for configured indexes with queue size of {}", queueSize);
}
use of org.apache.jackrabbit.oak.spi.commit.BackgroundObserver in project jackrabbit-oak by apache.
the class SecondaryStoreCacheService method registerObserver.
//~----------------------------------------------------< internal >
private void registerObserver(Observer observer, Map<String, Object> config) {
boolean enableAsyncObserver = toBoolean(config.get(PROP_ASYNC_OBSERVER), PROP_ASYNC_OBSERVER_DEFAULT);
int queueSize = toInteger(config.get(PROP_OBSERVER_QUEUE_SIZE), PROP_OBSERVER_QUEUE_SIZE_DEFAULT);
if (enableAsyncObserver) {
BackgroundObserver bgObserver = new BackgroundObserver(observer, executor, queueSize);
oakRegs.add(registerMBean(whiteboard, BackgroundObserverMBean.class, bgObserver.getMBean(), BackgroundObserverMBean.TYPE, "Secondary NodeStore observer stats"));
observer = bgObserver;
log.info("Configuring the observer for secondary NodeStore as " + "Background Observer with queue size {}", queueSize);
}
//Ensure that our observer comes first in processing
Hashtable<String, Object> props = new Hashtable<>();
props.put(Constants.SERVICE_RANKING, 10000);
regs.add(bundleContext.registerService(Observer.class.getName(), observer, props));
}
use of org.apache.jackrabbit.oak.spi.commit.BackgroundObserver in project jackrabbit-oak by apache.
the class ChangeProcessor method createObserver.
private FilteringObserver createObserver(final WhiteboardExecutor executor) {
FilteringDispatcher fd = new FilteringDispatcher(this);
BackgroundObserver bo = new BackgroundObserver(fd, executor, queueLength) {
private volatile long delay;
private volatile boolean blocking;
private long lastQueueFullWarnTimestamp = -1;
@Override
protected void added(int newQueueSize) {
queueSizeChanged(newQueueSize);
}
@Override
protected void removed(int newQueueSize, long created) {
queueSizeChanged(newQueueSize);
}
private void queueSizeChanged(int newQueueSize) {
maxQueueLengthRecorder.recordValue(newQueueSize);
tracker.recordQueueLength(newQueueSize);
if (newQueueSize >= queueLength) {
if (commitRateLimiter != null) {
if (!blocking) {
logQueueFullWarning("Revision queue is full. Further commits will be blocked.");
}
commitRateLimiter.blockCommits();
} else if (!blocking) {
logQueueFullWarning("Revision queue is full. Further revisions will be compacted.");
}
blocking = true;
} else {
double fillRatio = (double) newQueueSize / queueLength;
if (fillRatio > DELAY_THRESHOLD) {
if (commitRateLimiter != null) {
if (delay == 0) {
LOG.warn("Revision queue is becoming full. Further commits will be delayed.");
}
// Linear backoff proportional to the number of items exceeding
// DELAY_THRESHOLD. Offset by 1 to trigger the log message in the
// else branch once the queue falls below DELAY_THRESHOLD again.
int newDelay = 1 + (int) ((fillRatio - DELAY_THRESHOLD) / (1 - DELAY_THRESHOLD) * MAX_DELAY);
if (newDelay > delay) {
delay = newDelay;
commitRateLimiter.setDelay(delay);
}
}
} else {
if (commitRateLimiter != null) {
if (delay > 0) {
LOG.debug("Revision queue becoming empty. Unblocking commits");
commitRateLimiter.setDelay(0);
delay = 0;
}
if (blocking) {
LOG.debug("Revision queue becoming empty. Stop delaying commits.");
commitRateLimiter.unblockCommits();
blocking = false;
}
} else {
blocking = false;
}
}
}
}
private void logQueueFullWarning(String message) {
long currTime = clock.getTime();
if (lastQueueFullWarnTimestamp + QUEUE_FULL_WARN_INTERVAL < currTime) {
LOG.warn("{} Suppressing further such cases for {} minutes.", message, TimeUnit.MILLISECONDS.toMinutes(QUEUE_FULL_WARN_INTERVAL));
lastQueueFullWarnTimestamp = currTime;
} else {
LOG.debug(message);
}
}
@Override
public String toString() {
return "Prefiltering BackgroundObserver for " + ChangeProcessor.this;
}
};
return new FilteringObserver(bo, new Filter() {
@Override
public boolean excludes(NodeState root, CommitInfo info) {
final FilterResult filterResult = evalPrefilter(root, info, getChangeSet(info));
switch(filterResult) {
case PREFILTERING_SKIPPED:
{
prefilterSkipCount++;
return false;
}
case EXCLUDE:
{
prefilterExcludeCount++;
return true;
}
case INCLUDE:
{
prefilterIncludeCount++;
return false;
}
default:
{
LOG.info("isExcluded: unknown/unsupported filter result: " + filterResult);
prefilterSkipCount++;
return false;
}
}
}
});
}
Aggregations