This repository has been archived by the owner on Apr 17, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 297
On demand OS connection manager #1645
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "ordering/impl/on_demand_connection_manager.hpp" | ||
|
||
#include "interfaces/iroha_internal/proposal.hpp" | ||
|
||
using namespace iroha::ordering; | ||
|
||
OnDemandConnectionManager::OnDemandConnectionManager( | ||
std::shared_ptr<transport::OdOsNotificationFactory> factory, | ||
CurrentPeers initial_peers, | ||
rxcpp::observable<CurrentPeers> peers) | ||
: factory_(std::move(factory)), | ||
subscription_(peers.subscribe([this](const auto &peers) { | ||
// exclusive lock | ||
std::lock_guard<std::shared_timed_mutex> lock(mutex_); | ||
|
||
this->initializeConnections(peers); | ||
})) { | ||
// using start_with(initial_peers) results in deadlock | ||
initializeConnections(initial_peers); | ||
} | ||
|
||
void OnDemandConnectionManager::onTransactions(CollectionType transactions) { | ||
// shared lock | ||
std::shared_lock<std::shared_timed_mutex> lock(mutex_); | ||
|
||
connections_.current_consumer->onTransactions(transactions); | ||
connections_.previous_consumer->onTransactions(transactions); | ||
} | ||
|
||
boost::optional<OnDemandConnectionManager::ProposalType> | ||
OnDemandConnectionManager::onRequestProposal(transport::RoundType round) { | ||
// shared lock | ||
std::shared_lock<std::shared_timed_mutex> lock(mutex_); | ||
|
||
return connections_.issuer->onRequestProposal(round); | ||
} | ||
|
||
void OnDemandConnectionManager::initializeConnections( | ||
const CurrentPeers &peers) { | ||
auto create_assign = [this](auto &ptr, auto &peer) { | ||
ptr = factory_->create(*peer); | ||
}; | ||
|
||
create_assign(connections_.issuer, peers.issuer); | ||
create_assign(connections_.current_consumer, peers.current_consumer); | ||
create_assign(connections_.previous_consumer, peers.previous_consumer); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef IROHA_ON_DEMAND_CONNECTION_MANAGER_HPP | ||
#define IROHA_ON_DEMAND_CONNECTION_MANAGER_HPP | ||
|
||
#include "ordering/on_demand_os_transport.hpp" | ||
|
||
#include <shared_mutex> | ||
|
||
#include <rxcpp/rx-observable.hpp> | ||
|
||
namespace iroha { | ||
namespace ordering { | ||
|
||
/** | ||
* Proxy class which redirects requests to appropriate peers | ||
*/ | ||
class OnDemandConnectionManager : public transport::OdOsNotification { | ||
public: | ||
/** | ||
* Current peers to send transactions and request proposals | ||
* Transactions are sent to two ordering services: | ||
* current and previous consumers | ||
* Proposal is requested from current ordering service: issuer | ||
*/ | ||
struct CurrentPeers { | ||
std::shared_ptr<shared_model::interface::Peer> issuer, current_consumer, | ||
previous_consumer; | ||
}; | ||
|
||
/** | ||
* Corresponding connections created by OdOsNotificationFactory | ||
* @see CurrentPeers for individual descriptions | ||
*/ | ||
struct CurrentConnections { | ||
std::unique_ptr<transport::OdOsNotification> issuer, current_consumer, | ||
previous_consumer; | ||
}; | ||
|
||
OnDemandConnectionManager( | ||
std::shared_ptr<transport::OdOsNotificationFactory> factory, | ||
CurrentPeers initial_peers, | ||
rxcpp::observable<CurrentPeers> peers); | ||
|
||
void onTransactions(CollectionType transactions) override; | ||
|
||
boost::optional<ProposalType> onRequestProposal( | ||
transport::RoundType round) override; | ||
|
||
private: | ||
/** | ||
* Initialize corresponding peers in connections_ using factory_ | ||
* @param peers to initialize connections with | ||
*/ | ||
void initializeConnections(const CurrentPeers &peers); | ||
|
||
std::shared_ptr<transport::OdOsNotificationFactory> factory_; | ||
rxcpp::composite_subscription subscription_; | ||
|
||
CurrentConnections connections_; | ||
|
||
std::shared_timed_mutex mutex_; | ||
}; | ||
|
||
} // namespace ordering | ||
} // namespace iroha | ||
|
||
#endif // IROHA_ON_DEMAND_CONNECTION_MANAGER_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
test/module/irohad/ordering/on_demand_connection_manager_test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/** | ||
* Copyright Soramitsu Co., Ltd. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "ordering/impl/on_demand_connection_manager.hpp" | ||
|
||
#include <gtest/gtest.h> | ||
#include "interfaces/iroha_internal/proposal.hpp" | ||
#include "module/irohad/ordering/ordering_mocks.hpp" | ||
#include "module/shared_model/interface_mocks.hpp" | ||
|
||
using namespace iroha::ordering; | ||
using namespace iroha::ordering::transport; | ||
|
||
using ::testing::ByMove; | ||
using ::testing::Ref; | ||
using ::testing::Return; | ||
|
||
/** | ||
* Create unique_ptr with MockOdOsNotification, save to var, and return it | ||
*/ | ||
ACTION_P(CreateAndSave, var) { | ||
auto result = std::make_unique<MockOdOsNotification>(); | ||
*var = result.get(); | ||
return std::unique_ptr<OdOsNotification>(std::move(result)); | ||
} | ||
|
||
struct OnDemandConnectionManagerTest : public ::testing::Test { | ||
void SetUp() override { | ||
factory = std::make_shared<MockOdOsNotificationFactory>(); | ||
|
||
auto set = [this](auto &field, auto &ptr) { | ||
field = std::make_shared<MockPeer>(); | ||
|
||
EXPECT_CALL(*factory, create(Ref(*field))) | ||
.WillRepeatedly(CreateAndSave(&ptr)); | ||
}; | ||
|
||
set(cpeers.issuer, issuer); | ||
set(cpeers.current_consumer, current_consumer); | ||
set(cpeers.previous_consumer, previous_consumer); | ||
|
||
manager = std::make_shared<OnDemandConnectionManager>( | ||
factory, cpeers, peers.get_observable()); | ||
} | ||
|
||
OnDemandConnectionManager::CurrentPeers cpeers; | ||
MockOdOsNotification *issuer, *previous_consumer, *current_consumer; | ||
|
||
rxcpp::subjects::subject<OnDemandConnectionManager::CurrentPeers> peers; | ||
std::shared_ptr<MockOdOsNotificationFactory> factory; | ||
std::shared_ptr<OnDemandConnectionManager> manager; | ||
}; | ||
|
||
/** | ||
* @given OnDemandConnectionManager | ||
* @when peers observable is triggered | ||
* @then new peers are requested from factory | ||
*/ | ||
TEST_F(OnDemandConnectionManagerTest, FactoryUsed) { | ||
ASSERT_NE(issuer, nullptr); | ||
ASSERT_NE(previous_consumer, nullptr); | ||
ASSERT_NE(current_consumer, nullptr); | ||
} | ||
|
||
/** | ||
* @given initialized OnDemandConnectionManager | ||
* @when onTransactions is called | ||
* @then peers get data for propagation | ||
*/ | ||
TEST_F(OnDemandConnectionManagerTest, onTransactions) { | ||
OdOsNotification::CollectionType collection; | ||
EXPECT_CALL(*previous_consumer, onTransactions(collection)).Times(1); | ||
EXPECT_CALL(*current_consumer, onTransactions(collection)).Times(1); | ||
|
||
manager->onTransactions(collection); | ||
} | ||
|
||
/** | ||
* @given initialized OnDemandConnectionManager | ||
* @when onRequestProposal is called | ||
* AND proposal is returned | ||
* @then peer is triggered | ||
* AND return data is forwarded | ||
*/ | ||
TEST_F(OnDemandConnectionManagerTest, onRequestProposal) { | ||
RoundType round; | ||
boost::optional<OnDemandConnectionManager::ProposalType> oproposal = | ||
OnDemandConnectionManager::ProposalType{}; | ||
auto proposal = oproposal.value().get(); | ||
EXPECT_CALL(*issuer, onRequestProposal(round)) | ||
.WillOnce(Return(ByMove(std::move(oproposal)))); | ||
|
||
auto result = manager->onRequestProposal(round); | ||
|
||
ASSERT_TRUE(result); | ||
ASSERT_EQ(result.value().get(), proposal); | ||
} | ||
|
||
/** | ||
* @given initialized OnDemandConnectionManager | ||
* @when onRequestProposal is called | ||
* AND no proposal is returned | ||
* @then peer is triggered | ||
* AND return data is forwarded | ||
*/ | ||
TEST_F(OnDemandConnectionManagerTest, onRequestProposalNone) { | ||
RoundType round; | ||
boost::optional<OnDemandConnectionManager::ProposalType> oproposal; | ||
EXPECT_CALL(*issuer, onRequestProposal(round)) | ||
.WillOnce(Return(ByMove(std::move(oproposal)))); | ||
|
||
auto result = manager->onRequestProposal(round); | ||
|
||
ASSERT_FALSE(result); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't it be better to firstly check optional for
ASSERT_TRUE(..)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because it is not created from component being tested, but explicitly in two lines above by initializing optional with unique pointer.