From df4a11857b58ac2afdeb2928f10df62a9db4cb94 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Mon, 6 Sep 2021 19:36:56 +0200 Subject: [PATCH 1/2] fix(Session): refactor into a single class; Coding style #11 --- LICENSE | 32 ++++ README.md | 6 +- .../Acknowledgements.html | 65 ++++---- examples/cli.cpp | 4 +- examples/stress.cpp | 16 +- include/kademlia/Session.h | 93 ++++++++++++ include/kademlia/first_session.hpp | 142 ------------------ include/kademlia/session.hpp | 138 ----------------- include/kademlia/session_base.hpp | 105 ------------- src/kademlia/CMakeLists.txt | 9 +- src/kademlia/Engine.h | 4 +- src/kademlia/Session.cpp | 140 +++++++++++++++++ src/kademlia/SessionImpl.h | 87 ----------- src/kademlia/first_session.cpp | 12 +- src/kademlia/session.cpp | 112 -------------- src/kademlia/session_base.cpp | 33 ---- test/TestEngine.h | 20 +-- test/unit_tests/EngineTest.cpp | 11 +- test/unit_tests/StoreValueTaskTest.cpp | 5 +- test/unit_tests/test_first_session.cpp | 17 ++- test/unit_tests/test_session.cpp | 29 ++-- 21 files changed, 359 insertions(+), 721 deletions(-) create mode 100644 LICENSE rename src/kademlia/SessionImpl.cpp => doc/Acknowledgements.html (63%) create mode 100644 include/kademlia/Session.h delete mode 100644 include/kademlia/first_session.hpp delete mode 100644 include/kademlia/session.hpp delete mode 100644 include/kademlia/session_base.hpp create mode 100644 src/kademlia/Session.cpp delete mode 100644 src/kademlia/SessionImpl.h delete mode 100644 src/kademlia/session.cpp delete mode 100644 src/kademlia/session_base.cpp diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2f2f957 --- /dev/null +++ b/LICENSE @@ -0,0 +1,32 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- +Note: +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: BSL-1.0 + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ diff --git a/README.md b/README.md index 83dd458..1299391 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Initialization: // If an error occurs, this will throw. // Following runtime errors will be reported // through an std::error_code. - kademlia::session s{ initial_peer }; + kademlia::Session s{ initial_peer }; // Run the library main loop in a dedicated thread. auto main_loop_result = std::async( std::launch::async @@ -46,7 +46,7 @@ Searching for value associated with "key1": }; // Schedule an asynchronous load. - s.async_load( "key1", on_load ); + s.asyncLoad( "key1", on_load ); // [...] ``` @@ -64,7 +64,7 @@ Saving a data into the table is similar: } // And perform the saving. - s.async_save( "key2", data, on_save ); + s.asyncSave( "key2", data, on_save ); // [...] ``` diff --git a/src/kademlia/SessionImpl.cpp b/doc/Acknowledgements.html similarity index 63% rename from src/kademlia/SessionImpl.cpp rename to doc/Acknowledgements.html index 1db4f49..dfe2ae3 100644 --- a/src/kademlia/SessionImpl.cpp +++ b/doc/Acknowledgements.html @@ -1,5 +1,27 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. + + + + +POCO Kademlia Library - Acknowledgements + + + + + + + + + +

Acknowledgements

+ +

Portions of the POCO Kademlia Library utilize the +following copyrighted material, the use of which is hereby acknowledged.

+ +

C++11 distributed hash table library

+ +
Copyright (c) 2013-2014, David Keller
+
+All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
 //
@@ -22,40 +44,7 @@
 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
- -#include "SessionImpl.h" -#include "kademlia/error.hpp" -#include "error_impl.hpp" -#include "Poco/Timespan.h" - -namespace kademlia { -namespace detail { - - -SessionImpl::SessionImpl(endpoint const& ipv4, endpoint const& ipv6, int ms): - _ioService(Poco::Timespan(Poco::Timespan::TimeDiff(ms)*1000)), - _engine{ _ioService, ipv4, ipv6 } -{ } - -SessionImpl::SessionImpl(endpoint const& initPeer, endpoint const& ipv4, endpoint const& ipv6, int ms): - _ioService(Poco::Timespan(Poco::Timespan::TimeDiff(ms)*1000)), - _engine{ _ioService, initPeer, ipv4, ipv6 } -{ } - -std::error_code SessionImpl::run() -{ - Poco::FastMutex::ScopedLock l(_mutex); - _ioService.run(); - return make_error_code(RUN_ABORTED); -} - - -void SessionImpl::abort() -{ - _ioService.stop(); - _ioService.wakeUp(); -} - -} // namespace detail -} // namespace kademlia + + diff --git a/examples/cli.cpp b/examples/cli.cpp index 472b172..3987721 100644 --- a/examples/cli.cpp +++ b/examples/cli.cpp @@ -42,7 +42,7 @@ void load(k::session & session, std::string const& key) } }; - session.async_load(key_vec, std::move(on_load)); + session.asyncLoad(key_vec, std::move(on_load)); } void save(k::session & session, std::string const& key, std::string const& val) @@ -57,7 +57,7 @@ void save(k::session & session, std::string const& key, std::string const& val) std::cout << "Saved \"" << key << "\"" << std::endl; }; - session.async_save(key_vec, val_vec, std::move(on_save)); + session.asyncSave(key_vec, val_vec, std::move(on_save)); } void print_interactive_help() diff --git a/examples/stress.cpp b/examples/stress.cpp index 09bcdb3..05c8211 100644 --- a/examples/stress.cpp +++ b/examples/stress.cpp @@ -4,8 +4,7 @@ #include #include "kademlia/endpoint.hpp" -#include "kademlia/session.hpp" -#include "kademlia/first_session.hpp" +#include "kademlia/Session.h" #include "kademlia/error.hpp" #include "kademlia/detail/Util.h" #include "Poco/Timestamp.h" @@ -24,6 +23,7 @@ using Poco::Timespan; using Poco::Logger; using Poco::LogStream; using Poco::Net::SocketAddress; +using Session = Kademlia::Session; namespace { @@ -38,7 +38,7 @@ void load(S& session, std::string const& key) { std::vector key_vec(key.begin(), key.end()); Timestamp ts; - auto on_load = [key, ts] (std::error_code const& error, k::session::data_type const& data) + auto on_load = [key, ts] (std::error_code const& error, Session::DataType const& data) { if (error) _logger.error() << "Failed to load \"" << key << "\", error: " << error.message() << std::endl; @@ -51,7 +51,7 @@ void load(S& session, std::string const& key) } }; - session.async_load(key_vec, std::move(on_load)); + session.asyncLoad(key_vec, std::move(on_load)); _logger.debug() << "Async loading \"" << key << "\" ..." << std::endl; } @@ -73,7 +73,7 @@ void save(S& session, std::string const& key, std::string const& val) } }; - session.async_save(key_vec, val_vec, std::move(on_save)); + session.asyncSave(key_vec, val_vec, std::move(on_save)); _logger.debug() << "Async saving \"" << key << "\": \"" << val << "\"" << std::endl; } @@ -105,17 +105,17 @@ int main(int argc, char** argv) int reps = 50; pool.addCapacity(reps*2); - k::first_session firstSession{ k::endpoint{bootAddr4, bootPort4}, k::endpoint{bootAddr6, bootPort6} }; + Session firstSession{ k::endpoint{bootAddr4, bootPort4}, k::endpoint{bootAddr6, bootPort6} }; _logger.information() << "bootstrap session listening on " << bootAddr4 << ':' << bootPort4 << ", " << '[' << bootAddr6 << "]:" << bootPort6 << std::endl; uint16_t sessPort4 = kd::getAvailablePort(SocketAddress::IPv4, bootPort4 + 1); uint16_t sessPort6 = kd::getAvailablePort(SocketAddress::IPv6, bootPort6 + 1); - std::vector sessions; + std::vector sessions; for (int i = 0; i < reps; ++i) { - sessions.push_back(new k::session{ k::endpoint{ "127.0.0.1", bootPort4 } + sessions.push_back(new Session{ k::endpoint{ "127.0.0.1", bootPort4 } , k::endpoint{ "127.0.0.1", sessPort4 } , k::endpoint{ "::1", sessPort6} }); _logger.information() << "peer session connected to 127.0.0.1:" << bootPort4 << diff --git a/include/kademlia/Session.h b/include/kademlia/Session.h new file mode 100644 index 0000000..b8a35d1 --- /dev/null +++ b/include/kademlia/Session.h @@ -0,0 +1,93 @@ +// +// Session.h +// +// Library: Kademlia +// Package: DHT +// Module: Session +// +// Definition of the Session class. +// +// Copyright (c) 2021, Aleph ONE Software Engineering and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + +#ifndef KADEMLIA_SESSION_H +#define KADEMLIA_SESSION_H + + +#include +#include "Poco/ActiveMethod.h" +#include "Poco/Mutex.h" +#include "Poco/Net/DatagramSocket.h" +#include "Poco/Net/SocketProactor.h" +#include "kademlia/endpoint.hpp" + + +namespace Kademlia { + +class EngineImpl; + +class KADEMLIA_SYMBOL_VISIBILITY Session +{ +public: + using DataType = std::vector; + using KeyType = std::vector; + using Endpoint = kademlia::endpoint; + using SaveHandlerType = std::function; + using LoadHandlerType = std::function; + + static const std::uint16_t DEFAULT_PORT; + + Session(Endpoint const& ipv4 = {"0.0.0.0", DEFAULT_PORT}, + Endpoint const& ipv6 = {"::", DEFAULT_PORT}, int ms = 300); + + Session(Endpoint const& initPeer, Endpoint const& ipv4, Endpoint const& ipv6, int ms = 300); + + ~Session(); + + void asyncSave(KeyType const& key, DataType const& data, SaveHandlerType handler); + + template + void asyncSave(K const& key, D const& data, SaveHandlerType && handler) + { + asyncSave(KeyType(std::begin(key), std::end(key)), + DataType(std::begin(data), std::end(data)), std::move(handler)); + } + + void asyncLoad(KeyType const& key, LoadHandlerType handler ); + + template + void asyncLoad(K const& key, LoadHandlerType && handler) + { + asyncLoad(KeyType(std::begin(key), std::end(key)), std::move(handler)); + } + + std::error_code run(); + + void abort(); + std::error_code wait(); + +private: + using RunType = Poco::ActiveMethod; + using Result = Poco::ActiveResult; + using ResultPtr = std::unique_ptr; + + Result& result() + { + if (!_pResult) + _pResult.reset(new Result(this->_runMethod())); + return *_pResult; + } + + RunType _runMethod; + Poco::Net::SocketProactor _ioService; + std::unique_ptr _pEngine; + ResultPtr _pResult; + Poco::FastMutex _mutex; +}; + +} // namespace kademlia + +#endif + diff --git a/include/kademlia/first_session.hpp b/include/kademlia/first_session.hpp deleted file mode 100644 index 6c4769b..0000000 --- a/include/kademlia/first_session.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef KADEMLIA_FIRST_SESSION_HPP -#define KADEMLIA_FIRST_SESSION_HPP - - -#include -#include - -#include -#include -#include -#include - -namespace kademlia { - -/** - * @brief This object is used to bootstrap a network. - */ -class first_session final : public session_base -{ -public: - /** - * @brief Construct a passive first_session. - * @details This first_session acts like an active first_session except it - * does'nt try to discover neighbors. It can be used - * by the first node of a network as no peer is known - * uppon its creation. - * - * It does'nt make sense to use this constructor once the - * network has at least one peer. - * - * @param listen_on_ipv4 IPv4 listening endpoint. - * @param listen_on_ipv6 IPv6 listening endpoint. - */ - KADEMLIA_SYMBOL_VISIBILITY - first_session - ( endpoint const& listen_on_ipv4 = endpoint{ "0.0.0.0", DEFAULT_PORT } - , endpoint const& listen_on_ipv6 = endpoint{ "::", DEFAULT_PORT } ); - - /** - * @brief Destruct the first_session. - */ - KADEMLIA_SYMBOL_VISIBILITY - ~first_session(); - - /** - * @brief Disabled copy constructor. - */ - first_session(const first_session& ) = delete; - - /** - * @brief Disabled assignment operator. - */ - first_session& operator=(const first_session& ) = delete; - - /** - * @brief Async save a data into the network. - * - * @param key The data to save key. - * @param data The data to save. - * @param handler Callback called to report call status. - */ - KADEMLIA_SYMBOL_VISIBILITY - void async_save(key_type const& key, data_type const& data, save_handler_type handler); - - template - void async_save(KeyType const& key, DataType const& data, save_handler_type handler) - { - async_save( key_type{std::begin(key), std::end(key)} - , data_type{std::begin(data), std::end(data)} - , std::move(handler)); - } - - /** - * @brief Async load a data from the network. - * - * @param key The data to save key. - * @param handler Callback called to report call status. - */ - KADEMLIA_SYMBOL_VISIBILITY - void async_load(key_type const& key, load_handler_type handler ); - - template< typename KeyType > - void async_load(KeyType const& key, load_handler_type handler) - { - async_load(key_type{std::begin(key), std::end(key)}, std::move(handler)); - } - - /** - * @brief This blocking call execute the first_session main loop. - * - * @return The exit reason of the call. - */ - KADEMLIA_SYMBOL_VISIBILITY - std::error_code runImpl(); - - KADEMLIA_SYMBOL_VISIBILITY - std::error_code wait(); - - /** - * @brief Abort the first_session main loop. - */ - KADEMLIA_SYMBOL_VISIBILITY - void abort(); - -private: - /// Hidden implementation. - struct impl; - -private: - /// The hidden implementation instance. - std::unique_ptr< impl > impl_; -}; - -} // namespace kademlia - -#endif - diff --git a/include/kademlia/session.hpp b/include/kademlia/session.hpp deleted file mode 100644 index 66d93a9..0000000 --- a/include/kademlia/session.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef KADEMLIA_SESSION_HPP -#define KADEMLIA_SESSION_HPP - -#ifdef _MSC_VER -# pragma once -#endif - -#include -#include - -#include -#include -#include -#include - -namespace kademlia { - -/** - * @brief This object is used to save and load data from the network. - */ -class session final: public session_base -{ -public: - /** - * @brief Construct an active session. - * @details This session perform a neighbors discovery on creation. - * If the network is down or the neighbor can't be contacted, - * an exception will be throw from the session::run() - * method. - * - * @param initial_peer In order to discover network peers, the session - * contacts this peer and retrieve it's neighbors. - * @param listen_on_ipv4 IPv4 listening endpoint. - * @param listen_on_ipv6 IPv6 listening endpoint. - */ - KADEMLIA_SYMBOL_VISIBILITY - session(endpoint const& initial_peer, - endpoint const& listen_on_ipv4 = endpoint{ "0.0.0.0", DEFAULT_PORT }, - endpoint const& listen_on_ipv6 = endpoint{ "::", DEFAULT_PORT } ); - - /** - * @brief Destruct the session. - */ - KADEMLIA_SYMBOL_VISIBILITY - ~session(); - - /** - * @brief Disabled copy constructor. - */ - session(session const&) = delete; - - /** - * @brief Disabled assignment operator. - */ - session& operator= (session const&) = delete; - - /** - * @brief Async save a data into the network. - * - * @param key The data to save key. - * @param data The data to save. - * @param handler Callback called to report call status. - */ - KADEMLIA_SYMBOL_VISIBILITY - void async_save(key_type const& key, data_type const& data, save_handler_type handler); - - template - void async_save(KeyType const& key, DataType const& data, save_handler_type handler) - { - async_save( key_type{std::begin(key), std::end(key)} - , data_type{std::begin(data), std::end(data)} - , std::move(handler)); - } - - /** - * @brief Async load a data from the network. - * - * @param key The data to save key. - * @param handler Callback called to report call status. - */ - KADEMLIA_SYMBOL_VISIBILITY - void async_load(key_type const& key, load_handler_type handler ); - - template< typename KeyType > - void async_load(KeyType const& key, load_handler_type handler) - { - async_load(key_type{std::begin(key), std::end(key)}, std::move(handler)); - } - - KADEMLIA_SYMBOL_VISIBILITY - std::error_code wait(); - - /** - * @brief Abort the session main loop. - */ - KADEMLIA_SYMBOL_VISIBILITY - void abort(); - -private: - std::error_code runImpl(); - - /// Hidden implementation. - struct impl; - -private: - /// The hidden implementation instance. - std::unique_ptr impl_; -}; - -} // namespace kademlia - -#endif - diff --git a/include/kademlia/session_base.hpp b/include/kademlia/session_base.hpp deleted file mode 100644 index 445be4f..0000000 --- a/include/kademlia/session_base.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef KADEMLIA_SESSION_BASE_HPP -#define KADEMLIA_SESSION_BASE_HPP - -#ifdef _MSC_VER -# pragma once -#endif - -#include "Poco/ActiveMethod.h" -#include -#include -#include -#include -#include - -#include - -namespace kademlia { - -/** - * @brief This object contains session types. - */ -class session_base -{ -public: - /// The key type used to find data. - using key_type = std::vector< std::uint8_t >; - - /// The stored data type. - using data_type = std::vector< std::uint8_t >; - - /// The callback type called to signal an async save status. - using save_handler_type = std::function - < void - ( std::error_code const& error ) - >; - /// The callback type called to signal an async load status. - using load_handler_type = std::function - < void - ( std::error_code const& error - , data_type const& data ) - >; - - /// This kademlia implementation default port. - static CXX11_CONSTEXPR std::uint16_t DEFAULT_PORT = 27980; - -protected: - session_base(): runMethod(this, &session_base::runImpl) - { - } - - using RunType = Poco::ActiveMethod; - using Result = Poco::ActiveResult; - using ResultPtr = std::unique_ptr; - RunType runMethod; - virtual std::error_code runImpl(void) = 0; - - Result& result() - { - if (!_pResult) - _pResult.reset(new Result(this->runMethod())); - return *_pResult; - } - - /** - * @brief Destructor used to prevent - * usage derived classes as this - * base. - */ - ~session_base - ( void ) - = default; - -private: - ResultPtr _pResult; -}; - -} // namespace kademlia - -#endif - diff --git a/src/kademlia/CMakeLists.txt b/src/kademlia/CMakeLists.txt index a4cc806..d434a3e 100644 --- a/src/kademlia/CMakeLists.txt +++ b/src/kademlia/CMakeLists.txt @@ -37,10 +37,11 @@ set(kademlia_sources Peer.cpp ResponseCallbacks.cpp ResponseRouter.cpp - session.cpp - SessionImpl.cpp - session_base.cpp - first_session.cpp +# session.cpp +# SessionImpl.cpp +# session_base.cpp +# first_session.cpp + Session.cpp Timer.cpp Util.cpp) diff --git a/src/kademlia/Engine.h b/src/kademlia/Engine.h index b609422..ad8668b 100644 --- a/src/kademlia/Engine.h +++ b/src/kademlia/Engine.h @@ -114,14 +114,14 @@ class Engine final Engine & operator = (Engine const&) = delete; template - void async_save(key_type const& key, data_type const& data, HandlerType && handler) + void asyncSave(key_type const& key, data_type const& data, HandlerType && handler) { LOG_DEBUG( engine, this ) << "executing async save of key '" << toString(key) << "'." << std::endl; start_store_value_task(id(key), data, tracker_, routing_table_, std::forward< HandlerType >(handler)); } template - void async_load(key_type const& key, HandlerType && handler) + void asyncLoad(key_type const& key, HandlerType && handler) { LOG_DEBUG( engine, this ) << "executing async load of key '" << toString( key ) << "'." << std::endl; diff --git a/src/kademlia/Session.cpp b/src/kademlia/Session.cpp new file mode 100644 index 0000000..acfaf48 --- /dev/null +++ b/src/kademlia/Session.cpp @@ -0,0 +1,140 @@ +// +// Session.h +// +// Library: Kademlia +// Package: DHT +// Module: Session +// +// Definition of the Session class. +// +// Copyright (c) 2021, Aleph ONE Software Engineering and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "kademlia/Session.h" +#include "kademlia/error.hpp" +#include "error_impl.hpp" +#include "SocketAdapter.h" +#include "Engine.h" +#include "Poco/Timespan.h" + +namespace Kademlia { + +using Endpoint = Session::Endpoint; + +class EngineImpl +{ +public: + using SocketType = kademlia::detail::SocketAdapter; + using EngineType = kademlia::detail::Engine; + + EngineImpl(Poco::Net::SocketProactor& ioService, Endpoint const& ipv4, Endpoint const& ipv6): + _engine(ioService, ipv4, ipv6) + {} + + EngineImpl(Poco::Net::SocketProactor& ioService, Endpoint const& initPeer, Endpoint const& ipv4, Endpoint const& ipv6): + _engine(ioService, initPeer, ipv4, ipv6) + {} + + EngineType& engine() + { + return _engine; + } + +private: + EngineType _engine; +}; + + +const std::uint16_t Session::DEFAULT_PORT = 27980; + + +Session::Session(Endpoint const& ipv4, Endpoint const& ipv6, int ms) +try: + _runMethod(this, &Kademlia::Session::run), + _ioService(Poco::Timespan(Poco::Timespan::TimeDiff(ms)*1000)), + _pEngine(new EngineImpl(_ioService, ipv4, ipv6)) + { + result(); + } +catch (std::exception& ex) +{ + std::cerr << ex.what() << std::endl; + throw; +} +catch (...) +{ + std::cerr << "unknown exception" << std::endl; + throw; +} + + +Session::Session(Endpoint const& initPeer, Endpoint const& ipv4, Endpoint const& ipv6, int ms) +try: + _runMethod(this, &Kademlia::Session::run), + _ioService(Poco::Timespan(Poco::Timespan::TimeDiff(ms)*1000)), + _pEngine(new EngineImpl(_ioService, initPeer, ipv4, ipv6)) + { + result(); + } +catch (std::exception& ex) +{ + std::cerr << ex.what() << std::endl; + throw; +} +catch (...) +{ + std::cerr << "unknown exception" << std::endl; + throw; +} + + +Session::~Session() +{ + abort(); + wait(); +} + + +std::error_code Session::run() +{ + Poco::FastMutex::ScopedLock l(_mutex); + try + { + _ioService.run(); + } + catch (std::exception& ex) + { + std::cerr << ex.what() << std::endl; + } + return kademlia::detail::make_error_code(kademlia::RUN_ABORTED); +} + + +void Session::abort() +{ + _ioService.stop(); + _ioService.wakeUp(); +} + + +std::error_code Session::wait() +{ + result().wait(); + return result().data(); +} + +void Session::asyncSave(KeyType const& key, DataType const& data, SaveHandlerType handler) +{ + _pEngine->engine().asyncSave(key, data, std::move(handler)); +} + +void Session::asyncLoad(KeyType const& key, LoadHandlerType handler ) +{ + _pEngine->engine().asyncLoad(key, std::move(handler)); +} + + +} // namespace kademlia diff --git a/src/kademlia/SessionImpl.h b/src/kademlia/SessionImpl.h deleted file mode 100644 index b2d6467..0000000 --- a/src/kademlia/SessionImpl.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef KADEMLIA_SESSION_IMPL_H -#define KADEMLIA_SESSION_IMPL_H - -#ifdef _MSC_VER -# pragma once -#endif - - -#include -#include "SocketAdapter.h" -#include "Poco/Mutex.h" -#include "Poco/Net/DatagramSocket.h" -#include "Poco/Net/SocketProactor.h" -#include "MessageSocket.h" -#include "kademlia/endpoint.hpp" -#include "Engine.h" - - -namespace kademlia { -namespace detail { - - -class SessionImpl -{ -public: - using DataType = std::vector; - using KeyType = std::vector; - using SocketType = SocketAdapter; - using EngineType = detail::Engine; - -public: - SessionImpl(endpoint const& listen_on_ipv4, endpoint const& listen_on_ipv6, int ms = 300); - - SessionImpl(endpoint const& initial_peer, endpoint const& listen_on_ipv4, endpoint const& listen_on_ipv6, int ms = 300); - - template - void async_save(KeyType const& key, DataType const& data, HandlerType && handler) - { - _engine.async_save(key, data, std::forward(handler)); - } - - template - void async_load(KeyType const& key, HandlerType && handler) - { - _engine.async_load(key, std::forward(handler)); - } - - std::error_code run(); - - void abort(); - -private: - Poco::Net::SocketProactor _ioService; - EngineType _engine; - Poco::FastMutex _mutex; -}; - -} // namespace detail -} // namespace kademlia - -#endif - diff --git a/src/kademlia/first_session.cpp b/src/kademlia/first_session.cpp index bc1961b..018bf7a 100644 --- a/src/kademlia/first_session.cpp +++ b/src/kademlia/first_session.cpp @@ -22,7 +22,7 @@ // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +#if 0 #include #include "SessionImpl.h" @@ -59,18 +59,18 @@ first_session::~first_session } -void first_session::async_save(key_type const& key, +void first_session::asyncSave(key_type const& key, data_type const& data, save_handler_type handler) { - impl_->async_save( key, data, std::move( handler ) ); + impl_->asyncSave( key, data, std::move( handler ) ); } -void first_session::async_load(key_type const& key, +void first_session::asyncLoad(key_type const& key, load_handler_type handler) { - impl_->async_load( key, std::move( handler ) ); + impl_->asyncLoad( key, std::move( handler ) ); } std::error_code @@ -90,4 +90,4 @@ first_session::abort { impl_->abort(); } } // namespace kademlia - +#endif diff --git a/src/kademlia/session.cpp b/src/kademlia/session.cpp deleted file mode 100644 index 38ca859..0000000 --- a/src/kademlia/session.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include "SessionImpl.h" - -namespace kademlia { - -/** - * - */ -struct session::impl final: detail::SessionImpl -{ - impl(endpoint const& initial_peer, - endpoint const& listen_on_ipv4, - endpoint const& listen_on_ipv6): - SessionImpl{initial_peer, listen_on_ipv4, listen_on_ipv6 } - { } -}; - -session::session(endpoint const& initial_peer, - endpoint const& listen_on_ipv4, - endpoint const& listen_on_ipv6 ) -try : - impl_{ new impl{ initial_peer, listen_on_ipv4, listen_on_ipv6 } } - { - result(); - } -catch (std::exception& ex) -{ - std::cerr << ex.what() << std::endl; - throw; -} -catch (...) -{ - std::cerr << "unknown exception" << std::endl; - throw; -} - -session::~session() -{ - abort(); - wait(); -} - - -void session::async_save(key_type const& key, - data_type const& data, - save_handler_type handler) -{ - impl_->async_save( key, data, std::move( handler ) ); -} - - -void session::async_load(key_type const& key, - load_handler_type handler) -{ - impl_->async_load( key, std::move( handler ) ); -} - - -std::error_code session::wait() -{ - result().wait(); - return result().data(); -} - - -std::error_code session::runImpl() -{ - try - { - return impl_->run(); - } - catch (std::exception& ex) - { - std::cerr << ex.what() << std::endl; - abort(); - } - return kademlia::detail::make_error_code(RUN_ABORTED); -} - - -void session::abort() -{ - impl_->abort(); -} - -} // namespace kademlia diff --git a/src/kademlia/session_base.cpp b/src/kademlia/session_base.cpp deleted file mode 100644 index 766c217..0000000 --- a/src/kademlia/session_base.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2013-2014, David Keller -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of California, Berkeley nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY DAVID KELLER AND CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "kademlia/session_base.hpp" - -namespace kademlia { - -CXX11_CONSTEXPR std::uint16_t session_base::DEFAULT_PORT; - -} // namespace kademlia - diff --git a/test/TestEngine.h b/test/TestEngine.h index cf3965f..68cf085 100644 --- a/test/TestEngine.h +++ b/test/TestEngine.h @@ -25,7 +25,7 @@ #include #include "Poco/Net/SocketProactor.h" -#include +#include "kademlia/Session.h" #include #include "kademlia/log.hpp" #include "kademlia/buffer.hpp" @@ -35,32 +35,34 @@ namespace kademlia { namespace test { +using Session = Kademlia::Session; + class TestEngine final { public: TestEngine(Poco::Net::SocketProactor& service,endpoint const & ipv4,endpoint const & ipv6, detail::id const& new_id): engine_(service, ipv4, ipv6, new_id), - listen_ipv4_(FakeSocket::get_last_allocated_ipv4(), session_base::DEFAULT_PORT), - listen_ipv6_(FakeSocket::get_last_allocated_ipv6(), session_base::DEFAULT_PORT) + listen_ipv4_(FakeSocket::get_last_allocated_ipv4(), Session::DEFAULT_PORT), + listen_ipv6_(FakeSocket::get_last_allocated_ipv6(), Session::DEFAULT_PORT) { } TestEngine(Poco::Net::SocketProactor& service, endpoint const & initial_peer , endpoint const & ipv4, endpoint const & ipv6, detail::id const& new_id) : engine_(service, initial_peer, ipv4, ipv6, new_id), - listen_ipv4_(FakeSocket::get_last_allocated_ipv4(), session_base::DEFAULT_PORT), - listen_ipv6_(FakeSocket::get_last_allocated_ipv6(), session_base::DEFAULT_PORT) + listen_ipv4_(FakeSocket::get_last_allocated_ipv4(), Session::DEFAULT_PORT), + listen_ipv6_(FakeSocket::get_last_allocated_ipv6(), Session::DEFAULT_PORT) { } template< typename Callable > - void async_save(std::string const& key, std::string const& data, Callable & callable) + void asyncSave(std::string const& key, std::string const& data, Callable & callable) { impl::key_type const k{ key.begin(), key.end() }; impl::data_type const d{ data.begin(), data.end() }; - engine_.async_save(k, d, callable); + engine_.asyncSave(k, d, callable); } template< typename Callable > - void async_load(std::string const& key, Callable & callable) + void asyncLoad(std::string const& key, Callable & callable) { impl::key_type const k{ key.begin(), key.end() }; auto c = [ callable ](std::error_code const& failure, impl::data_type const& data) @@ -68,7 +70,7 @@ class TestEngine final callable(failure, std::string{ data.begin(), data.end() }); }; - engine_.async_load(k, c); + engine_.asyncLoad(k, c); } endpoint diff --git a/test/unit_tests/EngineTest.cpp b/test/unit_tests/EngineTest.cpp index 8bb2d60..93cc4b4 100644 --- a/test/unit_tests/EngineTest.cpp +++ b/test/unit_tests/EngineTest.cpp @@ -37,6 +37,7 @@ namespace t = k::test; using Poco::Net::SocketProactor; using Poco::Thread; +using Session = Kademlia::Session; template std::unique_ptr< t::TestEngine > @@ -44,8 +45,8 @@ create_test_engine(SocketProactor& io_service , d::id const& id , InitialPeer &&... initial_peer) { - k::endpoint ipv4_endpoint{ "127.0.0.1", k::session_base::DEFAULT_PORT }; - k::endpoint ipv6_endpoint{ "::1", k::session_base::DEFAULT_PORT }; + k::endpoint ipv4_endpoint{ "127.0.0.1", Session::DEFAULT_PORT }; + k::endpoint ipv6_endpoint{ "::1", Session::DEFAULT_PORT }; using engine_ptr = std::unique_ptr< t::TestEngine >; @@ -61,7 +62,7 @@ TEST(EngineTest, isolated_engine_cannot_be_constructed) { Poco::Net::SocketProactor io_service; - k::endpoint initial_peer{ "172.18.1.2", k::session_base::DEFAULT_PORT }; + k::endpoint initial_peer{ "172.18.1.2", Session::DEFAULT_PORT }; EXPECT_THROW(create_test_engine(io_service , d::id{} @@ -96,7 +97,7 @@ TEST(EngineTest, two_engines_can_save_and_load) auto on_save = [](std::error_code const& failure) { if (failure) throw std::system_error{ failure }; }; - e1->async_save("key", expected_data, on_save); + e1->asyncSave("key", expected_data, on_save); EXPECT_GT(io_service.poll(), 0); @@ -106,7 +107,7 @@ TEST(EngineTest, two_engines_can_save_and_load) if (expected_data != actual_data) throw std::runtime_error{ "Unexpected data" }; }; - e2->async_load("key", on_load); + e2->asyncLoad("key", on_load); EXPECT_GT(io_service.poll(), 0); } diff --git a/test/unit_tests/StoreValueTaskTest.cpp b/test/unit_tests/StoreValueTaskTest.cpp index 8f4d943..746c115 100644 --- a/test/unit_tests/StoreValueTaskTest.cpp +++ b/test/unit_tests/StoreValueTaskTest.cpp @@ -195,10 +195,7 @@ TEST_F(StoreValueTaskTest, CanStoreValueWhenDiscoveredPeerIsTheTarget) , tracker_ , routing_table_ , std::ref(*this)); - while (!callback_call_count_) - { - io_service_.poll(); - } + io_service_.poll(); // Task queried routing table to find closest known peers. EXPECT_EQ(1, routing_table_.find_call_count_); diff --git a/test/unit_tests/test_first_session.cpp b/test/unit_tests/test_first_session.cpp index 59589f6..a34b947 100644 --- a/test/unit_tests/test_first_session.cpp +++ b/test/unit_tests/test_first_session.cpp @@ -24,7 +24,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "kademlia/error.hpp" -#include "kademlia/first_session.hpp" +#include "kademlia/Session.h" #include "kademlia/detail/Util.h" #include "common.hpp" #include "Network.h" @@ -37,13 +37,14 @@ namespace { namespace k = kademlia; namespace kd = kademlia::detail; using namespace Poco::Net; +using Session = Kademlia::Session; TEST(FirstSessionTest, opens_sockets_on_all_interfaces_by_default) { - k::first_session s; + Session s; - k::test::checkListening("0.0.0.0", k::first_session::DEFAULT_PORT); - k::test::checkListening("::", k::first_session::DEFAULT_PORT); + k::test::checkListening("0.0.0.0", Session::DEFAULT_PORT); + k::test::checkListening("::", Session::DEFAULT_PORT); } TEST(FirstSessionTest, opens_both_ipv4_ipv6_sockets) @@ -54,7 +55,7 @@ TEST(FirstSessionTest, opens_both_ipv4_ipv6_sockets) k::endpoint ipv4_endpoint{ "127.0.0.1", port1 }; k::endpoint ipv6_endpoint{ "::1", port2 }; - k::first_session s{ ipv4_endpoint, ipv6_endpoint }; + Session s{ ipv4_endpoint, ipv6_endpoint }; k::test::checkListening("127.0.0.1", port1); k::test::checkListening("::1", port2); @@ -68,7 +69,7 @@ TEST(FirstSessionTest, throw_on_invalid_ipv6_address) k::endpoint ipv4_endpoint{ "127.0.0.1", port1 }; k::endpoint ipv6_endpoint{ "0.0.0.0", port2 }; - EXPECT_THROW(k::first_session s(ipv4_endpoint, ipv6_endpoint),std::exception); + EXPECT_THROW(Session s(ipv4_endpoint, ipv6_endpoint),std::exception); } TEST(FirstSessionTest, throw_on_invalid_ipv4_address) @@ -79,13 +80,13 @@ TEST(FirstSessionTest, throw_on_invalid_ipv4_address) k::endpoint ipv4_endpoint{ "::", port1 }; k::endpoint ipv6_endpoint{ "::1", port2 }; - EXPECT_THROW(k::first_session s(ipv4_endpoint, ipv6_endpoint), std::exception); + EXPECT_THROW(Session s(ipv4_endpoint, ipv6_endpoint), std::exception); } TEST(FirstSessionTest, run_can_be_aborted) { - k::first_session s; + Session s; s.abort(); auto result = s.wait(); EXPECT_TRUE(result/*.get()*/ == k::RUN_ABORTED); diff --git a/test/unit_tests/test_session.cpp b/test/unit_tests/test_session.cpp index 3d10780..9d63e0f 100644 --- a/test/unit_tests/test_session.cpp +++ b/test/unit_tests/test_session.cpp @@ -25,8 +25,7 @@ #include "kademlia/error.hpp" -#include "kademlia/session.hpp" -#include "kademlia/first_session.hpp" +#include "kademlia/Session.h" #include "kademlia/detail/Util.h" #include "common.hpp" #include "Network.h" @@ -38,14 +37,14 @@ namespace { namespace k = kademlia; namespace kd = kademlia::detail; using namespace Poco::Net; - +using Session = Kademlia::Session; TEST(SessionTest, session_opens_sockets_on_all_interfaces_by_default) { - k::first_session s; + Session s; - k::test::checkListening("0.0.0.0", k::first_session::DEFAULT_PORT); - k::test::checkListening("::", k::first_session::DEFAULT_PORT); + k::test::checkListening("0.0.0.0", Session::DEFAULT_PORT); + k::test::checkListening("::", Session::DEFAULT_PORT); } TEST(SessionTest, session_opens_both_ipv4_ipv6_sockets) @@ -56,7 +55,7 @@ TEST(SessionTest, session_opens_both_ipv4_ipv6_sockets) k::endpoint ipv4_endpoint{"127.0.0.1", port1}; k::endpoint ipv6_endpoint{"::1", port2}; - k::first_session s{ ipv4_endpoint, ipv6_endpoint }; + Session s{ ipv4_endpoint, ipv6_endpoint }; k::test::checkListening("127.0.0.1", port1); k::test::checkListening("::1", port2); @@ -70,7 +69,7 @@ TEST(SessionTest, session_throw_on_invalid_ipv6_address) k::endpoint ipv4_endpoint{ "127.0.0.1", port1 }; k::endpoint ipv6_endpoint{ "0.0.0.0", port2 }; - EXPECT_THROW(k::first_session s(ipv4_endpoint, ipv6_endpoint), std::exception); + EXPECT_THROW(Session s(ipv4_endpoint, ipv6_endpoint), std::exception); } TEST(SessionTest, session_throw_on_invalid_ipv4_address) @@ -81,13 +80,13 @@ TEST(SessionTest, session_throw_on_invalid_ipv4_address) k::endpoint ipv4_endpoint{ "::", port1 }; k::endpoint ipv6_endpoint{ "::1", port2 }; - EXPECT_THROW(k::first_session s(ipv4_endpoint, ipv6_endpoint), std::exception); + EXPECT_THROW(Session s(ipv4_endpoint, ipv6_endpoint), std::exception); } TEST(SessionTest, session_run_can_be_aborted) { - k::first_session s{}; + Session s{}; s.abort(); auto result = s.wait(); @@ -100,11 +99,11 @@ TEST(SessionTest, session_can_save_and_load) auto const fs_port4 = kd::getAvailablePort(SocketAddress::IPv4); auto const fs_port6 = kd::getAvailablePort(SocketAddress::IPv6); k::endpoint const first_session_endpoint{ "127.0.0.1", fs_port4 }; - k::first_session fs{first_session_endpoint, k::endpoint{"::1", fs_port6}}; + Session fs{first_session_endpoint, k::endpoint{"::1", fs_port6}}; auto const s_port4 = kd::getAvailablePort(SocketAddress::IPv4, fs_port4+1); auto const s_port6 = kd::getAvailablePort(SocketAddress::IPv6, fs_port6+1); - k::session s{first_session_endpoint + Session s{first_session_endpoint , k::endpoint{"127.0.0.1", s_port4} , k::endpoint{"::1", s_port6}}; @@ -114,7 +113,7 @@ TEST(SessionTest, session_can_save_and_load) std::string actual_value; auto on_load = [ &s, &actual_value ] ( std::error_code const& failure - , k::session::data_type const& data ) + , Session::DataType const& data ) { if ( ! failure ) actual_value.assign( data.begin(), data.end() ); @@ -127,10 +126,10 @@ TEST(SessionTest, session_can_save_and_load) if ( failure ) s.abort(); else - s.async_load( key, on_load ); + s.asyncLoad( key, on_load ); }; - s.async_save( key, expected_value, on_save ); + s.asyncSave( key, expected_value, on_save ); auto s_result = s.wait(); From f78996a09f9a621c3d1a209269c20f87689a1bd8 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Mon, 6 Sep 2021 19:48:37 +0200 Subject: [PATCH 2/2] fix(examples): adjust for single Session class; Coding style #11 --- examples/bootstrap.cpp | 9 +++++---- examples/cli.cpp | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/bootstrap.cpp b/examples/bootstrap.cpp index 16f2ad2..766e8a9 100644 --- a/examples/bootstrap.cpp +++ b/examples/bootstrap.cpp @@ -8,9 +8,10 @@ #include #include -#include +#include "kademlia/Session.h" -namespace k = kademlia; +using Session = Kademlia::Session; +using Endpoint = kademlia::endpoint; int main(int argc, char** argv ) { @@ -25,7 +26,7 @@ int main(int argc, char** argv ) std::uint16_t const port = std::atoi( argv[1] ); // Create the session - k::first_session session{k::endpoint{"0.0.0.0", port}, k::endpoint{"::", port}}; + Session session{Endpoint{"0.0.0.0", port}, Endpoint{"::", port}}; // Wait for exit request std::cout << "Press any key to exit" << std::endl; @@ -36,6 +37,6 @@ int main(int argc, char** argv ) // Wait for the main loop thread termination auto failure = session.wait(); - if ( failure != k::RUN_ABORTED ) + if ( failure != kademlia::RUN_ABORTED ) std::cerr << failure.message() << std::endl; } diff --git a/examples/cli.cpp b/examples/cli.cpp index 3987721..a1c733c 100644 --- a/examples/cli.cpp +++ b/examples/cli.cpp @@ -7,10 +7,11 @@ #include #include -#include +#include "kademlia/Session.h" #include -namespace k = kademlia; +using Session = Kademlia::Session; +using Endpoint = kademlia::endpoint; namespace { @@ -28,10 +29,10 @@ std::vector split(std::string const& line) return std::vector{ iterator{ in }, iterator{} }; } -void load(k::session & session, std::string const& key) +void load(Session & session, std::string const& key) { std::vector key_vec(key.begin(), key.end()); - auto on_load = [key] (std::error_code const& error, k::session::data_type const& data) + auto on_load = [key] (std::error_code const& error, Session::DataType const& data) { if (error) std::cerr << "Failed to load \"" << key << "\", error: " << error.message() << std::endl; @@ -45,7 +46,7 @@ void load(k::session & session, std::string const& key) session.asyncLoad(key_vec, std::move(on_load)); } -void save(k::session & session, std::string const& key, std::string const& val) +void save(Session & session, std::string const& key, std::string const& val) { std::vector key_vec(key.begin(), key.end()); std::vector val_vec(val.begin(), val.end()); @@ -90,9 +91,9 @@ int main(int argc, char** argv) auto boot_port = boot_ep.substr(sep_idx+1); // Create the session (runs in its own thread) - k::session session{ k::endpoint{ boot_addr, boot_port } - , k::endpoint{ "0.0.0.0", port } - , k::endpoint{ "::", port } }; + Session session{ Endpoint{ boot_addr, boot_port } + , Endpoint{ "0.0.0.0", port } + , Endpoint{ "::", port } }; // Parse stdin until EOF (CTRL-D in Unix, CTRL-Z-Enter on Windows)) std::cout << "Enter \"help\" to see available actions" << std::endl; @@ -131,7 +132,7 @@ int main(int argc, char** argv) // Wait for the session termination auto failure = session.wait(); - if (failure != k::RUN_ABORTED) + if (failure != kademlia::RUN_ABORTED) std::cerr << failure.message() << std::endl; std::cout << "Goodbye!" << std::endl; }