Skip to content

Commit

Permalink
Added retries to keys loading
Browse files Browse the repository at this point in the history
  • Loading branch information
spylogsster committed Jul 6, 2021
1 parent e913ab0 commit 6e02156
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 4 deletions.
15 changes: 15 additions & 0 deletions browser/ipfs/test/ipns_keys_manager_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "chrome/test/base/ui_test_utils.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/test/browser_test.h"
#include "net/base/net_errors.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"

Expand Down Expand Up @@ -229,4 +230,18 @@ IN_PROC_BROWSER_TEST_F(IpnsManagerBrowserTest, ImportKey) {
run_loop.Run();
}

IN_PROC_BROWSER_TEST_F(IpnsManagerBrowserTest, LoadKeysRetry) {
base::RunLoop run_loop;
auto* ipns_manager = ipfs_service()->GetIpnsKeysManager();
ipns_manager->LoadKeys(base::BindOnce(
[](base::OnceCallback<void(void)> launch_callback, const bool success) {
ASSERT_FALSE(success);
if (launch_callback)
std::move(launch_callback).Run();
},
run_loop.QuitClosure()));
run_loop.Run();
EXPECT_EQ(ipns_manager->GetLastLoadRetryForTest(), 0);
}

} // namespace ipfs
48 changes: 45 additions & 3 deletions components/ipfs/keys/ipns_keys_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <string>
#include <utility>

#include "base/rand_util.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "brave/components/ipfs/blob_context_getter_factory.h"
Expand All @@ -26,6 +27,29 @@
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"

namespace {

// Retry after some time If local node responded with error.
// The keys are often called immediately after startup
// and node initialization may take some time.
constexpr int kDefaultRetries = 5;

// Used to retry requests if we got error from ipfs node,
// it may fail requests sometimes right after launch,
// Actual value will be generated randomly in range
// (kMinimalRequestRetryIntervalMs,
// kRequetsRetryRate*kMinimalRequestRetryIntervalMs)
const int kMinimalRequestRetryIntervalMs = 350;
const int kRequetsRetryRate = 3;

base::TimeDelta CalculateKeysRetryTime() {
return base::TimeDelta::FromMilliseconds(
base::RandInt(kMinimalRequestRetryIntervalMs,
kRequetsRetryRate * kMinimalRequestRetryIntervalMs));
}

} // namespace

namespace ipfs {

IpnsKeysManager::IpnsKeysManager(
Expand Down Expand Up @@ -164,13 +188,17 @@ void IpnsKeysManager::LoadKeys(LoadKeysCallback callback) {
if (callback)
pending_load_callbacks_.push(std::move(callback));

LoadKeysInternal(kDefaultRetries);
}

void IpnsKeysManager::LoadKeysInternal(int retries) {
auto url_loader =
CreateURLLoader(server_endpoint_.Resolve(kAPIKeyListEndpoint), "POST");
auto iter = url_loaders_.insert(url_loaders_.begin(), std::move(url_loader));

iter->get()->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
url_loader_factory_, base::BindOnce(&IpnsKeysManager::OnKeysLoaded,
weak_factory_.GetWeakPtr(), iter));
url_loader_factory_,
base::BindOnce(&IpnsKeysManager::OnKeysLoaded, weak_factory_.GetWeakPtr(),
iter, retries));
}

void IpnsKeysManager::UploadData(
Expand Down Expand Up @@ -226,13 +254,23 @@ void IpnsKeysManager::OnIpfsShutdown() {
}

void IpnsKeysManager::OnKeysLoaded(SimpleURLLoaderList::iterator iter,
int retry_number,
std::unique_ptr<std::string> response_body) {
auto* url_loader = iter->get();
int error_code = url_loader->NetError();
int response_code = -1;
if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers)
response_code = url_loader->ResponseInfo()->headers->response_code();
url_loaders_.erase(iter);
last_load_retry_value_for_test_ = retry_number;
if (error_code == net::ERR_CONNECTION_REFUSED && retry_number) {
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&IpnsKeysManager::LoadKeysInternal,
weak_factory_.GetWeakPtr(), retry_number - 1),
CalculateKeysRetryTime());
return;
}

bool success = (error_code == net::OK && response_code == net::HTTP_OK);
std::unordered_map<std::string, std::string> new_keys;
Expand All @@ -247,6 +285,10 @@ void IpnsKeysManager::OnKeysLoaded(SimpleURLLoaderList::iterator iter,
NotifyKeysLoaded(success);
}

int IpnsKeysManager::GetLastLoadRetryForTest() const {
return last_load_retry_value_for_test_;
}

void IpnsKeysManager::SetLoadCallbackForTest(LoadKeysCallback callback) {
if (callback)
pending_load_callbacks_.push(std::move(callback));
Expand Down
5 changes: 4 additions & 1 deletion components/ipfs/keys/ipns_keys_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class IpnsKeysManager : public IpfsServiceObserver {
ImportKeyCallback callback);
void SetServerEndpointForTest(const GURL& gurl);
void SetLoadCallbackForTest(LoadKeysCallback callback);
int GetLastLoadRetryForTest() const;

private:
using SimpleURLLoaderList =
Expand All @@ -81,14 +82,16 @@ class IpnsKeysManager : public IpfsServiceObserver {
RemoveKeyCallback callback,
std::unique_ptr<std::string> response_body);
void OnKeysLoaded(SimpleURLLoaderList::iterator iter,
int retry_number,
std::unique_ptr<std::string> response_body);

void NotifyKeysLoaded(bool result);

void LoadKeysInternal(int retries);
void UploadData(ImportKeyCallback callback,
const std::string& name,
std::unique_ptr<network::ResourceRequest> request);

int last_load_retry_value_for_test_ = -1;
BlobContextGetterFactory* blob_context_getter_factory_ = nullptr;
network::mojom::URLLoaderFactory* url_loader_factory_;
SimpleURLLoaderList url_loaders_;
Expand Down

0 comments on commit 6e02156

Please sign in to comment.