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

io.sphere.sdk.queries.ForAllSubscription Maven / Gradle / Ivy

package io.sphere.sdk.queries;

import io.sphere.sdk.client.QueueSphereClientDecorator;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.models.Base;
import io.sphere.sdk.models.Identifiable;
import io.sphere.sdk.utils.ListUtils;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ScheduledThreadPoolExecutor;

import static java.lang.String.format;

final class ForAllSubscription, C extends QueryDsl> extends Base implements Subscription {
    private static final long ELEMENTS_PER_QUERY = 20;
    private QueryDsl seedQuery;
    private SphereClient sphereClient;
    private Subscriber subscriber;

    private String lastId;
    private Queue queue = new LinkedList<>();
    private Queue elementsQueue = new LinkedList<>();
    private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);//kind of mailbox

    ForAllSubscription(final QueryDsl seedQuery, final SphereClient sphereClient, final Subscriber subscriber) {
        this.seedQuery = seedQuery.withSort(QuerySort.of("id asc")).withFetchTotal(false).withLimit(ELEMENTS_PER_QUERY);
        this.sphereClient = QueueSphereClientDecorator.of(sphereClient, 1, false);
        this.subscriber = subscriber;
    }

    @Override
    public void cancel() {
        if (subscriptionIsCanceled()) {
            noOp();
        } else {
            executor.shutdownNow();
            executor = null;
            subscriber = null;
            sphereClient.close();
            sphereClient = null;
            seedQuery = null;
            lastId = null;
        }
    }

    @Override
    public void request(final long n) {
        executor.execute(() -> {
            long remainingElements = n;
            boolean valueFound = true;
            while (valueFound && remainingElements > 0) {
                T value = elementsQueue.poll();
                valueFound = value != null;
                if (valueFound) {
                    subscriber.onNext(value);
                    remainingElements--;
                }
            }
            if (remainingElements > 0) {
                fetchNewElements();
                queue.add(remainingElements);
            }
        });
    }

    private void fetchNewElements() {
        final QueryPredicate idIsGreaterThanLastIdPredicate = QueryPredicate.of(format("id > \"%s\"", lastId));
        final Query query = lastId == null ? seedQuery : seedQuery.withPredicates(ListUtils.listOf(seedQuery.predicates(), idIsGreaterThanLastIdPredicate));
        sphereClient.execute(query).whenComplete((r, e) -> {
            executor.execute(() -> {
                final boolean success = e == null;
                if (success) {
                    final List results = r.getResults();
                    if (results.size() == 0) {
                        executor.execute(() -> {
                            subscriber.onComplete();
                            cancel();
                        });
                    } else {
                        executor.execute(() -> {
                            final T t = results.get(results.size() - 1);
                            lastId = t.getId();
                            elementsQueue.addAll(results);
                            queue.forEach(n -> request(n));
                            queue.clear();
                        });
                    }
                } else {
                    executor.execute(() -> {
                        subscriber.onError(e);
                        cancel();
                    });
                }
            });
        });
    }

    private boolean subscriptionIsCanceled() {
        return subscriber == null;
    }

    private void noOp() {

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy