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

com.google.cloud.firestore.SilenceableBidiStream Maven / Gradle / Ivy

There is a newer version: 3.29.1
Show newest version
/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.cloud.firestore;

import com.google.api.gax.rpc.BidiStreamObserver;
import com.google.api.gax.rpc.ClientStream;
import com.google.api.gax.rpc.StreamController;
import java.util.function.Function;
import java.util.logging.Logger;

/**
 * Conditionally pass through callbacks to wrapped `BidiStreamObserver`.
 *
 * 

Due to the asynchronous nature of a stream, there can be a delay between closing a stream and * the upstream no longer sending responses. Receiving callbacks after closing upstream can have * undesirable consequences. * *

The underlying `ClientStream` can be called through the `SilenceableBidiStream`. Methods such * as `send()` and `closeSend()` are exposed. * *

The `SilenceableBidiStream` wraps a `BidiStreamObserver`. This is helpful for situations where * the observer should be detached from a stream. Instead of calling the `closeSend()` method, the * `closeSendAndSilence()` method will silence the stream by preventing further callbacks including * `onError` and `onComplete`. * *

If silenced, the observer could be safely attached to a new stream. This is useful for error * handling where upstream must be stopped, but a new stream can continue to service the observer. * In these cases, the old stream cannot be allowed to send more responses, and especially cannot be * allowed to send `onError` or `onComplete` since that would signal the downstream that the stream * is finished. */ final class SilenceableBidiStream implements BidiStreamObserver { private final ClientStream stream; private final BidiStreamObserver delegate; private boolean silence = false; private static final Logger LOGGER = Logger.getLogger(Watch.class.getName()); SilenceableBidiStream( BidiStreamObserver responseObserverT, Function, ClientStream> streamSupplier) { this.delegate = responseObserverT; stream = streamSupplier.apply(this); } public boolean isSilenced() { return silence; } public void send(RequestT request) { LOGGER.info(stream.toString()); stream.send(request); } public void closeSend() { LOGGER.info(stream::toString); stream.closeSend(); } public void closeSendAndSilence() { LOGGER.info(stream::toString); silence = true; stream.closeSend(); } @Override public void onReady(ClientStream stream) { if (silence) { LOGGER.info(() -> String.format("Silenced: %s", stream)); } else { delegate.onReady(stream); } } @Override public void onStart(StreamController controller) { if (silence) { LOGGER.info(() -> String.format("Silenced: %s", stream)); } else { delegate.onStart(controller); } } @Override public void onResponse(ResponseT response) { if (silence) { LOGGER.info(() -> String.format("Silenced: %s", stream)); } else { delegate.onResponse(response); } } @Override public void onError(Throwable t) { if (silence) { LOGGER.info(() -> String.format("Silenced: %s", stream)); } else { delegate.onError(t); } } @Override public void onComplete() { if (silence) { LOGGER.info(() -> String.format("Silenced: %s", stream)); } else { delegate.onComplete(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy