diff --git a/component/inter_request_state.cc b/component/inter_request_state.cc index 589fb967..ed7b88ef 100644 --- a/component/inter_request_state.cc +++ b/component/inter_request_state.cc @@ -50,10 +50,10 @@ auto Self::cache() -> std::shared_ptr& { } return cache_; } -auto Self::orchestrator() -> Orchestrator& { +auto Self::orchestrator() -> Partition& { if (!orc_) { auto rtor = gw::default_requestor(cache(), api()); - orc_ = std::make_shared(rtor, api()); + orc_ = api()->with(rtor).partition({}); } return *orc_; } diff --git a/component/inter_request_state.h b/component/inter_request_state.h index dffb033d..6553068f 100644 --- a/component/inter_request_state.h +++ b/component/inter_request_state.h @@ -5,7 +5,7 @@ #include "ipfs_client/ctx/default_gateways.h" #include "ipfs_client/ipns_names.h" -#include "ipfs_client/orchestrator.h" +#include "ipfs_client/partition.h" #include "base/supports_user_data.h" #include "services/network/network_context.h" @@ -25,7 +25,7 @@ class COMPONENT_EXPORT(IPFS) InterRequestState std::time_t last_discovery_ = 0; std::shared_ptr cache_; base::FilePath const disk_path_; - std::shared_ptr orc_; // TODO - map of origin to Orchestrator + std::shared_ptr orc_; // TODO - map of origin to Orchestrator raw_ptr network_context_; std::shared_ptr& cache(); @@ -38,7 +38,7 @@ class COMPONENT_EXPORT(IPFS) InterRequestState Scheduler& scheduler(); std::shared_ptr api(); std::array,2> serialized_caches(); - Orchestrator& orchestrator(); + Partition& orchestrator(); void network_context(network::mojom::NetworkContext*); network::mojom::NetworkContext* network_context() const; diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 183dde2b..abf3b31b 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -241,4 +241,3 @@ if(GTest_FOUND AND IN_WORKSPACE) else() message(WARNING "Not running tests - no gtest available.") endif()#GTest_FOUND - diff --git a/library/include/ipfs_client/context_api.h b/library/include/ipfs_client/context_api.h index 48048b1a..bf60138a 100644 --- a/library/include/ipfs_client/context_api.h +++ b/library/include/ipfs_client/context_api.h @@ -10,6 +10,7 @@ #include "ctx/http_api.h" #include "ctx/json_parser.h" #include "dag_cbor_value.h" +#include "gw/requestor.h" #include "http_request_description.h" #include "ipns_cbor_entry.h" #include "multi_hash.h" @@ -27,6 +28,7 @@ class io_context; } namespace ipfs { +class Partition; class IpfsRequest; class DagJsonValue; class DagCborValue; @@ -47,16 +49,19 @@ class ContextApi : public std::enable_shared_from_this { ContextApi(); virtual ~ContextApi() noexcept {} + std::shared_ptr partition(std::string key); ctx::HttpApi& http(); ctx::DnsTxtLookup& dns_txt(); ctx::GatewayConfig& gw_cfg(); ctx::JsonParser& json(); ctx::CborParser& cbor(); + std::shared_ptr requestor(); ContextApi& with(std::unique_ptr); ContextApi& with(std::unique_ptr); ContextApi& with(std::unique_ptr); ContextApi& with(std::unique_ptr); ContextApi& with(std::unique_ptr); + ContextApi& with(std::shared_ptr); ContextApi& with(SigningKeyType, std::unique_ptr); ContextApi& with(MimeTypeDeduction); ContextApi& with(UrlUnescaping); @@ -98,6 +103,8 @@ class ContextApi : public std::enable_shared_from_this { std::unique_ptr cbor_parser_; MimeTypeDeduction deduce_mime_type_; UrlUnescaping unescape_; + std::shared_ptr rtor_; + std::unordered_map> partitions_; }; } // namespace ipfs diff --git a/library/include/ipfs_client/gw/gateway_request.h b/library/include/ipfs_client/gw/gateway_request.h index f9e15f04..6c02c111 100644 --- a/library/include/ipfs_client/gw/gateway_request.h +++ b/library/include/ipfs_client/gw/gateway_request.h @@ -14,7 +14,7 @@ namespace ipfs { class IpfsRequest; -class Orchestrator; +class Partition; namespace ipld { class DagNode; } @@ -37,7 +37,7 @@ std::string_view name(Type); constexpr std::size_t BLOCK_RESPONSE_BUFFER_SIZE = 2 * 1024 * 1024; class GatewayRequest { - std::shared_ptr orchestrator_; + std::shared_ptr orchestrator_; std::vector> bytes_received_hooks; void ParseNodes(std::string_view, ContextApi* api); @@ -60,7 +60,7 @@ class GatewayRequest { std::optional max_response_size() const; std::optional describe_http(std::string_view) const; std::string debug_string() const; - void orchestrator(std::shared_ptr const&); + void orchestrator(std::shared_ptr const&); bool cachable() const; bool RespondSuccessfully(std::string_view, diff --git a/library/include/ipfs_client/opinionated_context.h b/library/include/ipfs_client/opinionated_context.h index 8296fe2d..c9e79a3c 100644 --- a/library/include/ipfs_client/opinionated_context.h +++ b/library/include/ipfs_client/opinionated_context.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include @@ -29,8 +29,8 @@ class HttpSession; namespace ipfs { -std::pair, std::shared_ptr> -start_default(boost::asio::io_context& io); +// std::pair, std::shared_ptr> +std::shared_ptr start_default(boost::asio::io_context& io); } // namespace ipfs diff --git a/library/include/ipfs_client/orchestrator.h b/library/include/ipfs_client/partition.h similarity index 85% rename from library/include/ipfs_client/orchestrator.h rename to library/include/ipfs_client/partition.h index 7222c23c..3c252c24 100644 --- a/library/include/ipfs_client/orchestrator.h +++ b/library/include/ipfs_client/partition.h @@ -13,19 +13,20 @@ namespace ipfs { class ContextApi; -class Orchestrator : public std::enable_shared_from_this { +class Partition : public std::enable_shared_from_this { public: using GatewayAccess = std::function)>; using MimeDetection = std::function< std::string(std::string, std::string_view, std::string const&)>; - explicit Orchestrator(std::shared_ptr requestor, - std::shared_ptr = {}); void build_response(std::shared_ptr); bool add_node(std::string key, ipld::NodePtr); bool has_key(std::string const& k) const; std::size_t Stored() const { return dags_.size(); } + explicit Partition(std::shared_ptr requestor, + std::shared_ptr); + private: flat_map dags_; std::shared_ptr api_; diff --git a/library/src/ipfs_client/context_api.cc b/library/src/ipfs_client/context_api.cc index 16385cb7..3963d3df 100644 --- a/library/src/ipfs_client/context_api.cc +++ b/library/src/ipfs_client/context_api.cc @@ -8,6 +8,9 @@ #include "ipfs_client/ctx/null_dns_txt_lookup.h" #include "ipfs_client/ctx/null_http_provider.h" #include "ipfs_client/ctx/transitory_gateway_config.h" +#include "ipfs_client/gw/default_requestor.h" + +#include "ipfs_client/partition.h" #include "ipfs_client/web_util.h" #include "log_macros.h" @@ -67,6 +70,14 @@ std::string Self::UnescapeUrlComponent(std::string_view url_comp) { return unescape_(url_comp); } +auto Self::partition(std::string key) -> std::shared_ptr { + auto& part = partitions_[key]; + if (!part) { + LOG(INFO) << "New partition for key '" << key << "'."; + part = std::make_shared(requestor(), shared_from_this()); + } + return part; +} auto Self::http() -> ctx::HttpApi& { if (!http_api_) { http_api_ = std::make_unique(); @@ -108,6 +119,14 @@ auto Self::cbor() -> ctx::CborParser& { DCHECK(cbor_parser_); return *cbor_parser_; } +auto Self::requestor() -> std::shared_ptr { + if (!rtor_) { + LOG(INFO) << "No gateway requestor provided. Will use default with no " + "caching or custom behavior."; + rtor_ = gw::default_requestor({}, shared_from_this()); + } + return rtor_; +} Self& Self::with(std::unique_ptr p) { json_parser_ = std::move(p); return *this; @@ -145,3 +164,7 @@ Self& Self::with(std::unique_ptr p) { gateway_config_ = std::move(p); return *this; } +Self& Self::with(std::shared_ptr p) { + rtor_ = p; + return *this; +} diff --git a/library/src/ipfs_client/gw/dnslink_requestor.cc b/library/src/ipfs_client/gw/dnslink_requestor.cc index d7866f12..ada282ad 100644 --- a/library/src/ipfs_client/gw/dnslink_requestor.cc +++ b/library/src/ipfs_client/gw/dnslink_requestor.cc @@ -7,7 +7,7 @@ #include #include -#include +#include #include "log_macros.h" diff --git a/library/src/ipfs_client/gw/dnslink_requestor_unittest.cc b/library/src/ipfs_client/gw/dnslink_requestor_unittest.cc index 740a609b..e40129f5 100644 --- a/library/src/ipfs_client/gw/dnslink_requestor_unittest.cc +++ b/library/src/ipfs_client/gw/dnslink_requestor_unittest.cc @@ -4,7 +4,7 @@ #include #include -#include +#include using T = ig::DnsLinkRequestor; @@ -15,9 +15,13 @@ struct DnslinkRequestorTest : public testing::Test { std::shared_ptr r_ = ig::GatewayRequest::fromIpfsPath(i::SlashDelimited{"/ipns/not_a_cid"}); ig::Requestor& t() { return *t_; } - std::shared_ptr orc_ = std::make_shared( - std::make_shared()); - DnslinkRequestorTest() { r_->orchestrator(orc_); } + std::shared_ptr rtor_; + std::shared_ptr orc_; + DnslinkRequestorTest() { + rtor_ = std::make_shared(); + orc_ = api->with(rtor_).partition({}); + r_->orchestrator(orc_); + } }; } // namespace diff --git a/library/src/ipfs_client/gw/gateway_request.cc b/library/src/ipfs_client/gw/gateway_request.cc index 76a55215..dc185ec6 100644 --- a/library/src/ipfs_client/gw/gateway_request.cc +++ b/library/src/ipfs_client/gw/gateway_request.cc @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -364,7 +364,7 @@ bool Self::RespondSuccessfully(std::string_view bytes, void Self::Hook(std::function f) { bytes_received_hooks.push_back(f); } -void Self::orchestrator(std::shared_ptr const& orc) { +void Self::orchestrator(std::shared_ptr const& orc) { orchestrator_ = orc; } bool Self::PartiallyRedundant() const { diff --git a/library/src/ipfs_client/gw/gateway_request_unittest.cc b/library/src/ipfs_client/gw/gateway_request_unittest.cc index a10fa1dd..0f11dfcd 100644 --- a/library/src/ipfs_client/gw/gateway_request_unittest.cc +++ b/library/src/ipfs_client/gw/gateway_request_unittest.cc @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -53,9 +53,9 @@ struct GatewayRequestTest : public testing::Test { T t_; std::shared_ptr api = std::make_shared(); std::shared_ptr rtor = std::make_shared(); - std::shared_ptr orc = - std::make_shared(rtor, api); + std::shared_ptr orc; GatewayRequestTest() { + orc = api->with(rtor).partition({}); t_.orchestrator(orc); t_.main_param = "main"; } diff --git a/library/src/ipfs_client/gw/inline_request_handler.cc b/library/src/ipfs_client/gw/inline_request_handler.cc index b482bfc8..c40ca738 100644 --- a/library/src/ipfs_client/gw/inline_request_handler.cc +++ b/library/src/ipfs_client/gw/inline_request_handler.cc @@ -2,7 +2,7 @@ #include #include -#include +#include #include "log_macros.h" diff --git a/library/src/ipfs_client/gw/inline_request_handler_unittest.cc b/library/src/ipfs_client/gw/inline_request_handler_unittest.cc index c221f775..55a4e8e6 100644 --- a/library/src/ipfs_client/gw/inline_request_handler_unittest.cc +++ b/library/src/ipfs_client/gw/inline_request_handler_unittest.cc @@ -1,10 +1,10 @@ #include -#include +#include #include #include -#include +#include namespace i = ipfs; namespace ig = i::gw; @@ -15,9 +15,9 @@ using ipfs::Cid; TEST(InlineRequestHanlder, bluesky) { T t; - - auto orc = std::make_shared( - std::make_shared()); + auto api = std::make_shared(); + auto rtor = std::make_shared(); + auto orc = api->with(rtor).partition({}); auto r = std::make_shared(); r->type = ig::Type::Identity; r->orchestrator(orc); diff --git a/library/src/ipfs_client/gw/requestor.cc b/library/src/ipfs_client/gw/requestor.cc index e5b6dfe0..6302dc2e 100644 --- a/library/src/ipfs_client/gw/requestor.cc +++ b/library/src/ipfs_client/gw/requestor.cc @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/library/src/ipfs_client/opinionated_context.cc b/library/src/ipfs_client/opinionated_context.cc index 865547aa..18097d3a 100644 --- a/library/src/ipfs_client/opinionated_context.cc +++ b/library/src/ipfs_client/opinionated_context.cc @@ -5,7 +5,8 @@ #if HAS_OPINIONATED_CONTEXT auto ipfs::start_default(boost::asio::io_context& io) - -> std::pair, std::shared_ptr> { + -> std::shared_ptr { + // -> std::pair, std::shared_ptr> { auto api = std::make_shared(); using SKT = crypto::SigningKeyType; api->with(std::make_unique(io)) @@ -15,8 +16,10 @@ auto ipfs::start_default(boost::asio::io_context& io) .with(SKT::Ed25519, std::make_unique( EVP_PKEY_ED25519)); auto rtor = gw::default_requestor({}, api); - auto orc = std::make_shared(rtor, api); - return {api, orc}; + api->with(rtor); + // auto orc = std::make_shared(rtor, api); + // return {api, orc}; + return api; } #endif // HAS_OPINIONATED_CONTEXT diff --git a/library/src/ipfs_client/orchestrator.cc b/library/src/ipfs_client/partition.cc similarity index 95% rename from library/src/ipfs_client/orchestrator.cc rename to library/src/ipfs_client/partition.cc index 66bc4b43..1478357f 100644 --- a/library/src/ipfs_client/orchestrator.cc +++ b/library/src/ipfs_client/partition.cc @@ -1,4 +1,4 @@ -#include "ipfs_client/orchestrator.h" +#include "ipfs_client/partition.h" #include #include @@ -10,11 +10,10 @@ using namespace std::literals; -using Self = ipfs::Orchestrator; +using Self = ipfs::Partition; -Self::Orchestrator(std::shared_ptr requestor, - std::shared_ptr api) - // : gw_requestor_{ga}, api_{api}, requestor_{requestor} { +Self::Partition(std::shared_ptr requestor, + std::shared_ptr api) : api_{api}, requestor_{requestor} { DCHECK(requestor); } diff --git a/library/src/ipfs_client/orchestrator_unittest.cc b/library/src/ipfs_client/partition_unittest.cc similarity index 98% rename from library/src/ipfs_client/orchestrator_unittest.cc rename to library/src/ipfs_client/partition_unittest.cc index 89d3875b..967e5a4f 100644 --- a/library/src/ipfs_client/orchestrator_unittest.cc +++ b/library/src/ipfs_client/partition_unittest.cc @@ -1,4 +1,4 @@ -#include "ipfs_client/orchestrator.h" +#include "ipfs_client/partition.h" #include @@ -158,7 +158,7 @@ struct TestRequestor final : public ig::Requestor { }; struct OrchestratingRealData : public ::testing::Test { std::shared_ptr api_ = std::make_shared(); - std::shared_ptr orc_; + std::shared_ptr orc_; OrchestratingRealData() { i::log::SetLevel(i::log::Level::Off); auto f = [](auto) {}; @@ -166,8 +166,8 @@ struct OrchestratingRealData : public ::testing::Test { resp_.status_ = 0; resp_.mime_ = "uninit - no mime provided"; resp_.location_ = "uninit"; - orc_ = std::make_shared(std::make_shared(), - api_); + api_->with(std::make_shared()); + orc_ = api_->partition({}); } i::Response resp_; void dorequest(std::string_view ipfs_path) {