Skip to content

Creating bidder

Vladimir Venediktov edited this page Jun 4, 2017 · 13 revisions

Creating bidder is a 5 minute task

using DSLT = DSL::GenericDSL<> ;
exchange_handler<DSLT> openrtb_handler(std::chrono::milliseconds(50))
    .logger([](const std::string &data) {
        LOG(debug) << "request data :" << data ;
    })
    .error_logger([](const std::string &data) {
        LOG(debug) << "request error :" << data ;
    })
    .auction_async([](const auto &request) {
        //respond with no bid
        return  BidResponse();
    });

vanilla-rtb is using DSL mappers for conversion from json request to C++ structures as long as your custom DSL defines 2 types

DSL::deserialized_type
DSL::serialized_type

and 2 functions

 1. template<typename string_view_type>
 deserialized_type extract_request(const string_view_type & bid_request) 

 2. jsonv::value create_response(const serialized_type & bid_response)

vanilla-rtb works with any version of openRTB , so for example if you want to use our stack with both openRTB 2.5 and also continue support to openRTB 2.2 we provided, create your own in the new namespace DSL::v25::CustomDSL and add

exchange handler to the same executable by providing different CRUD endpoint or run it in a separate process listening on a different port.

using DSLT = DSL::GenericDSL<> ;
exchange_handler<DSLT> openrtb_handler(std::chrono::milliseconds(config.data().handler_timeout_v1));
    openrtb_handler    
    .logger([](const std::string &data) {
        LOG(debug) << "request v2.2 data:" << data ;
    })
    .error_logger([](const std::string &data) {
        LOG(debug) << "request v2.2 error: " << data ;
    })
    .auction_async([](const auto &request) {
        return  BidResponse();
});

using DSLT25 = DSL::v25::CustomDSL<> ;
exchange_handler<DSLT25> openrtb_handler_25(std::chrono::milliseconds(40));
    openrtb_handler_25
    .logger([](const std::string &data) {
        LOG(debug) << "request v2.5 data:" << data ;
    })
    .error_logger([](const std::string &data) {
        LOG(debug) << "request v2.5 error: " << data ;
    })
    .auction_async([](const auto &request) {
        return  BidResponse();
});

Create CRUD handlers for your 2.2 and 2.5 exchange handlers

 restful_dispatcher_t dispatcher(ep.root) ;
    dispatcher.crud_match(std::string("/openrtb_handler/auction/"))
              .post([&](http::server::reply & r, const http::crud::crud_match<boost::cmatch> & match) {
                  openrtb_handler.handle_post(r,match);
              });
    dispatcher.crud_match(std::string("/openrtb_handler/v25/auction/"))
              .post([&](http::server::reply & r, const http::crud::crud_match<boost::cmatch> & match) {
                  openrtb_handler_25.handle_post(r,match);
});

To make your stack outperform you should use zero-copy , zero-memory allocation , so to achieve that we provided way to do that by allowing you to specify string_view structure used for BidRequest strings, so when string_view passed to DSL parsers it will not allocate memory on the heap or copy bytes from original incoming json data.

 using DSLT = DSL::GenericDSL<jsonv::string_view> ; 

The string_view is a string structure having no ownership of the data and it can be passed to functions by copy as it represents begin address of a string and the size of string. Few things to remember though , because it does not own memory the actual string it points to has to be valid for the life cycle of your string_view.