diff --git a/docs/design/core/progress-listener/README.md b/docs/design/core/progress-listener/README.md new file mode 100644 index 000000000000..7cbd71a77111 --- /dev/null +++ b/docs/design/core/progress-listener/README.md @@ -0,0 +1,88 @@ +**Design:** New Feature, **Status:** [In Development](../../../README.md) + +# Project Tenets (unless you know better ones) + +1. Recording progress events should have minimal impact on the application performance. + +2. The supported progress event types should have minimum overlaps with existing execution interceptors. [To discuss] + +3. Progress events and publisher should be extensible. + +# Introduction + +This project provides Progress Listeners feature, which allows customers to track the progress of executions for streaming operations and execute callbacks +on different progress events. + +# Default Progress Event Types + +- Byte Counting Events + +```java + + /** + * Event of the content length to be sent in a request. + */ + REQUEST_CONTENT_LENGTH_EVENT, + /** + * Event of the content length received in a response. + */ + RESPONSE_CONTENT_LENGTH_EVENT, + + /** + * Used to indicate the number of bytes to be sent to the services. + */ + REQUEST_BYTE_TRANSFER_EVENT, + + /** + * Used to indicate the number of bytes received from services. + */ + RESPONSE_BYTE_TRANSFER_EVENT, + + ``` + +- Request/Response Events + +```java + + + //////////////////////////////////////// + // Byte counting progress events + //////////////////////////////////////// + /** + * Used to indicate the request body has been cancelled. + */ + REQUEST_BODY_CANCEL_EVENT, + + /** + * Used to indicate the request body is complete. + */ + REQUEST_BODY_COMPLETE_EVENT, + + /** + * Used to indicate the request has been reset. + */ + REQUEST_BODY_RESET_EVENT, + + RESPONSE_BODY_CANCEL_EVENT, + + RESPONSE_BODY_COMPLETE_EVENT, + + RESPONSE_BODY_RESET_EVENT + +``` + +# Configuration +```java + + ProgressEventListener eventListener = progressEvent -> { + System.out.println(progressEvent); + return CompletableFuture.completedFuture(null); + }; + + S3AsyncClient.builder() + .overrideConfiguration(b -> b.addProgressListener(eventListener)) + //.overrideConfiguration(b -> b.progressListeners(Collections.singletonList(eventListener))) + .build(); + + } +``` \ No newline at end of file diff --git a/docs/design/core/progress-listener/prototype.java b/docs/design/core/progress-listener/prototype.java new file mode 100644 index 000000000000..08b9f336da16 --- /dev/null +++ b/docs/design/core/progress-listener/prototype.java @@ -0,0 +1,154 @@ +package software.amazon.awssdk.core.progress; + +/** + * Listener interface to listen to the progress events. + * + * @see ProgressEvent the progress event + */ +@SdkPublicApi +@FunctionalInterface +public interface ProgressEventListener { + + /** + * Data notification sent by the {@link ProgressEventPublisher} when an event is available. + * + *

+ * It is recommended to process the events in a non-blocking way + * + * @param progressEvent the progress event + * @return the complete future + */ + CompletableFuture onProgressEvent(ProgressEvent progressEvent); +} + +/** + * interface to publish {@link ProgressEvent}s to {@link ProgressEventListener}s. + */ +@SdkPublicApi +@FunctionalInterface +public interface ProgressEventPublisher { + + /** + * Publish the progress events + * + * @param progressEvent the event to publish + * @return the future contains the results whether the publish is successful or not. + */ + CompletableFuture publishProgressEvent(ProgressEvent progressEvent); +} + +/** + * A progress event. Typically this is used to notify a chunk of bytes has been + * transferred. This can also used to notify other types of progress events such as a + * transfer starting, or failing. + * + * @see ProgressEventPublisher + * @see ProgressEventListener + */ +@SdkPublicApi +public final class ProgressEvent { + + private final ProgressEventType eventType; + private final ProgressEventData eventData; + + private ProgressEvent(ProgressEventType eventType, ProgressEventData eventData) { + this.eventType = eventType; + this.eventData = eventData; + } + + public ProgressEvent(ProgressEventType eventType) { + this(eventType, null); + } + + public static ProgressEvent create(ProgressEventType eventType) { + return new ProgressEvent(eventType); + } + + public static ProgressEvent create(ProgressEventType eventType, ProgressEventData eventData) { + return new ProgressEvent(eventType, eventData); + } + + /** + * @return the event type + */ + public ProgressEventType eventType() { + return eventType; + } + + /** + * @return the event data + */ + public Optional eventData() { + return Optional.ofNullable(eventData); + } +} + +/** + * The event data to be sent along within an {@link ProgressEvent}. + */ +@SdkPublicApi +public interface ProgressEventData { +} + +/** + * Progress Event type + */ +@SdkPublicApi +public interface ProgressEventType { +} + +/** + * Sdk default progress events. + */ +@SdkPublicApi +public enum SdkProgressEventType implements ProgressEventType { + + + //////////////////////////////////////// + // Byte counting progress events + //////////////////////////////////////// + + /** + * Event of the content length to be sent in a request. + */ + REQUEST_CONTENT_LENGTH_EVENT, + /** + * Event of the content length received in a response. + */ + RESPONSE_CONTENT_LENGTH_EVENT, + + /** + * Used to indicate the number of bytes to be sent to the services. + */ + REQUEST_BYTE_TRANSFER_EVENT, + + /** + * Used to indicate the number of bytes received from services. + */ + RESPONSE_BYTE_TRANSFER_EVENT, + + //////////////////////////////////////// + // Request/Response progress events + //////////////////////////////////////// + + /** + * Used to indicate the request body has been cancelled. + */ + REQUEST_BODY_CANCEL_EVENT, + + /** + * Used to indicate the request body is complete. + */ + REQUEST_BODY_COMPLETE_EVENT, + + /** + * Used to indicate the request has been reset. + */ + REQUEST_BODY_RESET_EVENT, + + RESPONSE_BODY_CANCEL_EVENT, + + RESPONSE_BODY_COMPLETE_EVENT, + + RESPONSE_BODY_RESET_EVENT +} \ No newline at end of file