Skip to content
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

Added retries to keys loading #9342

Merged
merged 1 commit into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
spylogsster marked this conversation as resolved.
Show resolved Hide resolved

base::TimeDelta CalculateKeysRetryTime() {
return base::TimeDelta::FromMilliseconds(
base::RandInt(kMinimalRequestRetryIntervalMs,
kRequetsRetryRate * kMinimalRequestRetryIntervalMs));
spylogsster marked this conversation as resolved.
Show resolved Hide resolved
}

} // 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