diff --git a/examples/bidder/response_builder.hpp b/examples/bidder/bidder.hpp similarity index 81% rename from examples/bidder/response_builder.hpp rename to examples/bidder/bidder.hpp index a866792..f4dfb27 100644 --- a/examples/bidder/response_builder.hpp +++ b/examples/bidder/bidder.hpp @@ -12,24 +12,23 @@ #include #include "rtb/common/perf_timer.hpp" #include "bidder_selector.hpp" -#include "examples/multiexchange/user_info.hpp" namespace vanilla { - template - class ResponseBuilder { - using BidRequest = openrtb::BidRequest; - using BidResponse = openrtb::BidResponse; - using Impression = openrtb::Impression; - using SeatBid = openrtb::SeatBid; - using Bid = openrtb::Bid; + template + class Bidder { + using BidRequest = typename DSL::deserialized_type; + using BidResponse = typename DSL::serialized_type; + using Impression = typename DSL::Impression; + using SeatBid = typename DSL::SeatBid; + using Bid = typename DSL::Bid; public: - ResponseBuilder(BidderCaches<> &caches) : + Bidder(BidderCaches &caches) : selector{caches}, uuid_generator{} { } - - const BidResponse& build(const vanilla::VanillaRequest &vanilla_request) { + template + const BidResponse& bid(const Request &vanilla_request) { response.clear(); const BidRequest &request = vanilla_request.bid_request; for (auto &imp : request.imp) { diff --git a/examples/bidder/config.hpp b/examples/bidder/config.hpp index 1b4ca03..2383405 100644 --- a/examples/bidder/config.hpp +++ b/examples/bidder/config.hpp @@ -20,6 +20,8 @@ struct bidder_config_data { std::string geo_campaign_source; std::string campaign_data_source; std::string campaign_data_ipc_name; + std::string key_value_host; + int key_value_port; int timeout; unsigned int concurrency; short port; @@ -34,6 +36,7 @@ struct bidder_config_data { geo_source{}, geo_ipc_name{}, geo_campaign_ipc_name{}, geo_campaign_source{}, campaign_data_source{}, campaign_data_ipc_name{}, + key_value_host{}, key_value_port{}, timeout{}, concurrency{}, port{}, host{}, root{}, num_of_bidders{} {} diff --git a/examples/bidder/decision_exchange.hpp b/examples/bidder/decision_exchange.hpp new file mode 100644 index 0000000..b6c4a84 --- /dev/null +++ b/examples/bidder/decision_exchange.hpp @@ -0,0 +1,41 @@ +/* + * File: decision_exchange.hpp + * Author: arseny.bushev@gmail.com + * + * Created on 9 мая 2017 г., 17:12 + */ + +#ifndef DECISION_EXCHANGE_HPP +#define DECISION_EXCHANGE_HPP + +#include + +namespace vanilla { + namespace decision_exchange { + template + class decision_exchange { + static constexpr int tree_depth{static_cast(SIZE)}; + using decision_manager = vanilla::common::decision_tree_manager; + public: + using decision_tree_type = typename decision_manager::decision_tree_type; + using decision_action = vanilla::common::decision_action; + + template + decision_exchange(T &&decision_tree): + decision_tree{decision_tree}, manager{this->decision_tree} + {} + template + void exchange(TArgs && ...args) { + //decision_manager manager(decision_tree); + manager.execute(std::forward(args)...); + } + private: + decision_tree_type decision_tree; + decision_manager manager; + + }; + } +} + +#endif /* DECISION_EXCHANGE_HPP */ + diff --git a/examples/bidder/http_bidder_test.cpp b/examples/bidder/http_bidder_test.cpp index 9dfd078..c61a8f8 100644 --- a/examples/bidder/http_bidder_test.cpp +++ b/examples/bidder/http_bidder_test.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -23,11 +24,15 @@ #include "examples/datacache/geo_entity.hpp" #include "examples/datacache/city_country_entity.hpp" #include "examples/datacache/ad_entity.hpp" +#include "bidder.hpp" #include "rtb/common/perf_timer.hpp" #include "config.hpp" #include "serialization.hpp" #include "bidder_selector.hpp" +#include "decision_exchange.hpp" +#include "rtb/client/empty_key_value_client.hpp" +#include "examples/multiexchange/user_info.hpp" extern void init_framework_logging(const std::string &) ; @@ -42,13 +47,16 @@ auto random_pick(int max) { return dis(gen); } +namespace bidder_decision_codes { + enum {EXIT=-1, USER_DATA=0, NO_BID, AUCTION_ASYNC, SIZE}; +} int main(int argc, char *argv[]) { using namespace std::placeholders; using namespace vanilla::exchange; using namespace std::chrono_literals; using restful_dispatcher_t = http::crud::crud_dispatcher ; - using BidRequest = openrtb::BidRequest; + //using BidRequest = openrtb::BidRequest; using BidResponse = openrtb::BidResponse; using SeatBid = openrtb::SeatBid; using Bid = openrtb::Bid; @@ -71,6 +79,8 @@ int main(int argc, char *argv[]) { ("bidder.geo_campaign_source", boost::program_options::value(&d.geo_campaign_source)->default_value("data/geo_campaign"), "geo_campaign_source file name") ("bidder.campaign_data_ipc_name", boost::program_options::value(&d.campaign_data_ipc_name)->default_value("vanilla-campaign-data-ipc"), "campaign data ipc name") ("bidder.campaign_data_source", boost::program_options::value(&d.campaign_data_source)->default_value("data/campaign_data"), "campaign_data_source file name") + ("bidder.key_value_host", boost::program_options::value(&d.key_value_host)->default_value("0.0.0.0"), "key value storage host") + ("bidder.key_value_port", boost::program_options::value(&d.key_value_port)->default_value(0), "key value storage port") ; }); @@ -95,7 +105,39 @@ int main(int argc, char *argv[]) { LOG(error) << e.what(); return 0; } - exchange_handler> bid_handler(std::chrono::milliseconds(config.data().timeout)); + + using bid_handler_type = exchange_handler, vanilla::VanillaRequest>; + using BidRequest = bid_handler_type::auction_request_type; + using decision_exchange_type = vanilla::decision_exchange::decision_exchange; + + bid_handler_type bid_handler(std::chrono::milliseconds(config.data().timeout)); + + auto request_user_data_f = [&bid_handler, &config](http::server::reply &reply, BidRequest & bid_request) -> bool { + using kv_type = vanilla::client::empty_key_value_client; + thread_local kv_type kv_client; + bool is_matched_user = bid_request.user_info.user_id.length(); + if (!is_matched_user) { + return true; // bid unmatched + } + if (!kv_client.connected()) { + kv_client.connect(config.data().key_value_host, config.data().key_value_port); + } + kv_client.request(bid_request.user_info.user_id, bid_request.user_info.user_data); + return true; + }; + auto no_bid_f = [&bid_handler, &config](http::server::reply &reply, BidRequest & bid_request) -> bool { + reply << http::server::reply::flush(""); + }; + auto auction_async_f = [&bid_handler](http::server::reply &reply, BidRequest & bid_request) -> bool { + return bid_handler.handle_auction_async(reply, bid_request); + }; + const decision_exchange_type::decision_tree_type decision_tree = {{ + {bidder_decision_codes::USER_DATA, {request_user_data_f, bidder_decision_codes::AUCTION_ASYNC, bidder_decision_codes::NO_BID}}, + {bidder_decision_codes::NO_BID, {no_bid_f, bidder_decision_codes::EXIT, bidder_decision_codes::EXIT}}, + {bidder_decision_codes::AUCTION_ASYNC, {auction_async_f, bidder_decision_codes::EXIT, bidder_decision_codes::EXIT}} + }}; + decision_exchange_type decision_exchange(decision_tree); + bid_handler .logger([](const std::string &data) { //LOG(debug) << "bid request=" << data ; @@ -103,41 +145,14 @@ int main(int argc, char *argv[]) { .error_logger([](const std::string &data) { LOG(debug) << "bid request error " << data ; }) - .auction_async([&](const BidRequest &request) { - - thread_local vanilla::BidderSelector<> selector(caches); - BidResponse response; - for(auto &imp : request.imp) { - if(auto ad = selector.select(request, imp)) { - boost::uuids::uuid bidid = uuid_generator(); - response.bidid = boost::uuids::to_string(bidid); - if (request.cur.size()) { - response.cur = request.cur[0]; - } else if (imp.bidfloorcur.length()) { - response.cur = imp.bidfloorcur; // Just return back - } - Bid bid; - bid.id = boost::uuids::to_string(bidid); // TODO check documentation - // Is it the same as response.bidid? - // Wrong filling type - bid.impid = imp.id; - bid.price = ad->max_bid_micros / 1000000.0; // Not micros? - bid.w = ad->width; - bid.h = ad->height; - bid.adm = ad->code; - bid.adid = ad->ad_id; - if (response.seatbid.size() == 0) { - SeatBid seatbid; - seatbid.bid.push_back(bid); - response.seatbid.push_back(seatbid); - } else { - response.seatbid.back().bid.push_back(bid); - } - } - } - return response; - }); + thread_local vanilla::Bidder, BidderConfig> bidder(caches); + return bidder.bid(request); + }) + .decision([&decision_exchange](auto && ... args) { + decision_exchange.exchange(args...); + }) + ; connection_endpoint ep {std::make_tuple(config.data().host, boost::lexical_cast(config.data().port), config.data().root)}; diff --git a/examples/bidder/multi_bidder.cpp b/examples/bidder/multi_bidder.cpp index f3c3b89..a27e69e 100644 --- a/examples/bidder/multi_bidder.cpp +++ b/examples/bidder/multi_bidder.cpp @@ -36,7 +36,7 @@ #else #include #endif -#include "response_builder.hpp" +#include "bidder.hpp" #include "examples/multiexchange/user_info.hpp" #include "rtb/core/core.hpp" @@ -46,10 +46,10 @@ using RtbBidderCaches = vanilla::BidderCaches; void run(short port, RtbBidderCaches &bidder_caches) { using namespace vanilla::messaging; - vanilla::ResponseBuilder response_builder(bidder_caches); - communicator().inbound(port).process([&response_builder](auto endpoint, vanilla::VanillaRequest vanilla_request) { + vanilla::Bidder, BidderConfig> bidder(bidder_caches); + communicator().inbound(port).process([&bidder](auto endpoint, vanilla::VanillaRequest vanilla_request) { LOG(debug) << "Request from user " << vanilla_request.user_info.user_id; - return response_builder.build(vanilla_request); + return bidder.bid(vanilla_request); }).dispatch(); } diff --git a/examples/multiexchange/multi_exchange_handler.cpp b/examples/multiexchange/multi_exchange_handler.cpp index 38dae53..ae94b31 100644 --- a/examples/multiexchange/multi_exchange_handler.cpp +++ b/examples/multiexchange/multi_exchange_handler.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) { if(request.user) { vanilla_request.user_info.user_id = request.user.get().buyeruid; } - vanilla::multibidder_communicator<> communicator( + vanilla::multibidder_communicator > communicator( config.data().bidders_port, std::chrono::milliseconds(config.data().bidders_response_timeout) ); diff --git a/examples/multiexchange/user_info.hpp b/examples/multiexchange/user_info.hpp index 8d83d34..796d9a6 100644 --- a/examples/multiexchange/user_info.hpp +++ b/examples/multiexchange/user_info.hpp @@ -10,6 +10,7 @@ #include #include "rtb/core/bid_request.hpp" +#include "rtb/DSL/generic_dsl.hpp" namespace vanilla { struct UserInfo { @@ -17,7 +18,7 @@ namespace vanilla { std::string user_data{}; }; - using VanillaRequest = vanilla::BidRequest; + using VanillaRequest = vanilla::BidRequest, vanilla::UserInfo>; } diff --git a/rtb/DSL/generic_dsl.hpp b/rtb/DSL/generic_dsl.hpp index fdf4552..bd4f06d 100644 --- a/rtb/DSL/generic_dsl.hpp +++ b/rtb/DSL/generic_dsl.hpp @@ -16,6 +16,9 @@ * GNU General Public License for more details. */ +#ifndef RTB_DSL_HPP +#define RTB_DSL_HPP + #include "core/openrtb.hpp" #include "encoders.hpp" #include @@ -34,15 +37,19 @@ namespace DSL { //BidRequest using Banner = openrtb::Banner; using AdPosition = openrtb::AdPosition; + public: using Impression = openrtb::Impression; + private: using User = openrtb::User; using Geo = openrtb::Geo; using Site = openrtb::Site; using Publisher = openrtb::Publisher; using BidRequest = openrtb::BidRequest; //BidResponse + public: using Bid = openrtb::Bid; using SeatBid = openrtb::SeatBid; + private: using NoBidReason = openrtb::NoBidReason; using CreativeAttribute= openrtb::CreativeAttribute; using BidResponse = openrtb::BidResponse; @@ -194,3 +201,5 @@ namespace DSL { }; } //namespace + +#endif \ No newline at end of file diff --git a/rtb/common/decision_tree.hpp b/rtb/common/decision_tree.hpp index 692a80b..a209de3 100644 --- a/rtb/common/decision_tree.hpp +++ b/rtb/common/decision_tree.hpp @@ -42,70 +42,72 @@ tm.execute(); **/ -namespace vanilla { namespace common { - -struct decision_action { - using function_type = std::function; - struct node_S { - function_type f; - int next_true; - int next_false; - }; - using node_type = node_S; - enum CODES { EXIT=-1 , CONTINUE=0 }; - template int get() const ; - int operator()() const; - - uint32_t row_num; - node_type node; -}; - -template<> -inline int decision_action::get() const { - return node.next_true; -} - -template<> -inline int decision_action::get() const { - return node.next_false; -} +namespace vanilla { + namespace common { + template + struct decision_action { + using function_type = std::function; + + struct node_S { + function_type f; + int next_true; + int next_false; + }; + + using node_type = node_S; + + enum CODES { + EXIT = -1, CONTINUE = 0 + }; + int get(bool res) const { + return res ? node.next_true : node.next_false; + } + + template + inline int operator()(TArgs && ...targs) const { + return get(node.f(std::forward(targs)...)); + } + + uint32_t row_num{0}; + node_type node; + }; + + + template + using decision_tree = std::array, N>; + + template + struct decision_tree_manager { + using params_decision_action = decision_action; + using decision_tree_type = decision_tree; + decision_tree_manager(decision_tree_type && tree) : tree{std::move(tree)} + { + } + decision_tree_manager(const decision_tree_type & tree) : tree{tree} + { + } + + template + void execute(TArgs && ...args) const noexcept(false) { + next(tree.at(0), std::forward(args)...); + } + + template + void next(const params_decision_action &action_now, TArgs && ...args) const noexcept(false) { + int next_node_idx = action_now(std::forward(args)...); //executes and produces action_next + if (next_node_idx == params_decision_action::CONTINUE) { + next(tree.at(action_now.row_num + 1), std::forward(args)...); + } + else if (next_node_idx != params_decision_action::EXIT) { + next(tree.at(next_node_idx), std::forward(args)...); + } + } + private: + decision_tree_type tree; + }; -inline int decision_action::operator()() const { - if (node.f()) { - return get(); - } else { - return get(); } } - -template -using decision_tree = std::array; - -template -struct decision_tree_manager { - decision_tree_manager(decision_tree && tree) : tree{std::move(tree)} - {} - decision_tree_manager(const decision_tree & tree) : tree{tree} - {} - - void execute() { - next(tree.at(0)); - } - decision_action next(const decision_action &action_now) { - int next_node_idx = action_now(); //executes and produces action_next - if ( next_node_idx == decision_action::CONTINUE ) { - next(tree.at(action_now.row_num+1)); - } - if ( next_node_idx != decision_action::EXIT ) { - next(tree.at(next_node_idx)); - } - } -private: - decision_tree tree; -}; - -}} - #endif /* VANILLA_COMMON_DECISION_TREE_HPP */ diff --git a/rtb/core/bid_request.hpp b/rtb/core/bid_request.hpp index 96e24d0..c5e80ac 100644 --- a/rtb/core/bid_request.hpp +++ b/rtb/core/bid_request.hpp @@ -11,10 +11,20 @@ #include "openrtb.hpp" namespace vanilla { - template + template struct BidRequest { - openrtb::BidRequest bid_request; + using request_type = typename DSL::deserialized_type; + request_type bid_request; UserInfo user_info; + + BidRequest &operator=(const request_type &req) { + bid_request = req; + return *this; + } + + const request_type& request() const { + return bid_request; + } }; } diff --git a/rtb/core/openrtb.hpp b/rtb/core/openrtb.hpp index 211e1b5..7479425 100644 --- a/rtb/core/openrtb.hpp +++ b/rtb/core/openrtb.hpp @@ -378,6 +378,8 @@ namespace openrtb { template struct BidRequest { + using request_type = BidRequest; + ~BidRequest() {} T id; ///< Bid request ID std::vector> imp; ///< List of impressions @@ -395,6 +397,10 @@ namespace openrtb { boost::optional regs; ///< Regulations Object list (OpenRTB 2.2) T ext; //jsonv::value ext; ///< Protocol extensions T unparseable; //jsonv::value unparseable; ///< Unparseable fields get put here + + const request_type& request() const { + return *this; + } }; @@ -430,6 +436,7 @@ namespace openrtb { template struct BidResponse { + using data_type = T; T id; std::vector> seatbid; T bidid; diff --git a/rtb/exchange/exchange_handler.hpp b/rtb/exchange/exchange_handler.hpp index 16b1e00..0259a8e 100644 --- a/rtb/exchange/exchange_handler.hpp +++ b/rtb/exchange/exchange_handler.hpp @@ -27,115 +27,157 @@ #include #include "CRUD/service/reply.hpp" #include "CRUD/handlers/crud_matcher.hpp" +#include +#include + +namespace vanilla { + namespace exchange { + + thread_local boost::asio::io_service io_service; + thread_local boost::asio::deadline_timer timer{io_service}; + + + template + class exchange_handler { + //using auction_request_type = decltype(DSL().extract_request(std::string())); + public: + using auction_request_type = Request; + using auction_response_type = typename DSL::serialized_type; + using wire_response_type = decltype(DSL().create_response(auction_response_type())); + using parse_error_type = typename DSL::parse_error_type; + using auction_handler_type = std::function; + using auction_async_handler_type = auction_handler_type; + using log_handler_type = std::function; + using error_log_handler_type = std::function; + using self_type = exchange_handler; +// using decision_params_type = std::tuple; + private: + using decision_handler_type = std::function; + + DSL parser; + auction_handler_type auction_handler; + auction_async_handler_type auction_async_handler; + log_handler_type log_handler; + error_log_handler_type error_log_handler; + decision_handler_type decision_handler; + + const std::chrono::milliseconds tmax; + + public: + + exchange_handler(const std::chrono::milliseconds &tmax) : + parser{}, auction_handler{}, log_handler{}, tmax{tmax} + { + } -namespace vanilla { namespace exchange { - -thread_local boost::asio::io_service io_service; -thread_local boost::asio::deadline_timer timer{io_service}; + self_type & auction(const auction_handler_type &handler) { + auction_handler = handler; + return *this; + } -template -class exchange_handler { + self_type & auction_async(const auction_async_handler_type &handler) { + auction_async_handler = handler; + return *this; + } -using auction_request_type = decltype(DSL().extract_request(std::string())); -using auction_response_type = typename DSL::serialized_type; -using wire_response_type = decltype(DSL().create_response(auction_response_type())); -using parse_error_type = typename DSL::parse_error_type; -using auction_handler_type = std::function; -using auction_async_handler_type = auction_handler_type; -using log_handler_type = std::function; -using error_log_handler_type = std::function; -using self_type = exchange_handler ; + self_type & logger(const log_handler_type &handler) { + log_handler = handler; + return *this; + } -DSL parser; -auction_handler_type auction_handler; -auction_async_handler_type auction_async_handler; -log_handler_type log_handler; -error_log_handler_type error_log_handler; -const std::chrono::milliseconds tmax; + self_type & error_logger(const error_log_handler_type &handler) { + error_log_handler = handler; + return *this; + } + + self_type & decision(const decision_handler_type &handler) { + decision_handler = handler; + return *this; + } -public: - exchange_handler(const std::chrono::milliseconds &tmax) : - parser{}, auction_handler{}, log_handler{}, tmax{tmax} - {} + bool handle_auction(http::server::reply& r, const auction_request_type &bid_request) { + if (auction_handler) { + std::chrono::milliseconds timeout{bid_request.request().tmax ? bid_request.request().tmax : tmax.count()}; + auto future = std::async(std::launch::async, [&]() { + auto auction_response = auction_handler(bid_request); + auto wire_response = parser.create_response(auction_response); + return wire_response; + }); + if (future.wait_for(timeout) == std::future_status::ready) { + r << to_string(future.get()) << http::server::reply::flush(""); + } else { + r << http::server::reply::flush(""); + } + return true; + } + return false; + } + bool handle_auction_async(http::server::reply& r, const auction_request_type &bid_request) { + if (auction_async_handler) { + std::chrono::milliseconds timeout{bid_request.request().tmax ? bid_request.request().tmax : tmax.count()}; + boost::optional wire_response; + auto submit_async = [&]() { + auto auction_response = auction_async_handler(bid_request); + wire_response = parser.create_response(auction_response); + io_service.stop(); + }; + io_service.post(submit_async); + timer.expires_from_now(boost::posix_time::milliseconds(timeout.count())); + timer.async_wait([](const boost::system::error_code & error) { + if (error != boost::asio::error::operation_aborted) { + io_service.stop(); + } + }); + io_service.reset(); + io_service.run(); + if (wire_response && timer.expires_from_now().total_milliseconds() > 0) { + r << to_string(*wire_response) << http::server::reply::flush(""); + } else { + r << http::server::reply::flush(""); + } + return true; + } + return false; + } + private: - self_type & auction(const auction_handler_type &handler) { - auction_handler = handler; - return *this; - } + template + bool handle_post_common(http::server::reply & r, const http::crud::crud_match &match, auction_request_type &bid_request) { + if (log_handler) { + log_handler(match.data); + } + try { + bid_request = parser.extract_request(match.data); + } catch (const parse_error_type &err) { + if (error_log_handler) { + error_log_handler(to_string(err)); + } + r << http::server::reply::flush(""); + return false; + } + return true; + } + public: - self_type & auction_async(const auction_async_handler_type &handler) { - auction_async_handler = handler; - return *this; - } + template + void handle_post(http::server::reply & r, const http::crud::crud_match & match) { + auction_request_type bid_request; + if (!handle_post_common(r, match, bid_request)) { + return; + } - self_type & logger(const log_handler_type &handler) { - log_handler = handler; - return *this; - } - - self_type & error_logger(const error_log_handler_type &handler) { - error_log_handler = handler; - return *this; - } - - template - void handle_post(http::server::reply & r, const http::crud::crud_match & match) { - if ( log_handler ) { - log_handler(match.data); - } - auction_request_type bid_request; - try { - bid_request = parser.extract_request(match.data) ; - } - catch (const parse_error_type &err) { - if (error_log_handler) { - error_log_handler(to_string(err)); - } - r << http::server::reply::flush(""); - return; - } - - if ( auction_handler ) { - std::chrono::milliseconds timeout{bid_request.tmax ? bid_request.tmax : tmax.count()}; - auto future = std::async(std::launch::async, [&](){ - auto auction_response = auction_handler(bid_request) ; - auto wire_response = parser.create_response(auction_response) ; - return wire_response; - }); - if ( future.wait_for(timeout) == std::future_status::ready) { - r << to_string(future.get()) << http::server::reply::flush(""); - } else { - r << http::server::reply::flush(""); - } - } - - if ( auction_async_handler ) { - std::chrono::milliseconds timeout{bid_request.tmax ? bid_request.tmax : tmax.count()}; - boost::optional wire_response; - auto submit_async = [&]() { - auto auction_response = auction_async_handler(bid_request); - wire_response = parser.create_response(auction_response); - io_service.stop(); - }; - io_service.post(submit_async); - timer.expires_from_now(boost::posix_time::milliseconds(timeout.count())); - timer.async_wait([](const boost::system::error_code& error) { - if (error != boost::asio::error::operation_aborted) { - io_service.stop(); + if(decision_handler) { + decision_handler(r, bid_request); + } else if (handle_auction_async(r, bid_request)) { + ; + } + else if (handle_auction(r, bid_request)) { + ; } - }); - io_service.reset(); - io_service.run(); - if ( wire_response && timer.expires_from_now().total_milliseconds() > 0 ) { - r << to_string(*wire_response) << http::server::reply::flush(""); - } else { - r << http::server::reply::flush(""); } - } - } - -}; + }; -}} + } +} diff --git a/rtb/exchange/multibidder_communicator.hpp b/rtb/exchange/multibidder_communicator.hpp index 40b6701..b42a3b0 100644 --- a/rtb/exchange/multibidder_communicator.hpp +++ b/rtb/exchange/multibidder_communicator.hpp @@ -27,21 +27,24 @@ namespace vanilla { template < + typename DSL, typename Duration = std::chrono::milliseconds, typename DeliveryType = vanilla::messaging::broadcast > class multibidder_communicator { + private: + using serialized_type = typename DSL::serialized_type; public: multibidder_communicator(uint16_t bidders_port, Duration response_timeout) : response_timeout(response_timeout) { communicator.outbound(bidders_port); } - template - void process(const vanilla::VanillaRequest &vanilla_request, multibidder_collector &collector) { + template + void process(const Request &request, multibidder_collector &collector) { communicator - .distribute(vanilla_request) - .template collect>(response_timeout, [&collector](openrtb::BidResponse bid, auto done) { //move ctored by collect() + .distribute(request) + .template collect(response_timeout, [&collector](serialized_type bid, auto done) { //move ctored by collect() collector.add(std::move(bid)); if (collector.done()) { done(); diff --git a/rtb/messaging/serialization.hpp b/rtb/messaging/serialization.hpp index 30bd119..f187c39 100644 --- a/rtb/messaging/serialization.hpp +++ b/rtb/messaging/serialization.hpp @@ -206,8 +206,8 @@ namespace boost { //ar & value.ext //TODO: for this we need template load() and save() } - template - void serialize(Archive & ar, vanilla::BidRequest & value, const unsigned int version) { + template + void serialize(Archive & ar, vanilla::BidRequest & value, const unsigned int version) { ar & value.bid_request; ar & value.user_info; }