com.kolibrifx.plovercrest.server.internal.protocol.ThreadedSubscriberEntryWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plovercrest-server Show documentation
Show all versions of plovercrest-server Show documentation
Plovercrest server library.
The newest version!
/*
* Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
*/
package com.kolibrifx.plovercrest.server.internal.protocol;
import java.util.Collection;
import org.apache.log4j.Logger;
import com.kolibrifx.common.Disposable;
import com.kolibrifx.common.dispatcher.Dispatcher;
import com.kolibrifx.common.dispatcher.DispatcherQueue;
import com.kolibrifx.common.dispatcher.ThreadedDispatcher;
public class ThreadedSubscriberEntryWriter implements Disposable {
private static final Logger log = Logger.getLogger(ThreadedSubscriberEntryWriter.class);
private final SubscriberWriteHandler handler;
interface SubscriberWriteHandler {
void writeEntryCollection(SubscriberEntryCollection c);
void writeStandaloneEvent(StandaloneSubscriberEvent event);
}
private final Dispatcher dispatcher = new ThreadedDispatcher("TableSubscriptionHandler");
private final DispatcherQueue queue = new DispatcherQueue(dispatcher) {
private boolean writeIfNeeded(final SubscriberEntryCollection c) {
if (!c.getEntriesByTableIndex().isEmpty()) {
handler.writeEntryCollection(c);
return true;
}
return false;
}
@Override
protected void processChunk(final Collection elements) {
SubscriberEntryCollection c = new SubscriberEntryCollection();
for (final SubscriberEvent e : elements) {
if (e instanceof SubscriberEntry) {
final SubscriberEntry entry = (SubscriberEntry) e;
final SubscriberEntry lastEntry = c.getLastEntry(entry.subscriptionId);
if (lastEntry != null && !SubscriberEntry.areSuccessiveEntries(lastEntry, entry)) {
// this will happen if the subscriber has been rewinded
if (log.isTraceEnabled()) {
log.trace("Last entry index " + lastEntry.entryIndex + " vs " + entry.entryIndex
+ " -- flush needed");
}
writeIfNeeded(c);
c = new SubscriberEntryCollection();
}
c.add(entry);
} else if (e instanceof StandaloneSubscriberEvent) {
if (writeIfNeeded(c)) {
c = new SubscriberEntryCollection();
}
handler.writeStandaloneEvent((StandaloneSubscriberEvent) e);
} else {
log.error("Unknown event type " + e.getClass().getName());
}
}
writeIfNeeded(c);
}
};
public ThreadedSubscriberEntryWriter(final SubscriberWriteHandler handler) {
this.handler = handler;
}
public void put(final SubscriberEvent event) {
try {
queue.put(event);
} catch (final InterruptedException e) {
log.error("Unexpected interrupt", e);
}
}
@Override
public void close() {
dispatcher.close();
}
}