forked from prebid/prebid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultifetcher.go
113 lines (100 loc) · 3.53 KB
/
multifetcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package stored_requests
import (
"context"
"encoding/json"
"fmt"
)
// MultiFetcher is a Fetcher composed of multiple sub-Fetchers that are all polled for results.
type MultiFetcher []AllFetcher
// FetchRequests implements the Fetcher interface for MultiFetcher
func (mf MultiFetcher) FetchRequests(ctx context.Context, requestIDs []string, impIDs []string) (requestData map[string]json.RawMessage, impData map[string]json.RawMessage, errs []error) {
requestData = make(map[string]json.RawMessage, len(requestIDs))
impData = make(map[string]json.RawMessage, len(impIDs))
// Loop over the fetchers
for _, f := range mf {
remainingRequestIDs := filter(requestIDs, requestData)
requestIDs = remainingRequestIDs
remainingImpIDs := filter(impIDs, impData)
impIDs = remainingImpIDs
theseRequestData, theseImpData, rerrs := f.FetchRequests(ctx, remainingRequestIDs, remainingImpIDs)
// Drop NotFound errors, as other fetchers may have them. Also don't want multiple NotFound errors per ID.
rerrs = dropMissingIDs(rerrs)
if len(rerrs) > 0 {
errs = append(errs, rerrs...)
}
addAll(requestData, theseRequestData)
addAll(impData, theseImpData)
}
// Add missing ID errors back in for any IDs that are still missing
errs = appendNotFoundErrors("Request", requestIDs, requestData, errs)
errs = appendNotFoundErrors("Imp", impIDs, impData, errs)
return
}
func (mf MultiFetcher) FetchResponses(ctx context.Context, ids []string) (data map[string]json.RawMessage, errs []error) {
return nil, nil
}
func (mf MultiFetcher) FetchAccount(ctx context.Context, accountDefaultJSON json.RawMessage, accountID string) (account json.RawMessage, errs []error) {
for _, f := range mf {
if af, ok := f.(AccountFetcher); ok {
if account, accErrs := af.FetchAccount(ctx, accountDefaultJSON, accountID); len(accErrs) == 0 {
return account, nil
} else {
accErrs = dropMissingIDs(accErrs)
errs = append(errs, accErrs...)
}
}
}
errs = append(errs, NotFoundError{accountID, "Account"})
return nil, errs
}
func (mf MultiFetcher) FetchCategories(ctx context.Context, primaryAdServer, publisherId, iabCategory string) (string, error) {
for _, f := range mf {
if cf, ok := f.(CategoryFetcher); ok {
iabCategory, _ := cf.FetchCategories(ctx, primaryAdServer, publisherId, iabCategory)
if iabCategory != "" {
return iabCategory, nil
}
}
}
// For now just return a NotFoundError if we didn't find it for some reason
errtype := fmt.Sprintf("%s_%s.%s", primaryAdServer, publisherId, iabCategory)
return "", NotFoundError{errtype, "Category"}
}
func addAll(base map[string]json.RawMessage, toAdd map[string]json.RawMessage) {
for k, v := range toAdd {
base[k] = v
}
}
func filter(original []string, exclude map[string]json.RawMessage) (filtered []string) {
if len(exclude) == 0 {
filtered = original
return
}
filtered = make([]string, 0, len(original))
for _, id := range original {
if _, ok := exclude[id]; !ok {
filtered = append(filtered, id)
}
}
return
}
func appendNotFoundErrors(dataType string, expected []string, contains map[string]json.RawMessage, errs []error) []error {
for _, id := range expected {
if _, ok := contains[id]; !ok {
errs = append(errs, NotFoundError{id, dataType})
}
}
return errs
}
// dropMissingIDs will scrub the NotFoundError's from a slice of errors.
// The order of the errors will not be preserved.
func dropMissingIDs(errs []error) []error {
// filtered errors
ferrs := errs[:0]
for _, e := range errs {
if _, ok := e.(NotFoundError); !ok {
ferrs = append(ferrs, e)
}
}
return ferrs
}