RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
core/banker/banker.cc
00001 /* banker.cc
00002    Sunil Rottoo, May 2012
00003    Copyright (c) 2012 Datacratic.  All rights reserved.
00004    
00005    Banker functionality for the RTB router.
00006 */
00007 
00008 #include "banker.h"
00009 #include "jml/arch/timers.h"
00010 #include "jml/arch/format.h"
00011 #include "jml/utils/exc_assert.h"
00012 #include "jml/arch/futex.h"
00013 #include <boost/foreach.hpp>
00014 
00015 
00016 using namespace std;
00017 using namespace ML;
00018 
00019 
00020 namespace RTBKIT {
00021 
00022 
00023 /*****************************************************************************/
00024 /* BUDGET CONTROLLER PROXY                                                   */
00025 /*****************************************************************************/
00026 
00027 BudgetController::
00028 BudgetController()
00029 {
00030     // No more than $100k USD in budget as a default limit
00031     budgetLimits += USD(100000);
00032 }
00033 
00034 BudgetController::
00035 ~BudgetController()
00036 {
00037 }
00038 
00039 void
00040 BudgetController::
00041 addAccount(const AccountKey & account,
00042            const OnBudgetResult & onResult)
00043 {
00044     try {
00045         addAccountSync(account);
00046         if (onResult)
00047             onResult(nullptr);
00048     } catch (...) {
00049         if (onResult)
00050             onResult(std::current_exception());
00051         else throw;
00052     }
00053 }
00054 
00055 void
00056 BudgetController::
00057 addAccountSync(const AccountKey & account)
00058 {
00059     BankerSyncResult<void> result;
00060     addAccount(account, result);
00061     return result.get();
00062 }
00063 
00064 void
00065 BudgetController::
00066 topupTransfer(const AccountKey & account,
00067                         CurrencyPool amount,
00068                         const OnBudgetResult & onResult)
00069 {
00070     try {
00071         topupTransferSync(account, amount);
00072         if (onResult)
00073             onResult(nullptr);
00074     } catch (...) {
00075         if (onResult)
00076             onResult(std::current_exception());
00077         else throw;
00078     }
00079 }
00080 
00081 void
00082 BudgetController::
00083 topupTransferSync(const AccountKey & account,
00084                             CurrencyPool amount)
00085 {
00086     BankerSyncResult<void> result;
00087     topupTransfer(account, amount, result);
00088     return result.get();
00089 }
00090 
00091 void
00092 BudgetController::
00093 setBudget(const std::string & topLevelAccount,
00094           CurrencyPool amount,
00095           const OnBudgetResult & onResult)
00096 {
00097     try {
00098         setBudgetSync(topLevelAccount, amount);
00099         if (onResult)
00100             onResult(nullptr);
00101     } catch (...) {
00102         if (onResult)
00103             onResult(std::current_exception());
00104         else throw;
00105     }
00106 }
00107     
00108 void
00109 BudgetController::
00110 setBudgetSync(const std::string & topLevelAccount,
00111               CurrencyPool amount)
00112 {
00113     BankerSyncResult<void> result;
00114     setBudget(topLevelAccount, amount, result);
00115     return result.get();
00116 }
00117 
00118 void
00119 BudgetController::
00120 addBudget(const std::string & topLevelAccount,
00121           CurrencyPool amount,
00122           const OnBudgetResult & onResult)
00123 {
00124     try {
00125         addBudgetSync(topLevelAccount, amount);
00126         if (onResult)
00127             onResult(nullptr);
00128     } catch (...) {
00129         if (onResult)
00130             onResult(std::current_exception());
00131         else throw;
00132     }
00133 }
00134 
00135 void
00136 BudgetController::
00137 addBudgetSync(const std::string & topLevelAccount,
00138               CurrencyPool amount)
00139 {
00140     BankerSyncResult<void> result;
00141     addBudget(topLevelAccount, amount, result);
00142     return result.get();
00143 }
00144 
00145 
00146 /*****************************************************************************/
00147 /* ACCOUNTANT                                                                */
00148 /*****************************************************************************/
00149 
00150 std::vector<AccountKey>
00151 Accountant::
00152 getAccountListSync(const AccountKey & prefix,
00153                    int depth)
00154 {
00155     BankerSyncResult<std::vector<AccountKey> > result;
00156     getAccountList(prefix, depth, result);
00157     return result.get();
00158 }
00159 
00160 void
00161 Accountant::
00162 getAccountList(const AccountKey & prefix,
00163                int depth,
00164                std::function<void (std::exception_ptr,
00165                                    std::vector<AccountKey> &&)> onResult)
00166 {
00167     std::vector<AccountKey> res;
00168     std::exception_ptr p;
00169     try {
00170         res = getAccountListSync(prefix, depth);
00171     } catch (...) {
00172         if (onResult)
00173             p = std::current_exception();
00174         else throw;
00175     }
00176     if (onResult)
00177         onResult(p, std::move(res));
00178 }
00179 
00180 AccountSummary
00181 Accountant::
00182 getAccountSummarySync(const AccountKey & account, int depth)
00183 {
00184     BankerSyncResult<AccountSummary> result;
00185     getAccountSummary(account, depth, result);
00186     return result.get();
00187 }
00188 
00189 void
00190 Accountant::
00191 getAccountSummary(const AccountKey & account,
00192                  int depth,
00193                  std::function<void (std::exception_ptr,
00194                                      AccountSummary &&)> onResult)
00195 {
00196     AccountSummary res;
00197     std::exception_ptr p;
00198     try {
00199         res = getAccountSummarySync(account, depth);
00200     } catch (...) {
00201         if (onResult)
00202             p = std::current_exception();
00203         else throw;
00204     }
00205     if (onResult)
00206         onResult(p, std::move(res));
00207 }
00208 
00209 Account
00210 Accountant::
00211 getAccountSync(const AccountKey & account)
00212 {
00213     BankerSyncResult<Account> result;
00214     getAccount(account, result);
00215     return result.get();
00216 }
00217 
00218 void
00219 Accountant::
00220 getAccount(const AccountKey & account,
00221            std::function<void (std::exception_ptr,
00222                                Account &&)> onResult)
00223 {
00224     Account res;
00225     std::exception_ptr p;
00226     try {
00227         res = getAccountSync(account);
00228     } catch (...) {
00229         if (onResult)
00230             p = std::current_exception();
00231         else throw;
00232     }
00233     if (onResult)
00234         onResult(p, std::move(res));
00235 }
00236 
00237 
00238 /*****************************************************************************/
00239 /* BANKER                                                                    */
00240 /*****************************************************************************/
00241 
00242 Banker::
00243 ~Banker()
00244 {
00245 }
00246 
00247 ShadowAccount
00248 Banker::
00249 addSpendAccountSync(const AccountKey & account, CurrencyPool accountFloat)
00250 {
00251     BankerSyncResult<ShadowAccount> result;
00252     addSpendAccount(account, accountFloat, result);
00253     return result.get();
00254 }
00255 
00256 void
00257 Banker::
00258 addSpendAccount(const AccountKey & account, CurrencyPool accountFloat,
00259                 std::function<void (std::exception_ptr, ShadowAccount&&)> onDone)
00260 {
00261     ShadowAccount res;
00262     std::exception_ptr p;
00263     try {
00264         res = addSpendAccountSync(account, accountFloat);
00265     } catch (...) {
00266         if (onDone)
00267             p = std::current_exception();
00268         else throw;
00269     }
00270     if (onDone)
00271         onDone(p, std::move(res));
00272 }
00273 
00274 /*****************************************************************************/
00275 /* BANKER EXCEPTION                                                           */
00276 /*****************************************************************************/
00277 
00278 //----------------------------------------------------------------------
00279 string BankerException::errorToString(const BankerError &cond)
00280 {
00281     if (cond == BankerError::INVALID_CAMPAIGN)
00282         return "INVALID_CAMPAIGN";
00283     if (cond == BankerError::CAMPAIGN_NOT_FOUND)
00284         return "CAMPAIGN_NOT_FOUND";
00285     else if (cond == BankerError::INVALID_STRATEGY)
00286         return "INVALID_STRATEGY";
00287     else if (cond == BankerError::STRATEGY_NOT_FOUND)
00288         return "STRATEGY_NOT_FOUND";
00289     else if (cond == BankerError::INSUFFICIENT_FUNDS)
00290         return "INSUFFICIENT_FUNDS";
00291     else if (cond == BankerError::LOWER_THAN_TRANSFERRED)
00292         return "LOWER_THAN_TRANSFERRED";
00293     else if (cond == BankerError::EXCEEDS_MAX)
00294         return "EXCEEDS_MAX";
00295     else if (cond == BankerError::DATABASE_ERROR)
00296         return "DATABASE_ERROR";
00297     else if (cond == BankerError::ACCOUNTING_MISMATCH)
00298         return "ACCOUNTING_MISMATCH";
00299     else
00300         return "UNKNOWN_ERROR";
00301 }
00302 //---------------------------------------------------------------------------------
00303 BankerException::BankerException(const std::string &msg,
00304         const BankerError &error) :
00305         ML::Exception(msg + BankerException::errorToString(error)), error_(
00306                 error)
00307 {
00308 }
00309 
00310 } // namespace RTBKIT
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator