Skip to content

Commit

Permalink
Per-account cache TTLs
Browse files Browse the repository at this point in the history
  • Loading branch information
laurb9 committed Aug 13, 2020
1 parent 6011bc3 commit 8ab369f
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 25 deletions.
1 change: 1 addition & 0 deletions config/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Account struct {
Events Events `mapstructure:"events" json:"events"`
CCPA CCPA `mapstructure:"ccpa" json:"ccpa"`
GDPR TCF2 `mapstructure:"gdpr" json:"gdpr"`
LMT LMT `mapstructure:"lmt": json:"lmt"`
Analytics PubAnalytics `mapstructure:"analytics" json:"analytics"`
}

Expand Down
5 changes: 4 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,10 +539,13 @@ func New(v *viper.Viper) (*Configuration, error) {
return nil, err
}

// Migrate some settings to default account
// Migrate some global settings to default account so they can be overriden by account
// TODO: check they weren't already set or in conflict
c.DefaultAccount.Disabled = c.AccountRequired
c.DefaultAccount.GDPR = c.GDPR.TCF2
c.DefaultAccount.CCPA = c.CCPA
c.DefaultAccount.LMT = c.LMT
c.DefaultAccount.TTL = c.CacheURL.DefaultTTLs

if len(c.GDPR.NonStandardPublishers) > 0 {
glog.Warningf("gdpr.non_standard_publishers has been deprecated; use per-account gdpr.enabled=false setting instead")
Expand Down
4 changes: 2 additions & 2 deletions endpoints/openrtb2/amp_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
labels.CookieFlag = pbsmetrics.CookieFlagYes
}
labels.PubID = effectivePubID(req.Site.Publisher)
_, acctIdErr := deps.validateAccount(ctx, labels.PubID)
account, acctIdErr := deps.validateAccount(ctx, labels.PubID)
if acctIdErr != nil {
errL = append(errL, acctIdErr)
errCode := errortypes.ReadCode(acctIdErr)
Expand All @@ -175,7 +175,7 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h
return
}

response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, &deps.categories, nil)
response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, account, &deps.categories, nil)
ao.AuctionResponse = response

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion endpoints/openrtb2/amp_auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ var expectedErrorsFromHoldAuction map[openrtb_ext.BidderName][]openrtb_ext.ExtBi
},
}

func (m *mockAmpExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
func (m *mockAmpExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
m.lastRequest = bidRequest

response := &openrtb.BidResponse{
Expand Down
17 changes: 11 additions & 6 deletions endpoints/openrtb2/auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type endpointDeps struct {
paramsValidator openrtb_ext.BidderParamValidator
storedReqFetcher stored_requests.Fetcher
videoFetcher stored_requests.Fetcher
acccounts stored_requests.AccountFetcher
accounts stored_requests.AccountFetcher
categories stored_requests.CategoryFetcher
cfg *config.Configuration
metricsEngine pbsmetrics.MetricsEngine
Expand Down Expand Up @@ -154,14 +154,14 @@ func (deps *endpointDeps) Auction(w http.ResponseWriter, r *http.Request, _ http
labels.PubID = effectivePubID(req.Site.Publisher)
}

_, acctIdErr := deps.validateAccount(ctx, labels.PubID)
account, acctIdErr := deps.validateAccount(ctx, labels.PubID)
if acctIdErr != nil {
errL = append(errL, acctIdErr)
writeError(errL, w, &labels)
return
}

response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, &deps.categories, nil)
response, err := deps.ex.HoldAuction(ctx, req, usersyncs, labels, account, &deps.categories, nil)
ao.Request = req
ao.Response = response
if err != nil {
Expand Down Expand Up @@ -1293,13 +1293,18 @@ func (deps *endpointDeps) validateAccount(ctx context.Context, pubID string) (*c
}
var account *config.Account
var err error
if account, err = deps.acccounts.FetchAccount(ctx, pubID); err != nil || account == nil {
account = &deps.cfg.DefaultAccount
if account.Disabled {
if account, err = deps.accounts.FetchAccount(ctx, pubID); err != nil || account == nil {
if deps.cfg.DefaultAccount.Disabled {
err = error(&errortypes.AcctRequired{
Message: fmt.Sprintf("Prebid-server has been configured to discard requests that don't come with an Account ID. Please reach out to the prebid server host."),
})
}
// We have an unknown account, so use the DefaultAccount
// Transitional: make a copy of DefaultAccount instead of taking a reference,
// because the pubID is needed to check NonStandardPublisherMap in gdpr/impl.go
pubAccount := deps.cfg.DefaultAccount
pubAccount.ID = pubID
account = &pubAccount
} else {
glog.Infof("resolved account for %s -> %+v", pubID, account)
if account.Disabled {
Expand Down
6 changes: 3 additions & 3 deletions endpoints/openrtb2/auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ type nobidExchange struct {
gotRequest *openrtb.BidRequest
}

func (e *nobidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
func (e *nobidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
e.gotRequest = bidRequest
return &openrtb.BidResponse{
ID: bidRequest.ID,
Expand All @@ -1390,7 +1390,7 @@ func (e *nobidExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.Bid

type brokenExchange struct{}

func (e *brokenExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
func (e *brokenExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
return nil, errors.New("Critical, unrecoverable error.")
}

Expand Down Expand Up @@ -1763,7 +1763,7 @@ type mockExchange struct {
lastRequest *openrtb.BidRequest
}

func (m *mockExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
func (m *mockExchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
m.lastRequest = bidRequest
return &openrtb.BidResponse{
SeatBid: []openrtb.SeatBid{{
Expand Down
4 changes: 2 additions & 2 deletions endpoints/openrtb2/video_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,14 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
labels.PubID = effectivePubID(bidReq.Site.Publisher)
}

_, acctIdErr := deps.validateAccount(ctx, labels.PubID)
account, acctIdErr := deps.validateAccount(ctx, labels.PubID)
if acctIdErr != nil {
errL := []error{err}
handleError(&labels, w, errL, &vo, &debugLog)
return
}
//execute auction logic
response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, &deps.categories, &debugLog)
response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, account, &deps.categories, &debugLog)
vo.Request = bidReq
vo.Response = response
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion endpoints/openrtb2/video_auction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@ type mockExchangeVideo struct {
cache *mockCacheClient
}

func (m *mockExchangeVideo) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
func (m *mockExchangeVideo) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, ids exchange.IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *exchange.DebugLog) (*openrtb.BidResponse, error) {
m.lastRequest = bidRequest
if debugLog != nil && debugLog.Enabled {
m.cache.called = true
Expand Down
8 changes: 3 additions & 5 deletions exchange/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const DebugContextKey = ContextKey("debugInfo")
// Exchange runs Auctions. Implementations must be threadsafe, and will be shared across many goroutines.
type Exchange interface {
// HoldAuction executes an OpenRTB v2.5 Auction.
HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error)
HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error)
}

// IdFetcher can find the user's ID for a specific Bidder.
Expand All @@ -52,7 +52,6 @@ type exchange struct {
gDPR gdpr.Permissions
currencyConverter *currencies.RateConverter
UsersyncIfAmbiguous bool
defaultTTLs config.DefaultTTLs
privacyConfig config.Privacy
}

Expand Down Expand Up @@ -81,7 +80,6 @@ func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *con
e.gDPR = gDPR
e.currencyConverter = currencyConverter
e.UsersyncIfAmbiguous = cfg.GDPR.UsersyncIfAmbiguous
e.defaultTTLs = cfg.CacheURL.DefaultTTLs
e.privacyConfig = config.Privacy{
CCPA: cfg.CCPA,
GDPR: cfg.GDPR,
Expand All @@ -90,7 +88,7 @@ func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *con
return e
}

func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error) {
func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidRequest, usersyncs IdFetcher, labels pbsmetrics.Labels, account *config.Account, categoriesFetcher *stored_requests.CategoryFetcher, debugLog *DebugLog) (*openrtb.BidResponse, error) {

requestExt, err := extractBidRequestExt(bidRequest)
if err != nil {
Expand Down Expand Up @@ -177,7 +175,7 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
}
}

cacheErrs := auc.doCache(ctx, e.cache, targData, bidRequest, 60, &e.defaultTTLs, bidCategory, debugLog)
cacheErrs := auc.doCache(ctx, e.cache, targData, bidRequest, 60, &account.TTL, bidCategory, debugLog)
if len(cacheErrs) > 0 {
errs = append(errs, cacheErrs...)
}
Expand Down
6 changes: 3 additions & 3 deletions exchange/exchange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ func TestRaceIntegration(t *testing.T) {
theMetrics := pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{})
currencyConverter := currencies.NewRateConverter(&http.Client{}, "", time.Duration(0))
ex := NewExchange(server.Client(), &wellBehavedCache{}, cfg, theMetrics, adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencyConverter)
_, err := ex.HoldAuction(context.Background(), newRaceCheckingRequest(t), &emptyUsersync{}, pbsmetrics.Labels{}, &categoriesFetcher, nil)
_, err := ex.HoldAuction(context.Background(), newRaceCheckingRequest(t), &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil)
if err != nil {
t.Errorf("HoldAuction returned unexpected error: %v", err)
}
Expand Down Expand Up @@ -809,7 +809,7 @@ func TestPanicRecoveryHighLevel(t *testing.T) {
if error != nil {
t.Errorf("Failed to create a category Fetcher: %v", error)
}
_, err := e.HoldAuction(context.Background(), request, &emptyUsersync{}, pbsmetrics.Labels{}, &categoriesFetcher, nil)
_, err := e.HoldAuction(context.Background(), request, &emptyUsersync{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil)
if err != nil {
t.Errorf("HoldAuction returned unexpected error: %v", err)
}
Expand Down Expand Up @@ -922,7 +922,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) {
*debugLog = *spec.DebugLog
debugLog.Regexp = regexp.MustCompile(`[<>]`)
}
bid, err := ex.HoldAuction(context.Background(), &spec.IncomingRequest.OrtbRequest, mockIdFetcher(spec.IncomingRequest.Usersyncs), pbsmetrics.Labels{}, &categoriesFetcher, debugLog)
bid, err := ex.HoldAuction(context.Background(), &spec.IncomingRequest.OrtbRequest, mockIdFetcher(spec.IncomingRequest.Usersyncs), pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, debugLog)
responseTimes := extractResponseTimes(t, filename, bid)
for _, bidderName := range biddersInAuction {
if _, ok := responseTimes[bidderName]; !ok {
Expand Down
2 changes: 1 addition & 1 deletion exchange/targeting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func runTargetingAuction(t *testing.T, mockBids map[openrtb_ext.BidderName][]*op
if error != nil {
t.Errorf("Failed to create a category Fetcher: %v", error)
}
bidResp, err := ex.HoldAuction(context.Background(), req, &mockFetcher{}, pbsmetrics.Labels{}, &categoriesFetcher, nil)
bidResp, err := ex.HoldAuction(context.Background(), req, &mockFetcher{}, pbsmetrics.Labels{}, &config.Account{}, &categoriesFetcher, nil)

if err != nil {
t.Fatalf("Unexpected errors running auction: %v", err)
Expand Down

0 comments on commit 8ab369f

Please sign in to comment.