Skip to content

Internal classes and RequestBatchManager Impelementation #5418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

joviegas
Copy link
Contributor

@joviegas joviegas commented Jul 23, 2024

RequestManager Implementation details

Overview

The RequestManager is responsible for managing and executing batched requests in an efficient manner. It utilizes various batch managers to handle different types of requests such as sending messages, deleting messages, changing message visibility, and handling generic request batches. The design ensures that requests are processed in an optimized and scalable way by leveraging concurrent processing and batching techniques.

Classes

1. SendMessageBatchManager

  • Purpose: Manages the batching and sending of messages to SQS.
  • Key Responsibilities:
    • Collects messages to be sent.
    • Batches messages into the appropriate size.
    • Sends the batched messages to SQS.
    • Handles responses and errors for the batched requests.

2. RequestBatchManager

  • Purpose: Manages generic request batching for various types of SQS operations.
  • Key Responsibilities:
    • Aggregates individual requests.
    • Creates batches of requests based on configuration.
    • Executes batched requests.
    • Provides mechanisms for retrying failed requests.

3. RequestBatchBuffer

  • Purpose: Buffers requests before they are batched and sent.
  • Key Responsibilities:
    • Temporarily stores requests.
    • Provides methods to retrieve and clear buffered requests.
    • Ensures thread-safe operations for request storage and retrieval.

4. IdentifiableMessage

  • Purpose: Represents a message with a unique identifier.
  • Key Responsibilities:
    • Stores message content and unique identifier.
    • Provides methods to access message details.

5. DeleteMessageBatchManager

  • Purpose: Manages the batching and deletion of messages from SQS.
  • Key Responsibilities:
    • Collects messages to be deleted.
    • Batches delete requests.
    • Sends batched delete requests to SQS.
    • Handles responses and errors for the delete requests.

6. DefaultSqsAsyncBatchManager

  • Purpose: Default implementation for managing asynchronous SQS batch operations.
  • Key Responsibilities:
    • Provides a default mechanism for handling various SQS batch operations asynchronously.
    • Ensures efficient processing of batch requests.

7. ChangeMessageVisibilityBatchManager

  • Purpose: Manages the batching and visibility timeout changes for SQS messages.
  • Key Responsibilities:
    • Collects visibility change requests.
    • Batches visibility change requests.
    • Sends batched requests to SQS.
    • Handles responses and errors for the visibility change requests.

8. BatchingMap

  • Purpose: Utility class for managing batching contexts and operations.
  • Key Responsibilities:
    • Stores and manages batch contexts.
    • Provides methods for adding and retrieving batches.
    • Ensures thread-safe access to batch contexts.

9. BatchingExecutionContext

  • Purpose: Execution context for batching operations.
  • Key Responsibilities:
    • Manages the lifecycle of batch executions.
    • Provides context-specific configurations and state management.

10. RequestBatchConfiguration

  • Purpose: Configuration class for request batching.
  • Key Responsibilities:
    • Stores configuration settings for batching operations.
    • Provides methods to access and modify configuration settings.

Key Design Considerations

  • Concurrency: The design ensures thread-safe operations using appropriate synchronization mechanisms.
  • Scalability: Batching of requests allows for efficient handling of a large number of requests.
  • Error Handling: Each batch manager includes mechanisms for handling and retrying failed requests.
  • Flexibility: The use of different batch managers allows for easy extension and customization for various types of SQS operations.

Conclusion

The RequestManager design leverages batching and asynchronous processing to efficiently manage and execute SQS requests. The modular design with specific batch managers for different request types ensures flexibility and scalability, making it suitable for high-throughput applications.

License

  • I confirm that this pull request can be released under the Apache 2 license

@joviegas joviegas requested a review from a team as a code owner July 23, 2024 17:22
@joviegas joviegas force-pushed the joviegas/batchManager-internalclaases branch from 2ae8af6 to d78d204 Compare July 24, 2024 22:19
@joviegas joviegas changed the title Internal classes and Interface for BatchManager Internal classes and RequestBatchManager Impelementation Jul 24, 2024
@joviegas joviegas force-pushed the joviegas/batchManager-internalclaases branch from d78d204 to 1a3b8e1 Compare July 24, 2024 22:33
Copy link
Contributor

@dagnir dagnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it seems like we're still carrying over some of complexity from the original feature that intended to support batching across multiple services. Since we know that this is all going to be SQS specific can we simplify this design further, knowing that we just need to support SQS?

import software.amazon.awssdk.utils.Either;

@SdkInternalApi
public final class SqsBatchFunctions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a strange pattern since these look like they're only used for DefaultSqsAsyncBatchManager. Any reason this isn't an abstract class instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had private constructor , anyways made it abstract now.

Do you want to make it abstract and make DefaultSqsAsyncBatchManager extend SqsBatchFunctions ?


// Flushes the buffer for the given batchKey and fills in the response map with the returned responses.
// Returns exception in completableFuture if batchingFunction.apply throws an exception.
private void flushBuffer(String batchKey, Map<String, BatchingExecutionContext<RequestT, ResponseT>> flushableRequests) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wouldn't it just return the response map instead of taking it as an argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep the track of individual requests that were send and update those requests with its corresponding response. While sending we create unique ids for messages and while receiving we map it back.
Note that flushBuffer is done asynchronously and we are not returning any values but updating the CompletableFutures of the responses from the map, I can explain you this offline .

@joviegas
Copy link
Contributor Author

joviegas commented Aug 1, 2024

Overall, it seems like we're still carrying over some of complexity from the original feature that intended to support batching across multiple services. Since we know that this is all going to be SQS specific can we simplify this design further, knowing that we just need to support SQS?

I removed the Generic Interface for BatchManager and will have sepaarte Batch Manager for Response and Request.
We still need the Generic for RequestBatch manger apis since we have 3 APIs in it , this complexity is still needed unless we decide we will break it out and do simple implementation as V1

Comment on lines 36 to 38
private final BatchAndSend<RequestT, BatchResponseT> batchFunction;
private final BatchResponseMapper<BatchResponseT, ResponseT> responseMapper;
private final BatchKeyMapper<RequestT> batchKeyMapper;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should just be protected abstract methods:

    protected abstract CompletableFuture<BatchResponseT> batchAndSend(List<IdentifiableMessage<RequestT>> identifiedRequests,
                                                                      String batchKey);

    protected abstract String getBatchKey(RequestT request);

    protected abstract List<Either<IdentifiableMessage<ResponseT>, IdentifiableMessage<Throwable>>> mapBatchResponse(BatchResponseT batchResponse);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 49 to 51
this.responseMapper = Validate.notNull(builder.responseMapper, "Null responseMapper");
this.batchKeyMapper = Validate.notNull(builder.batchKeyMapper, "Null batchKeyMapper");
this.scheduledExecutor = Validate.notNull(builder.scheduledExecutor, "Null scheduledExecutor");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't need these right? See comment above re: making these protected abstract methods

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeap , removed these

@@ -12,6 +12,7 @@
}
},

"enableGenerateCompiledEndpointRules": true
"enableGenerateCompiledEndpointRules": true,
"batchManagerSupported": true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be more generic now that batch managers could differ between services, e.g. where the actual FQCN, construct method, and argument are all specified? Maybe similar to the way the utilities() method is generated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are providing static method for BatchManager we cannot use the existing customizations also discussed in
#5321 (comment)

Copy link

sonarqubecloud bot commented Aug 6, 2024

@joviegas joviegas merged commit a04379b into feature/master/sqs-batch-manager Aug 6, 2024
12 of 16 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Sep 11, 2024
* Codegenerate BatchManager API under AsyncClient and Initail Interfaces for BatchManager (#5321)

* Codegenerate BatchManager API under AsyncClient and Add empty initial Batchmanager interfaces and Implementations

* Addressed review comments

* Added Internal classes required for BatchManager Implementation

* Revert "Added Internal classes required for BatchManager Implementation"

This reverts commit 318969b.

* Internal classes and RequestBatchManager Impelementation (#5418)

* Added Internal classes required for BatchManager Implementation

* Added Batch Send Implementation

* Handled review comments

* Handled review comments

* Handled review comments

* Made RequestBatchManager class a Abstract class

* Checkstyle issues

* Removed unused methods

* New lines removed

* Made public static to private state for sqsBatch functions

* Constants added

* Sonar cloud issues fixed

* commit to check why test on codebuild

* Increased Timeouts for get

* Added abstract methods

* Handled comments to remove Builders

* Handled comments to take care when batchmanager closed while pending requests

* Handled comments

* Checkstyle issue

* Added Consumer builders args for existing APIs of BatchManager (#5514)

* Receive Batch Manager Implementation (#5488)

* Add Recieve Buffer Queue And its related configuration

* Update ReceiveBatch  manager

* Recieve Batch Manager Implementation

* Receive Batch Manager Implemetation

* Handled review comments

* Checkstyle failure

* Flsky test case fixed

* Flaky test case fixed

* Hamdled review comments

* Handled comments

* Removed ReceiveMessageCompletableFuture

* SdkClosable implemented

* Added ReceiveMessageBatchManager class for completeness

* Checkstyle issues

* Null checks

* Handled comments from Zoe

* Updated the defaults to 50ms same as V1 after surface area review

* Revert "Updated the defaults to 50ms same as V1 after surface area review"

This reverts commit e7d2295.

* Bytes Based batching for SendMessageRequest Batching (#5540)

* Initial changes

* Initial changes 2

* Byte Based batching for SendMessage API

* Byte Based batching for SendMessage API

* Handled comments

* Checkstyle issue

* Add User Agent for Sqs Calls made using Automatic Batching Manager  (#5546)

* Add User Agent for Sqs Calls made using Automatic Batching Manager as hll/abm

* Review comments

* Update comments from  PR 5488 (#5550)

* Update comments of PR 5488

* Update comments from  PR 5488

* Handled surface area review comments (#5563)

* Initial version

* Intermediate changes

* Update after internal poll

* ResponseCOnfiguration construction updated

* RequestOverride configuration check added to Bypass batch manager

* Handled review comments

* Removed TODO since validations are handled in BatchPverrideConfiguration

* Fix issue where the Scheduled Timeout was incorrectly completing the futures with empty messages (#5571)

* Fix issue where the Scheduled Timeout was incorrectly completing the futures with empty messages

* Handled review comments

* Integ test for Automatic Request Batching (#5576)

* feat(sqs): add BatchManager for client-side request batching to Amazon SQS

The new BatchManager allows for simple request batching using client-side buffering, improving cost efficiency and reducing the number of requests sent to Amazon SQS. The client-side buffering supports up to 10 requests per batch and is supported by the SqsAsyncClient. Batched requests, along with receive message polling, help to increase throughput.

* Add check for scheduledExecutor such that it not null when creating SqsAsyncBatchManager (#5582)

* Add check for scheduledExecutor such that it not null when creating SqsAsyncBatchManager

* Update services/sqs/src/test/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManagerBuilderTest.java

Co-authored-by: David Ho <[email protected]>

* Update services/sqs/src/test/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManagerBuilderTest.java

Co-authored-by: David Ho <[email protected]>

* Update services/sqs/src/test/java/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManagerBuilderTest.java

Co-authored-by: David Ho <[email protected]>

---------

Co-authored-by: David Ho <[email protected]>

* Updating Timeouts in gets so that we dont wait infinitely

---------

Co-authored-by: David Ho <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants