-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Needed
Summary
Support retrying a KMS in-place.
This is expected to simplify driver implementations that fan out KMS requests in parallel (so far, only Node) and reduce time between retries.
Background & Motivation
Quoting integrating.md:
Note, the driver MAY fan out KMS requests in parallel. More KMS requests may be added when processing responses to retry.
This poses an implementation difficulty for drivers that want to run KMS requests in parallel. In Node, a proposed implementation (in pseudo-code) batches requests:
while (true) { let requests = [] for (let request = mongocrypt_ctx_kms_next(); request != null; request = mongocrypt_ctx_kms_next()) { requests.push(request); } if (request.length === 0) break; execute_requests(requests); // Blocks until all requests complete. }
As a result, retries are unable to start until the slowest request in the batch returns. Drivers are expected to sleep for mongocrypt_kms_ctx_usleep between retries, but this implementation may wait longer.
mongocrypt_ctx_next_kms_ctx may return NULL (to signal no more immediate requests), then later return non-NULL if retries are needed. In test code this looks like:
mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); ASSERT_OK(kms_ctx, ctx); // Expect no more immediate KMS requests. ASSERT(!mongocrypt_ctx_next_kms_ctx(ctx)); // Feed a retryable HTTP error. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt")), kms_ctx); // Expect KMS request is returned again for a retry. kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); ASSERT_OK(kms_ctx, ctx); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
This ticket proposes adding API to permit an in-place retry, to avoid the need to iterate with mongocrypt_ctx_next_kms_ctx for retry attempts:
mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); ASSERT_OK(kms_ctx, ctx); // Expect no more immediate KMS requests. ASSERT(!mongocrypt_ctx_next_kms_ctx(ctx)); // Feed a retryable HTTP error. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt")), kms_ctx); // Expect KMS request can be retried in-place. ASSERT(mongocrypt_kms_ctx_reset_and_retry(kms_ctx)); // Proposed API. // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
Caveats
This change may further complicate the protocol, resulting in two ways to support retry.
- is related to
-
MONGOCRYPT-599 Retry KMS requests on transient errors
-
- Closed
-
- split to
-
CSHARP-5476 Support retrying a KMS in-place
-
- Backlog
-
-
JAVA-5772 Support retrying a KMS in-place
-
- Backlog
-
-
NODE-6687 Support retrying a KMS in-place
-
- Backlog
-
-
PYTHON-5065 Support retrying a KMS in-place
-
- Backlog
-