Skip to content

Commit

Permalink
tweak(resources/client): retry backoff for download failures
Browse files Browse the repository at this point in the history
This was requested at some point to better handle cases when resource
files are downloaded from an external file server, and for some reason a
download failure occurs.
  • Loading branch information
blattersturm committed Apr 21, 2023
1 parent a5cbb9b commit 9079223
Showing 1 changed file with 43 additions and 0 deletions.
Expand Up @@ -23,6 +23,7 @@
#include <VFSError.h>

#include <pplawait.h>
#include <agents.h>
#include <experimental/resumable>

#include <concurrent_queue.h>
Expand Down Expand Up @@ -380,6 +381,38 @@ void ResourceCacheDeviceV2::UnfetchEntry(const std::string& fileName)
}
}

static ConVar<int>* g_downloadBackoff;

// from https://learn.microsoft.com/en-us/cpp/parallel/concrt/how-to-create-a-task-that-completes-after-a-delay?view=msvc-170
concurrency::task<void> complete_after(unsigned int timeout)
{
using namespace concurrency;

// A task completion event that is set when a timer fires.
task_completion_event<void> tce;

// Create a non-repeating timer.
auto fire_once = std::make_shared<timer<int>>(timeout, 0, nullptr, false);
// Create a call object that sets the completion event after the timer fires.
auto callback = std::make_shared<call<int>>([tce](int)
{
tce.set();
});

// Connect the timer to the callback and start the timer.
fire_once->link_target(callback.get());
fire_once->start();

// Create a task that completes after the completion event is set.
task<void> event_set(tce);

// Create a continuation task that cleans up resources and
// and return that continuation task.
return event_set.then([callback = std::move(callback), fire_once = std::move(fire_once)]()
{
});
}

concurrency::task<RcdFetchResult> ResourceCacheDeviceV2::DoFetch(const ResourceCacheEntryList::Entry& entryRef)
{
auto entry = entryRef;
Expand Down Expand Up @@ -554,6 +587,11 @@ concurrency::task<RcdFetchResult> ResourceCacheDeviceV2::DoFetch(const ResourceC
}

tries++;

if (!result)
{
co_await complete_after(g_downloadBackoff->GetValue() * pow(2, tries));
}
} while (!result);

co_return *result;
Expand Down Expand Up @@ -963,3 +1001,8 @@ void MountResourceCacheDeviceV2(std::shared_ptr<ResourceCache> cache)
vfs::Mount(new resources::ResourceCacheDeviceV2(cache, true), "cache:/");
vfs::Mount(new resources::ResourceCacheDeviceV2(cache, false), "cache_nb:/");
}

static InitFunction initFunction([]
{
resources::g_downloadBackoff = new ConVar<int>("cl_rcdFailureBackoff", ConVar_None, 500);
});

0 comments on commit 9079223

Please sign in to comment.