Skip to content

Commit 30be940

Browse files
authored
support offset and user-id on latest items API (#1136)
1 parent b567dfd commit 30be940

File tree

3 files changed

+81
-7
lines changed

3 files changed

+81
-7
lines changed

common/parallel/parallel_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func TestParallelCancel(t *testing.T) {
163163
cancel()
164164
}
165165
count.Add(1)
166-
time.Sleep(time.Millisecond)
166+
time.Sleep(100 * time.Millisecond)
167167
return nil
168168
})
169169

server/rest.go

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -672,20 +672,61 @@ func (s *RestServer) SearchDocuments(collection, subset string, categories []str
672672
}
673673

674674
func (s *RestServer) getLatest(request *restful.Request, response *restful.Response) {
675-
n, err := ParseInt(request, "n", s.Config.Server.DefaultN)
676-
if err != nil {
677-
BadRequest(response, errors.New("invalid n parameter"))
675+
var (
676+
offset int
677+
n int
678+
err error
679+
)
680+
ctx := request.Request.Context()
681+
if offset, err = ParseInt(request, "offset", 0); err != nil {
682+
BadRequest(response, errors.Errorf("invalid offset parameter: %v", err))
683+
return
684+
}
685+
if n, err = ParseInt(request, "n", s.Config.Server.DefaultN); err != nil {
686+
BadRequest(response, errors.Errorf("invalid n parameter: %v", err))
678687
return
679688
}
680-
681689
categories := ReadCategories(request, nil)
682-
log.ResponseLogger(response).Debug("get category latest items in category", zap.Strings("categories", categories))
690+
userId := request.QueryParameter("user-id")
691+
692+
readItems := mapset.NewSet[string]()
693+
if userId != "" {
694+
feedback, err := s.DataClient.GetUserFeedback(ctx, userId, s.Config.Now())
695+
if err != nil {
696+
InternalServerError(response, err)
697+
return
698+
}
699+
for _, f := range feedback {
700+
readItems.Add(f.ItemId)
701+
}
702+
}
703+
704+
limit := offset + n
705+
if readItems.Cardinality() > 0 {
706+
limit += readItems.Cardinality()
707+
}
683708

684-
items, err := s.DataClient.GetLatestItems(request.Request.Context(), n, categories)
709+
items, err := s.DataClient.GetLatestItems(ctx, limit, categories)
685710
if err != nil {
686711
InternalServerError(response, err)
687712
return
688713
}
714+
715+
if readItems.Cardinality() > 0 {
716+
filtered := make([]data.Item, 0, len(items))
717+
for _, item := range items {
718+
if !readItems.Contains(item.ItemId) {
719+
filtered = append(filtered, item)
720+
}
721+
}
722+
items = filtered
723+
}
724+
725+
items = items[min(offset, len(items)):]
726+
if n > 0 && len(items) > n {
727+
items = items[:n]
728+
}
729+
689730
Ok(response, lo.Map(items, func(item data.Item, _ int) cache.Score {
690731
return cache.Score{
691732
Id: item.ItemId,

server/rest_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,20 @@ func (suite *ServerTestSuite) TestItems() {
293293
{Id: items[1].ItemId, Score: float64(items[1].Timestamp.Unix())},
294294
})).
295295
End()
296+
apitest.New().
297+
Handler(suite.handler).
298+
Get("/api/latest/").
299+
Header("X-API-Key", apiKey).
300+
QueryParams(map[string]string{
301+
"n": "3",
302+
"offset": "1",
303+
}).
304+
Expect(t).
305+
Status(http.StatusOK).
306+
Body(suite.marshal([]cache.Score{
307+
{Id: items[1].ItemId, Score: float64(items[1].Timestamp.Unix())},
308+
})).
309+
End()
296310
apitest.New().
297311
Handler(suite.handler).
298312
Get("/api/latest/*").
@@ -307,6 +321,25 @@ func (suite *ServerTestSuite) TestItems() {
307321
{Id: items[1].ItemId, Score: float64(items[1].Timestamp.Unix())},
308322
})).
309323
End()
324+
err := suite.DataClient.BatchInsertFeedback(context.Background(), []data.Feedback{{
325+
FeedbackKey: data.FeedbackKey{FeedbackType: "read", UserId: "0", ItemId: "6"},
326+
Timestamp: time.Now().Truncate(time.Hour),
327+
}}, true, true, true)
328+
suite.NoError(err)
329+
apitest.New().
330+
Handler(suite.handler).
331+
Get("/api/latest").
332+
Header("X-API-Key", apiKey).
333+
QueryParams(map[string]string{
334+
"n": "3",
335+
"user-id": "0",
336+
}).
337+
Expect(t).
338+
Status(http.StatusOK).
339+
Body(suite.marshal([]cache.Score{
340+
{Id: items[1].ItemId, Score: float64(items[1].Timestamp.Unix())},
341+
})).
342+
End()
310343

311344
// delete item
312345
apitest.New().

0 commit comments

Comments
 (0)