All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kolibrifx.plovercrest.server.internal.streams.UpdateLastValidTimestampViaStreams Maven / Gradle / Ivy

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();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy