Search in sources :

Example 1 with PushStream

use of org.osgi.util.pushstream.PushStream in project aries by apache.

the class AbstractPushStreamImpl method window.

@Override
public <R> PushStream<R> window(Supplier<Duration> time, IntSupplier maxEvents, Executor ex, BiFunction<Long, Collection<T>, R> f) {
    AtomicLong timestamp = new AtomicLong();
    AtomicLong counter = new AtomicLong();
    Object lock = new Object();
    AtomicReference<Queue<T>> queueRef = new AtomicReference<Queue<T>>(null);
    // This code is declared as a separate block to avoid any confusion
    // about which instance's methods and variables are in scope
    Consumer<AbstractPushStreamImpl<R>> begin = p -> {
        synchronized (lock) {
            timestamp.lazySet(System.nanoTime());
            long count = counter.get();
            scheduler.schedule(getWindowTask(p, f, time, maxEvents, lock, count, queueRef, timestamp, counter, ex), time.get().toNanos(), NANOSECONDS);
        }
        queueRef.set(getQueueForInternalBuffering(maxEvents.getAsInt()));
    };
    @SuppressWarnings("resource") AbstractPushStreamImpl<R> eventStream = new IntermediatePushStreamImpl<R>(psp, ex, scheduler, this) {

        @Override
        protected void beginning() {
            begin.accept(this);
        }
    };
    AtomicBoolean endPending = new AtomicBoolean(false);
    updateNext((event) -> {
        try {
            if (eventStream.closed.get() == CLOSED) {
                return ABORT;
            }
            Queue<T> queue;
            if (!event.isTerminal()) {
                long elapsed;
                long newCount;
                synchronized (lock) {
                    for (; ; ) {
                        queue = queueRef.get();
                        if (queue == null) {
                            if (endPending.get()) {
                                return ABORT;
                            } else {
                                continue;
                            }
                        } else if (queue.offer(event.getData())) {
                            return CONTINUE;
                        } else {
                            queueRef.lazySet(null);
                            break;
                        }
                    }
                    long now = System.nanoTime();
                    elapsed = now - timestamp.get();
                    timestamp.lazySet(now);
                    newCount = counter.get() + 1;
                    counter.lazySet(newCount);
                    // This is a non-blocking call, and must happen in the
                    // synchronized block to avoid re=ordering the executor
                    // enqueue with a subsequent incoming close operation
                    aggregateAndForward(f, eventStream, event, queue, ex, elapsed);
                }
                // These must happen outside the synchronized block as we
                // call out to user code
                queueRef.set(getQueueForInternalBuffering(maxEvents.getAsInt()));
                scheduler.schedule(getWindowTask(eventStream, f, time, maxEvents, lock, newCount, queueRef, timestamp, counter, ex), time.get().toNanos(), NANOSECONDS);
                return CONTINUE;
            } else {
                long elapsed;
                synchronized (lock) {
                    queue = queueRef.get();
                    queueRef.lazySet(null);
                    endPending.set(true);
                    long now = System.nanoTime();
                    elapsed = now - timestamp.get();
                    counter.lazySet(counter.get() + 1);
                }
                Collection<T> collected = queue == null ? emptyList() : queue;
                ex.execute(() -> {
                    try {
                        eventStream.handleEvent(PushEvent.data(f.apply(Long.valueOf(NANOSECONDS.toMillis(elapsed)), collected)));
                    } catch (Exception e) {
                        close(PushEvent.error(e));
                    }
                });
            }
            ex.execute(() -> eventStream.handleEvent(event.nodata()));
            return ABORT;
        } catch (Exception e) {
            close(PushEvent.error(e));
            return ABORT;
        }
    });
    return eventStream;
}
Also used : Arrays(java.util.Arrays) BiFunction(java.util.function.BiFunction) AbstractQueue(java.util.AbstractQueue) Deferred(org.osgi.util.promise.Deferred) EventType(org.osgi.util.pushstream.PushEvent.EventType) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Collector(java.util.stream.Collector) PushStreamBuilder(org.osgi.util.pushstream.PushStreamBuilder) Collections.emptyList(java.util.Collections.emptyList) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) Collectors(java.util.stream.Collectors) BinaryOperator(java.util.function.BinaryOperator) Promise(org.osgi.util.promise.Promise) PushStreamProvider(org.osgi.util.pushstream.PushStreamProvider) List(java.util.List) Optional(java.util.Optional) Queue(java.util.Queue) ConcurrentModificationException(java.util.ConcurrentModificationException) PushEvent(org.osgi.util.pushstream.PushEvent) LongAdder(java.util.concurrent.atomic.LongAdder) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PushStream(org.osgi.util.pushstream.PushStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) PushEventSource(org.osgi.util.pushstream.PushEventSource) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) IntSupplier(java.util.function.IntSupplier) IntFunction(java.util.function.IntFunction) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Executor(java.util.concurrent.Executor) Semaphore(java.util.concurrent.Semaphore) State(org.apache.aries.pushstream.AbstractPushStreamImpl.State) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) PushEventConsumer(org.osgi.util.pushstream.PushEventConsumer) Comparator(java.util.Comparator) Collections(java.util.Collections) AtomicReference(java.util.concurrent.atomic.AtomicReference) ConcurrentModificationException(java.util.ConcurrentModificationException) NoSuchElementException(java.util.NoSuchElementException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) AbstractQueue(java.util.AbstractQueue) BlockingQueue(java.util.concurrent.BlockingQueue) Queue(java.util.Queue)

Example 2 with PushStream

use of org.osgi.util.pushstream.PushStream in project aries by apache.

the class AbstractPushStreamImpl method merge.

@Override
public PushStream<T> merge(PushEventSource<? extends T> source) {
    AbstractPushStreamImpl<T> eventStream = new IntermediatePushStreamImpl<>(psp, defaultExecutor, scheduler, this);
    AtomicInteger count = new AtomicInteger(2);
    PushEventConsumer<T> consumer = event -> {
        try {
            if (!event.isTerminal()) {
                return eventStream.handleEvent(event);
            }
            if (count.decrementAndGet() == 0) {
                eventStream.handleEvent(event.nodata());
                return ABORT;
            }
            return CONTINUE;
        } catch (Exception e) {
            PushEvent<T> error = PushEvent.error(e);
            close(error);
            eventStream.close(event.nodata());
            return ABORT;
        }
    };
    updateNext(consumer);
    AutoCloseable second;
    try {
        second = source.open((PushEvent<? extends T> event) -> {
            return consumer.accept(event);
        });
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException("Unable to merge events as the event source could not be opened.", e);
    }
    return eventStream.onClose(() -> {
        try {
            second.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }).map(Function.identity());
}
Also used : Arrays(java.util.Arrays) BiFunction(java.util.function.BiFunction) AbstractQueue(java.util.AbstractQueue) Deferred(org.osgi.util.promise.Deferred) EventType(org.osgi.util.pushstream.PushEvent.EventType) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Collector(java.util.stream.Collector) PushStreamBuilder(org.osgi.util.pushstream.PushStreamBuilder) Collections.emptyList(java.util.Collections.emptyList) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) Collectors(java.util.stream.Collectors) BinaryOperator(java.util.function.BinaryOperator) Promise(org.osgi.util.promise.Promise) PushStreamProvider(org.osgi.util.pushstream.PushStreamProvider) List(java.util.List) Optional(java.util.Optional) Queue(java.util.Queue) ConcurrentModificationException(java.util.ConcurrentModificationException) PushEvent(org.osgi.util.pushstream.PushEvent) LongAdder(java.util.concurrent.atomic.LongAdder) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PushStream(org.osgi.util.pushstream.PushStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) PushEventSource(org.osgi.util.pushstream.PushEventSource) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) IntSupplier(java.util.function.IntSupplier) IntFunction(java.util.function.IntFunction) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Executor(java.util.concurrent.Executor) Semaphore(java.util.concurrent.Semaphore) State(org.apache.aries.pushstream.AbstractPushStreamImpl.State) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) PushEventConsumer(org.osgi.util.pushstream.PushEventConsumer) Comparator(java.util.Comparator) Collections(java.util.Collections) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentModificationException(java.util.ConcurrentModificationException) NoSuchElementException(java.util.NoSuchElementException)

Example 3 with PushStream

use of org.osgi.util.pushstream.PushStream in project aries by apache.

the class AbstractPushStreamImpl method merge.

@Override
public PushStream<T> merge(PushStream<? extends T> source) {
    AbstractPushStreamImpl<T> eventStream = new IntermediatePushStreamImpl<>(psp, defaultExecutor, scheduler, this);
    AtomicInteger count = new AtomicInteger(2);
    PushEventConsumer<T> consumer = event -> {
        try {
            if (!event.isTerminal()) {
                return eventStream.handleEvent(event);
            }
            if (count.decrementAndGet() == 0) {
                eventStream.handleEvent(event.nodata());
                return ABORT;
            }
            return CONTINUE;
        } catch (Exception e) {
            PushEvent<T> error = PushEvent.error(e);
            close(error);
            eventStream.close(event.nodata());
            return ABORT;
        }
    };
    updateNext(consumer);
    try {
        source.forEachEvent(event -> {
            return consumer.accept(event);
        }).then(p -> {
            count.decrementAndGet();
            consumer.accept(PushEvent.close());
            return null;
        }, p -> {
            count.decrementAndGet();
            consumer.accept(PushEvent.error((Exception) p.getFailure()));
        });
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new IllegalStateException("Unable to merge events as the event source could not be opened.", e);
    }
    return eventStream.onClose(() -> {
        try {
            source.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }).map(Function.identity());
}
Also used : Arrays(java.util.Arrays) BiFunction(java.util.function.BiFunction) AbstractQueue(java.util.AbstractQueue) Deferred(org.osgi.util.promise.Deferred) EventType(org.osgi.util.pushstream.PushEvent.EventType) AtomicReferenceArray(java.util.concurrent.atomic.AtomicReferenceArray) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) Collector(java.util.stream.Collector) PushStreamBuilder(org.osgi.util.pushstream.PushStreamBuilder) Collections.emptyList(java.util.Collections.emptyList) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) Collectors(java.util.stream.Collectors) BinaryOperator(java.util.function.BinaryOperator) Promise(org.osgi.util.promise.Promise) PushStreamProvider(org.osgi.util.pushstream.PushStreamProvider) List(java.util.List) Optional(java.util.Optional) Queue(java.util.Queue) ConcurrentModificationException(java.util.ConcurrentModificationException) PushEvent(org.osgi.util.pushstream.PushEvent) LongAdder(java.util.concurrent.atomic.LongAdder) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PushStream(org.osgi.util.pushstream.PushStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) PushEventSource(org.osgi.util.pushstream.PushEventSource) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) IntSupplier(java.util.function.IntSupplier) IntFunction(java.util.function.IntFunction) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Executor(java.util.concurrent.Executor) Semaphore(java.util.concurrent.Semaphore) State(org.apache.aries.pushstream.AbstractPushStreamImpl.State) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) PushEventConsumer(org.osgi.util.pushstream.PushEventConsumer) Comparator(java.util.Comparator) Collections(java.util.Collections) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentModificationException(java.util.ConcurrentModificationException) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

Duration (java.time.Duration)3 AbstractQueue (java.util.AbstractQueue)3 ArrayList (java.util.ArrayList)3 Arrays (java.util.Arrays)3 Collection (java.util.Collection)3 Collections (java.util.Collections)3 Collections.emptyList (java.util.Collections.emptyList)3 Comparator (java.util.Comparator)3 ConcurrentModificationException (java.util.ConcurrentModificationException)3 Iterator (java.util.Iterator)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 NoSuchElementException (java.util.NoSuchElementException)3 Optional (java.util.Optional)3 Queue (java.util.Queue)3 Set (java.util.Set)3 BlockingQueue (java.util.concurrent.BlockingQueue)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 Executor (java.util.concurrent.Executor)3 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)3