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

com.payneteasy.grpc.longpolling.client.LongPollingClientStreamTap Maven / Gradle / Ivy

There is a newer version: 1.0-9
Show newest version
package com.payneteasy.grpc.longpolling.client;

import com.payneteasy.grpc.longpolling.client.http.HttpClientDelayedInit;
import com.payneteasy.grpc.longpolling.client.http.HttpClientDownloading;
import com.payneteasy.grpc.longpolling.client.http.HttpClientExecutor;
import com.payneteasy.grpc.longpolling.client.http.HttpClientTapping;
import com.payneteasy.grpc.longpolling.client.util.ServerEndPoint;
import com.payneteasy.grpc.longpolling.common.SingleMessageProducer;
import com.payneteasy.grpc.longpolling.common.SlotSender;
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.internal.ClientStreamListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.payneteasy.grpc.longpolling.client.http.HttpClientDownloading.EMPTY_INPUT;

/**
 * Send one request then waiting for responses
 *
 * Sequences:
 * 1. setCompressor(identity)
 * 2. setFullStreamDecompression(false)
 * 3. setDecompressorRegistry([gzip], [gzip, identity])
 * 4. start(io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl@41975bb9)
 * 5. writeMessage(1)
 * 6. request(io.grpc.protobuf.lite.ProtoInputStream@4a465447)
 * 7. halfClose()
 */
public class LongPollingClientStreamTap extends AbstractClientStream {

    private static final Logger LOG = LoggerFactory.getLogger(LongPollingClientStreamTap.class);

    private volatile ClientStreamListener listener;
    private volatile State                state;

    private enum State {
        SENDING_TAP
        , SENDING_DOWN
    }

    private final SlotSender slotSender;
    private final HttpClientDelayedInit             tapping;
    private final HttpClientDelayedInit             downloading;

    public LongPollingClientStreamTap(ExecutorService aExecutor, ServerEndPoint aEndpoint, AtomicBoolean aTransportActive) {
        state = State.SENDING_TAP;
        slotSender = new SlotSender<>(LOG, aMessage -> listener.messagesAvailable(aMessage));

        downloading = new HttpClientDelayedInit(aListener ->
                new HttpClientExecutor(aExecutor, new HttpClientDownloading(aEndpoint, aTransportActive, slotSender, listener))
        );

        HttpClientTapping.IOnCompleteAction onCompleteAction = aMessage -> {
            if(aMessage.isEmpty())  {
                downloading.sendMessage(EMPTY_INPUT);
            } else {
                for (InputStream inputStream : aMessage.getInputs()) {
                    slotSender.onSendMessage(SingleMessageProducer.readFully(getClass(), inputStream));
                    if(slotSender.hasSlots()) {
                        downloading.sendMessage(EMPTY_INPUT);
                    }
                }
            }
        };

        tapping = new HttpClientDelayedInit(aListener ->
                new HttpClientExecutor(aExecutor, new HttpClientTapping(aListener, aEndpoint, onCompleteAction))
        );

    }

    @Override
    public void cancel(Status aReason) {
        LOG.trace("cancel({})", aReason);
        tapping.cancelStream(aReason);
        downloading.cancelStream(aReason);
        listener.closed(aReason, new Metadata());
    }

    @Override
    public void start(ClientStreamListener aListener) {
        LOG.trace("start({})", aListener);
        listener = aListener;
        tapping.initialiseDelegate(aListener);
        downloading.initialiseDelegate(aListener);
    }

    @Override
    public void request(int aCount) {
        LOG.trace("request({})", aCount);
        slotSender.onRequest(aCount);
        if(state == State.SENDING_DOWN) {
            LOG.debug("State is {}, getting new messages from server ...", state);
            downloading.sendMessage(EMPTY_INPUT);
        } else {
            LOG.debug("State is {}. Waiting for tap response ...", state);
            state = State.SENDING_DOWN;
        }
    }

    @Override
    public void writeMessage(InputStream aMessage) {
        LOG.trace("writeMessage({})", aMessage);
        tapping.sendMessage(aMessage);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy