OutboundStreamListener.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.arrow.flight;
import org.apache.arrow.memory.ArrowBuf;
import org.apache.arrow.vector.VectorSchemaRoot;
import org.apache.arrow.vector.dictionary.DictionaryProvider;
import org.apache.arrow.vector.ipc.message.IpcOption;
/** An interface for writing data to a peer, client or server. */
public interface OutboundStreamListener {
/**
* A hint indicating whether the client is ready to receive data without excessive buffering.
*
* <p>Writers should poll this flag before sending data to respect backpressure from the client
* and avoid sending data faster than the client can handle. Ignoring this flag may mean that the
* server will start consuming excessive amounts of memory, as it may buffer messages in memory.
*/
boolean isReady();
/**
* Set a callback for when the listener is ready for new calls to putNext(), i.e. {@link
* #isReady()} has become true.
*
* <p>Note that this callback may only be called some time after {@link #isReady()} becomes true,
* and may never be called if all executor threads on the server are busy, or the RPC method body
* is implemented in a blocking fashion. Note that isReady() must still be checked after the
* callback is run as it may have been run spuriously.
*/
default void setOnReadyHandler(Runnable handler) {
throw new UnsupportedOperationException("Not yet implemented.");
}
/**
* Start sending data, using the schema of the given {@link VectorSchemaRoot}.
*
* <p>This method must be called before all others, except {@link #putMetadata(ArrowBuf)}.
*/
default void start(VectorSchemaRoot root) {
start(root, null, IpcOption.DEFAULT);
}
/**
* Start sending data, using the schema of the given {@link VectorSchemaRoot}.
*
* <p>This method must be called before all others, except {@link #putMetadata(ArrowBuf)}.
*/
default void start(VectorSchemaRoot root, DictionaryProvider dictionaries) {
start(root, dictionaries, IpcOption.DEFAULT);
}
/**
* Start sending data, using the schema of the given {@link VectorSchemaRoot}.
*
* <p>This method must be called before all others, except {@link #putMetadata(ArrowBuf)}.
*/
void start(VectorSchemaRoot root, DictionaryProvider dictionaries, IpcOption option);
/**
* Send the current contents of the associated {@link VectorSchemaRoot}.
*
* <p>This will not necessarily block until the message is actually sent; it may buffer messages
* in memory. Use {@link #isReady()} to check if there is backpressure and avoid excessive
* buffering.
*/
void putNext();
/**
* Send the current contents of the associated {@link VectorSchemaRoot} alongside
* application-defined metadata.
*
* @param metadata The metadata to send. Ownership of the buffer is transferred to the Flight
* implementation.
*/
void putNext(ArrowBuf metadata);
/**
* Send a pure metadata message without any associated data.
*
* <p>This may be called without starting the stream.
*/
void putMetadata(ArrowBuf metadata);
/**
* Indicate an error to the client. Terminates the stream; do not call {@link #completed()}
* afterwards.
*/
void error(Throwable ex);
/** Indicate that transmission is finished. */
void completed();
/**
* Toggle whether to use the zero-copy write optimization.
*
* <p>By default or when disabled, Arrow may copy data into a buffer for the underlying
* implementation to send. When enabled, Arrow will instead try to directly enqueue the Arrow
* buffer for sending. Not all implementations support this optimization, so even if enabled, you
* may not see a difference.
*
* <p>In this mode, buffers must not be reused after they are written with {@link #putNext()}. For
* example, you would have to call {@link VectorSchemaRoot#allocateNew()} after every call to
* {@link #putNext()}. Hence, this is not enabled by default.
*
* <p>The default value can be toggled globally by setting the JVM property
* arrow.flight.enable_zero_copy_write or the environment variable
* ARROW_FLIGHT_ENABLE_ZERO_COPY_WRITE.
*/
default void setUseZeroCopy(boolean enabled) {}
}