Skip to content

Creating bidder

Vladimir Venediktov edited this page Aug 18, 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 mapper defines 3 types

 deserialized_type
 serialized_type
 parse_error_type

it should work with our GenericDSL class listed below.

  template<typename T=std::string , template<class, unsigned int...> class Mapper = DSL::dsl_mapper>
  class GenericDSL : public Mapper<T>  {
            
  public:
      using deserialized_type = typename Mapper<T>::deserialized_type;
      using serialized_type = typename Mapper<T>::serialized_type;
      using parse_error_type = typename Mapper<T>::parse_error_type;

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(40));
    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::GenericDSL<std::string, dsl_mapper_25> ; //dsl_mapper_25 is your custom mapper based on v.2.5
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();
});

Please visit wiki Customizing-BidRequest-and-BidResponse

Create CRUD handlers for your 2.2 and 2.5 exchange handlers

 using restful_dispatcher_t =  http::crud::crud_dispatcher<http::server::request, http::server::reply, std::string, std::string> ;
 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 have coded our DSL mapper as a template class accepting string_view structure used for BidRequest strings as a template parameter, so when string_view is passed to DSL mapper , the mapper does not allocate memory on the heap or copy bytes from original incoming json data into the the string.

 using DSLT = DSL::GenericDSL<jsonv::string_view> ; 
 using DSLT25 = DSL::GenericDSL<jsonv::string_view, dsl_mapper_25> ;

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 time of your string_view.

In our August, 2017 release we have added two more json-to-cpluplus mappers that outperform our default jsonv DSL mapping by nearly 50% .

To start using them you will have to pass new template parameter to GenericDSL structure

If you have low memory requirement for your deployment and performance is not top priority then you can try using solution based on boost::any

using DSLT = DSL::GenericDSL<std::string, DSL::any_mapper>;

However , if memory is not an issue you can start using our solution based on rapidjson

using DSLT = DSL::GenericDSL<std::string, DSL::rapid_mapper>;

Then pass this template parameter into exchange_handler like that

exchange_handler<DSLT> openrtb_handler(std::chrono::milliseconds(40));