From ccf196d7f40da485911a21c93daa9827524900e2 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Sat, 1 Nov 2025 00:31:40 +0100 Subject: [PATCH] libstore/s3: resolve completion status via the transfer status callback Completion status can be updated in two ways: - progress callback - transfer status update callback (esp. important in multipart transfers) It's guaranteed that one of the two will provide progress for our promise. This fixes #945. Change-Id: Iac9e92df34f82fbc1facae7a411ccabf1688da52 Signed-off-by: Raito Bezarius --- lix/libstore/s3-binary-cache-store.cc | 52 ++++++++++++++++++--------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/lix/libstore/s3-binary-cache-store.cc b/lix/libstore/s3-binary-cache-store.cc index 6f3d32dcf..adbaa3038 100644 --- a/lix/libstore/s3-binary-cache-store.cc +++ b/lix/libstore/s3-binary-cache-store.cc @@ -312,6 +312,28 @@ struct S3BinaryCacheStoreConfig final : BinaryCacheStoreConfig } }; +namespace { +struct TransferContext : Aws::Client::AsyncCallerContext +{ + FulfillerWrapper signal; + explicit TransferContext(kj::Own> signal) + : signal(std::move(signal)) + { + } +}; +} + +static void notifyIfTransferFinished(const std::shared_ptr & transferHandle) +{ + if (transferHandle->GetStatus() != TransferStatus::NOT_STARTED + && transferHandle->GetStatus() != TransferStatus::IN_PROGRESS) + { + auto context = + std::static_pointer_cast(transferHandle->GetContext()); + context->signal.fulfill(); + } +} + struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore { S3BinaryCacheStoreConfig config_; @@ -432,15 +454,6 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore static std::shared_ptr executor = std::make_shared(maxThreads); - struct TransferContext : Aws::Client::AsyncCallerContext - { - FulfillerWrapper signal; - explicit TransferContext(kj::Own> signal) - : signal(std::move(signal)) - { - } - }; - std::call_once(transferManagerCreated, [&]() { if (config().multipartUpload) { @@ -458,14 +471,19 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore transferHandle->GetBytesTransferred(), transferHandle->GetBytesTotalSize()); - if (transferHandle->GetStatus() != TransferStatus::NOT_STARTED - && transferHandle->GetStatus() != TransferStatus::IN_PROGRESS) - { - auto context = std::static_pointer_cast( - transferHandle->GetContext() - ); - context->signal.fulfill(); - } + notifyIfTransferFinished(transferHandle); + }; + + transferConfig.transferStatusUpdatedCallback = + [](const TransferManager * transferManager, + const std::shared_ptr & transferHandle) { + debug( + "transfer ('%s') status updated to '%s'", + transferHandle->GetKey(), + transferHandle->GetStatus() + ); + + notifyIfTransferFinished(transferHandle); }; transferManager = TransferManager::Create(transferConfig);