com.kolibrifx.plovercrest.server.internal.streams.UpdateLastValidTimestampViaStreams 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.streams;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import com.kolibrifx.common.Disposable;
import com.kolibrifx.plovercrest.client.PlovercrestTableNotFound;
import com.kolibrifx.plovercrest.client.internal.SubscriptionQuery;
import com.kolibrifx.plovercrest.client.internal.SubscriptionQuery.QueryKind;
import com.kolibrifx.plovercrest.server.internal.StreamObservers;
import com.kolibrifx.plovercrest.server.streams.Stream;
import com.kolibrifx.plovercrest.server.streams.StreamEngine;
import com.kolibrifx.plovercrest.server.streams.StreamObserver;
public class UpdateLastValidTimestampViaStreams implements Disposable {
private final StreamEngine streamEngine;
private final CopyOnWriteArrayList> streams = new CopyOnWriteArrayList<>();
private final StreamObservers observers;
private final AtomicLong lastValidTimestamp = new AtomicLong(-1);
private final StreamObserver streamObserver;
private final Collection disposables = Collections.synchronizedCollection(new ArrayList());
public UpdateLastValidTimestampViaStreams(final StreamEngine streamEngine) {
this.streamEngine = streamEngine;
this.observers = new StreamObservers(streamEngine);
streamObserver = new StreamObserver() {
@Override
public void onObserve(final long timestamp, final long index, final ByteBuffer element) {
tryUpdateLastValidTimestamp(timestamp - 1);
}
@Override
public void onObserveEnd(final long lastValidTimestamp, final long elementCount) {
}
@Override
public void onObserveFrozen() {
}
};
}
public void addStream(final String name) {
final Stream stream = streamEngine.openRaw(name);
if (stream == null) {
throw new PlovercrestTableNotFound("No such stream: " + name);
}
// make sure the stream is writable: if not, getWriter() should throw an exception
if (stream.getWriter() == null) {
throw new IllegalStateException();
}
streams.add(stream);
disposables.add(observers.subscribe(name,
new SubscriptionQuery(QueryKind.TIMESTAMP, stream.getLastTimestamp()),
streamObserver, ByteBuffer.class));
}
private void tryUpdateLastValidTimestamp(final long newValue) {
final long oldValue = lastValidTimestamp.get();
if (oldValue >= newValue) {
return;
}
if (!lastValidTimestamp.compareAndSet(oldValue, newValue)) {
return;
}
for (final Stream> stream : streams) {
if (stream.getLastValidTimestamp() < newValue) {
stream.getWriter().updateLastValidTimestamp(newValue);
}
}
}
@Override
public void close() {
synchronized (disposables) {
for (final Disposable d : disposables) {
d.close();
}
disposables.clear();
}
observers.close();
}
}