• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brotherlogic / wantslist / 3826731617

03 Jan 2023 03:53AM UTC coverage: 62.376%. First build
3826731617

Pull #316

github

Simon Tucker
Logging on complete set
Pull Request #316: Logging on complete set

1 of 1 new or added line in 1 file covered. (100.0%)

189 of 303 relevant lines covered (62.38%)

0.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.12
/wantslistutils.go
1
package main
2

3
import (
4
        "fmt"
5
        "math"
6
        "sort"
7
        "time"
8

9
        "github.com/prometheus/client_golang/prometheus"
10
        "github.com/prometheus/client_golang/prometheus/promauto"
11
        "golang.org/x/net/context"
12
        "google.golang.org/grpc/codes"
13
        "google.golang.org/grpc/status"
14

15
        rbpb "github.com/brotherlogic/recordbudget/proto"
16
        pbrc "github.com/brotherlogic/recordcollection/proto"
17
        pbrw "github.com/brotherlogic/recordwants/proto"
18
        pb "github.com/brotherlogic/wantslist/proto"
19
)
20

21
var (
22
        togoMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{
23
                Name: "wantslist_togo",
24
                Help: "The number of outstanding wants",
25
        }, []string{"list", "budget"})
26
        costMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{
27
                Name: "wantslist_cost",
28
                Help: "The number of outstanding wants",
29
        }, []string{"list", "budget"})
30
        oldest = promauto.NewGauge(prometheus.GaugeOpts{
31
                Name: "wantslist_oldest_cost",
32
                Help: "The number of outstanding wants",
33
        })
34
        newest = promauto.NewGauge(prometheus.GaugeOpts{
35
                Name: "wantslist_newest_cost",
36
                Help: "The number of outstanding wants",
37
        })
38
        activeMetric = promauto.NewGaugeVec(prometheus.GaugeOpts{
39
                Name: "wantslist_active",
40
                Help: "The number of outstanding wants",
41
        }, []string{"list", "budget"})
42
)
43

44
func recordMetrics(config *pb.Config) {
1✔
45
        for _, list := range config.GetLists() {
2✔
46
                togo := 0
1✔
47
                remaining := 0
1✔
48
                active := 0
1✔
49
                for _, entry := range list.GetWants() {
2✔
50
                        if entry.Status != pb.WantListEntry_WANTED && entry.Status == pb.WantListEntry_COMPLETE {
2✔
51
                                togo++
1✔
52
                                remaining += int(entry.GetEstimatedCost())
1✔
53
                        }
1✔
54
                        if entry.Status == pb.WantListEntry_WANTED {
2✔
55
                                active++
1✔
56
                        }
1✔
57
                }
58
                if active > 0 {
2✔
59
                        activeMetric.With(prometheus.Labels{"list": list.GetName(), "budget": list.GetBudget()}).Set(float64(active))
1✔
60
                }
1✔
61
                togoMetric.With(prometheus.Labels{"list": list.GetName(), "budget": list.GetBudget()}).Set(float64(togo))
1✔
62
                costMetric.With(prometheus.Labels{"list": list.GetName(), "budget": list.GetBudget()}).Set(float64(remaining))
1✔
63
        }
64
}
65

66
func (s *Server) prodProcess(ctx context.Context, config *pb.Config) error {
1✔
67
        return s.processWantLists(ctx, config)
1✔
68
}
1✔
69

70
func (s *Server) getRecord(ctx context.Context, id int32) (*pbrc.Record, error) {
1✔
71
        ids, err := s.rcclient.QueryRecords(ctx, &pbrc.QueryRecordsRequest{Query: &pbrc.QueryRecordsRequest_ReleaseId{int32(id)}})
1✔
72
        if err != nil {
1✔
73
                return nil, err
×
74
        }
×
75

76
        if len(ids.GetInstanceIds()) > 0 {
1✔
77
                rec, err := s.rcclient.GetRecord(ctx, &pbrc.GetRecordRequest{InstanceId: ids.GetInstanceIds()[0]})
×
78
                if err != nil {
×
79
                        return nil, err
×
80
                }
×
81
                return rec.GetRecord(), err
×
82
        }
83

84
        return nil, status.Errorf(codes.NotFound, "Cannot locate %v", id)
1✔
85
}
86
func (s *Server) updateWantOld(ctx context.Context, v *pb.WantListEntry, list *pb.WantList) error {
×
87
        if v.Status == pb.WantListEntry_WANTED {
×
88
                r, err := s.getRecord(ctx, v.Want)
×
89
                s.CtxLog(ctx, fmt.Sprintf("GOT Record: %v, %v", r, err))
×
90
                if err == nil && ((list.GetType() == pb.WantList_STANDARD &&
×
91
                        r.GetMetadata().Category != pbrc.ReleaseMetadata_UNLISTENED &&
×
92
                        r.GetMetadata().Category != pbrc.ReleaseMetadata_STAGED &&
×
93
                        r.GetMetadata().GetCategory() != pbrc.ReleaseMetadata_UNKNOWN) ||
×
94
                        (list.GetType() == pb.WantList_RAPID &&
×
95
                                r.GetMetadata().Category != pbrc.ReleaseMetadata_UNLISTENED)) {
×
96
                        v.Status = pb.WantListEntry_COMPLETE
×
97
                } else if err != nil {
×
98
                        want, err := s.wantBridge.get(ctx, v.Want)
×
99
                        s.CtxLog(ctx, fmt.Sprintf("Got want: %v, %v", want, err))
×
100
                        if err != nil || want.Level != pbrw.MasterWant_ANYTIME_LIST || want.GetRetireTime() != list.GetRetireTime() {
×
101
                                return s.wantBridge.want(ctx, v.Want, list.GetRetireTime(), list.GetBudget())
×
102
                        }
×
103
                }
104
        } else if v.Status == pb.WantListEntry_UNPROCESSED {
×
105
                s.wantBridge.unwant(ctx, v.Want, list.GetBudget())
×
106
        }
×
107
        return nil
×
108
}
109

110
func (s *Server) updateCosts(ctx context.Context, list *pb.WantList) error {
1✔
111
        defer func() {
2✔
112
                costs := int32(0)
1✔
113
                for _, entry := range list.GetWants() {
2✔
114
                        costs += entry.GetEstimatedCost()
1✔
115
                }
1✔
116
                list.OverallEstimatedCost = costs
1✔
117
        }()
118

119
        old := int64(math.MaxInt64)
1✔
120
        new := int64(0)
1✔
121
        for _, entry := range list.GetWants() {
2✔
122
                if entry.GetLastCostTime() < old {
2✔
123
                        old = (entry.GetLastCostTime())
1✔
124
                }
1✔
125
                if entry.GetLastCostTime() > new {
2✔
126
                        new = entry.GetLastCostTime()
1✔
127
                }
1✔
128
        }
129
        oldest.Set(float64(old))
1✔
130
        newest.Set(float64(new))
1✔
131

1✔
132
        for _, entry := range list.GetWants() {
2✔
133
                if time.Since(time.Unix(entry.GetLastCostTime(), 0)) > time.Hour*24*7 {
2✔
134
                        price, err := s.rcclient.GetPrice(ctx, &pbrc.GetPriceRequest{Id: entry.GetWant()})
1✔
135
                        if err != nil {
1✔
136
                                return err
×
137
                        }
×
138
                        entry.EstimatedCost = int32(price.GetPrice() * 100)
1✔
139
                        entry.LastCostTime = time.Now().Unix()
1✔
140
                        return nil
1✔
141
                }
142
        }
143

144
        return nil
×
145
}
146

147
func (s *Server) processWantLists(ctx context.Context, config *pb.Config) error {
1✔
148
        defer s.CtxLog(ctx, "Complete processing")
1✔
149
        for _, list := range config.Lists {
2✔
150
                s.updateCosts(ctx, list)
1✔
151

1✔
152
                //
1✔
153
                budget, err := s.budgetClient.GetBudget(ctx, &rbpb.GetBudgetRequest{Budget: list.GetBudget()})
1✔
154
                if err != nil {
1✔
155
                        return err
×
156
                }
×
157
                if budget.GetChosenBudget().GetRemaining() <= 0 {
2✔
158
                        s.CtxLog(ctx, fmt.Sprintf("Unwanting %v becuase budget %v has no money in it", list.GetName(), list.GetBudget()))
1✔
159
                        for _, w := range list.GetWants() {
2✔
160
                                if w.Status == pb.WantListEntry_WANTED {
2✔
161
                                        w.Status = pb.WantListEntry_UNPROCESSED
1✔
162
                                }
1✔
163
                        }
164

165
                        continue
1✔
166
                }
167

168
                sort.SliceStable(list.Wants, func(i2, j2 int) bool {
2✔
169
                        return list.Wants[i2].Index < list.Wants[j2].Index
1✔
170
                })
1✔
171
                hasLimbo := false
1✔
172
                for _, entry := range list.GetWants() {
2✔
173
                        if entry.Status == pb.WantListEntry_LIMBO {
2✔
174
                                hasLimbo = true
1✔
175
                                break
1✔
176
                        }
177
                }
178

179
                if hasLimbo {
2✔
180
                        for _, w := range list.GetWants() {
2✔
181
                                if w.Status == pb.WantListEntry_WANTED {
1✔
182
                                        w.Status = pb.WantListEntry_UNPROCESSED
×
183
                                }
×
184
                        }
185
                        continue
1✔
186
                }
187

188
                switch list.GetType() {
1✔
189
                case pb.WantList_ALL_IN:
1✔
190
                        for _, w := range list.GetWants() {
2✔
191
                                want, err := s.wantBridge.get(ctx, w.GetWant())
1✔
192
                                if err != nil && status.Code(err) != codes.NotFound {
1✔
193
                                        return err
×
194
                                }
×
195

196
                                if want != nil && want.GetCurrentState() == pbrw.MasterWant_WANTED && w.GetStatus() != pb.WantListEntry_WANTED {
1✔
197
                                        s.wantBridge.unwant(ctx, w.GetWant(), list.GetBudget())
×
198
                                } else if (want == nil || want.GetCurrentState() != pbrw.MasterWant_WANTED) && w.GetStatus() == pb.WantListEntry_WANTED {
2✔
199
                                        s.wantBridge.want(ctx, w.GetWant(), list.GetRetireTime(), list.GetBudget())
1✔
200
                                }
1✔
201

202
                                _, err = s.getRecord(ctx, w.GetWant())
1✔
203
                                if err == nil || status.Code(err) != codes.NotFound {
1✔
204
                                        w.Status = pb.WantListEntry_COMPLETE
×
205
                                }
×
206

207
                                if w.Status == pb.WantListEntry_UNPROCESSED {
2✔
208
                                        w.Status = pb.WantListEntry_WANTED
1✔
209
                                }
1✔
210
                        }
211
                case pb.WantList_STANDARD, pb.WantList_RAPID:
1✔
212
                        prior := pb.WantListEntry_COMPLETE
1✔
213
                        for _, entry := range list.GetWants() {
2✔
214
                                if entry.GetStatus() == pb.WantListEntry_UNPROCESSED && prior == pb.WantListEntry_COMPLETE {
2✔
215
                                        entry.Status = pb.WantListEntry_WANTED
1✔
216
                                        break
1✔
217
                                }
218
                        }
219
                case pb.WantList_YEARLY:
×
220
                        days := 365 / len(list.GetWants())
×
221
                        for i, entry := range list.GetWants() {
×
222
                                want, err := s.wantBridge.get(ctx, entry.GetWant())
×
223
                                if err != nil && status.Code(err) != codes.NotFound {
×
224
                                        return err
×
225
                                }
×
226
                                if want != nil && want.GetCurrentState() == pbrw.MasterWant_WANTED && entry.GetStatus() != pb.WantListEntry_WANTED {
×
227
                                        s.wantBridge.unwant(ctx, entry.GetWant(), list.GetBudget())
×
228
                                } else if (want == nil || want.GetCurrentState() != pbrw.MasterWant_WANTED) && entry.GetStatus() == pb.WantListEntry_WANTED {
×
229
                                        s.wantBridge.want(ctx, entry.GetWant(), list.GetRetireTime(), list.GetBudget())
×
230
                                }
×
231

232
                                _, err = s.getRecord(ctx, entry.GetWant())
×
233
                                s.CtxLog(ctx, fmt.Sprintf("Got record: %v", err))
×
234
                                if err == nil || status.Code(err) != codes.NotFound {
×
235
                                        entry.Status = pb.WantListEntry_COMPLETE
×
236
                                }
×
237

238
                                if time.Now().YearDay() > days*i {
×
239
                                        if entry.Status == pb.WantListEntry_UNPROCESSED {
×
240
                                                entry.Status = pb.WantListEntry_WANTED
×
241
                                        }
×
242
                                }
243
                        }
244
                }
245
        }
246

247
        config = s.cleanWantlists(ctx, config)
1✔
248
        return s.save(ctx, config)
1✔
249
}
250

251
func (s *Server) cleanWantlists(ctx context.Context, config *pb.Config) *pb.Config {
1✔
252
        newwantlists := []*pb.WantList{}
1✔
253
        for _, list := range config.Lists {
2✔
254
                if int32(time.Now().Year()) == list.GetYear() {
2✔
255
                        newwantlists = append(newwantlists, list)
1✔
256
                }
1✔
257
        }
258

259
        config.Lists = newwantlists
1✔
260
        return config
1✔
261
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc