From 8b8d11815931817612db6774e9f24ee7b01ea5c7 Mon Sep 17 00:00:00 2001 From: Sergey Tsalkov Date: Thu, 14 Nov 2019 20:43:22 -0800 Subject: [PATCH] perpage setting applies to search results simplify search results code --- web/joblist.go | 101 +++++++++++++++++++++++++++---------------------- web/search.go | 90 ++++++++++++------------------------------- 2 files changed, 80 insertions(+), 111 deletions(-) diff --git a/web/joblist.go b/web/joblist.go index 7ba356f..e848002 100644 --- a/web/joblist.go +++ b/web/joblist.go @@ -10,8 +10,6 @@ import ( "strconv" "brooce/task" - - "github.com/go-redis/redis" ) type joblistOutputType struct { @@ -19,6 +17,7 @@ type joblistOutputType struct { QueueName string Page int64 Pages int64 + PerPage int64 Length int64 Start int64 End int64 @@ -40,31 +39,20 @@ func joblistHandler(req *http.Request, rep *httpReply) (err error) { queueName := path[1] page := joblistQueryParams(req.URL.RawQuery) - perpage := joblistPerPage(req) output := &joblistOutputType{ QueueName: queueName, ListType: listType, Page: int64(page), + PerPage: joblistPerPage(req), URL: req.URL, } - err = output.listJobs(listType == "pending", perpage) + err = output.listJobs() if err != nil { return } - if output.Pages == 0 { - output.Page = 0 - } else if output.Page > output.Pages { - output.Page = output.Pages - - err = output.listJobs(listType == "pending", perpage) - if err != nil { - return - } - } - err = templates.ExecuteTemplate(rep, "joblist", output) return } @@ -119,54 +107,41 @@ func (output *joblistOutputType) LinkParamsForNextPage(page int64) template.URL return output.LinkParamsForPage(page + 1) } -func (output *joblistOutputType) listJobs(reverse bool, perpage int64) (err error) { - output.Start = (output.Page-1)*perpage + 1 - output.End = output.Page * perpage - +func (output *joblistOutputType) listJobs() (err error) { + reverse := (output.ListType == "pending") redisKey := fmt.Sprintf("%s:queue:%s:%s", redisHeader, output.QueueName, output.ListType) - rangeStart := (output.Page - 1) * perpage - rangeEnd := output.Page*perpage - 1 - - if reverse { - rangeStart, rangeEnd = (rangeEnd+1)*-1, (rangeStart+1)*-1 + output.Length, err = redisClient.LLen(redisKey).Result() + if err != nil { + return err } - var lengthResult *redis.IntCmd - var rangeResult *redis.StringSliceCmd - _, err = redisClient.Pipelined(func(pipe redis.Pipeliner) error { - lengthResult = pipe.LLen(redisKey) - rangeResult = pipe.LRange(redisKey, rangeStart, rangeEnd) - return nil - }) - if err != nil { + output.pageCalculate() + + if output.Length == 0 { return } - output.Length = lengthResult.Val() - output.Pages = int64(math.Ceil(float64(output.Length) / float64(perpage))) - if output.End > output.Length { - output.End = output.Length - } - if output.Start > output.Length { - output.Start = output.Length + rangeStart := output.Start - 1 + rangeEnd := output.End - 1 + + if reverse { + rangeStart, rangeEnd = (rangeEnd+1)*-1, (rangeStart+1)*-1 } - rangeLength := len(rangeResult.Val()) - output.Jobs = make([]*task.Task, rangeLength) + var jobs []string + jobs, err = redisClient.LRange(redisKey, rangeStart, rangeEnd).Result() - if len(output.Jobs) == 0 { - return - } + output.Jobs = make([]*task.Task, len(jobs)) - for i, value := range rangeResult.Val() { + for i, value := range jobs { job, err := task.NewFromJson(value, output.QueueName) if err != nil { continue } if reverse { - output.Jobs[rangeLength-i-1] = job + output.Jobs[len(jobs)-i-1] = job } else { output.Jobs[i] = job } @@ -175,3 +150,37 @@ func (output *joblistOutputType) listJobs(reverse bool, perpage int64) (err erro task.PopulateHasLog(output.Jobs) return } + +func (output *joblistOutputType) pageCalculate() { + if output.Page < 1 { + output.Page = 1 + } + if output.PerPage < 1 { + output.PerPage = 1 + } + + output.Pages = int64(math.Ceil(float64(output.Length) / float64(output.PerPage))) + + if output.Length == 0 { + output.Start = 0 + output.End = 0 + output.Page = 0 + return + } + + for { + output.Start = (output.Page-1)*output.PerPage + 1 + output.End = output.Page * output.PerPage + + if output.Start > output.Length { + output.Page = output.Pages + continue + } + + break + } + + if output.End > output.Length { + output.End = output.Length + } +} diff --git a/web/search.go b/web/search.go index 1d29853..155d5de 100644 --- a/web/search.go +++ b/web/search.go @@ -3,7 +3,6 @@ package web import ( "fmt" "log" - "math" "net/http" "net/url" "strconv" @@ -13,92 +12,53 @@ import ( "brooce/task" ) -type PagedHits struct { - Hits []*task.Task - Start int - End int - Pages int - PageSize int - PageWanted int -} - func searchHandler(req *http.Request, rep *httpReply) (err error) { query, queueName, listType, page := searchQueryParams(req.URL.RawQuery) - hitsJson := searchQueueForCommand(query, queueName, listType) - pagedHits := newPagedHits(hitsJson, 10, page, queueName) - - if pagedHits.Pages == 0 { - pagedHits.Start = 0 - page = 0 - } else if page > pagedHits.Pages { - page = pagedHits.Pages - pagedHits = newPagedHits(hitsJson, 10, page, queueName) - } - - task.PopulateHasLog(pagedHits.Hits) - output := &joblistOutputType{ QueueName: queueName, ListType: listType, Query: query, - Page: int64(page), - Pages: int64(pagedHits.Pages), - Jobs: pagedHits.Hits, - Start: int64(pagedHits.Start), - End: int64(pagedHits.End), - Length: int64(len(hitsJson)), - - URL: req.URL, + Page: page, + PerPage: joblistPerPage(req), + URL: req.URL, } + output.searchQueueAndPopulateResults() + err = templates.ExecuteTemplate(rep, "joblist", output) return } -func newPagedHits(hits []string, pageSize int, pageWanted int, queueName string) *PagedHits { - if pageWanted < 1 { - pageWanted = 1 - } - - start := 1 - end := pageSize - - totalHits := len(hits) - totalPages := int(math.Ceil(float64(totalHits) / float64(pageSize))) +func (output *joblistOutputType) searchQueueAndPopulateResults() (err error) { + jsonResults := searchQueue(output.Query, output.QueueName, output.ListType) - maxStart := (pageWanted - 1) * pageSize - maxEnd := (pageWanted * pageSize) - 1 + output.Length = int64(len(jsonResults)) + output.pageCalculate() - if maxStart > totalHits { - start = totalHits - } else { - start = maxStart + if output.Length == 0 { + return } - if (maxEnd + 1) > totalHits { - end = totalHits - } else { - end = maxEnd + 1 - } + start := output.Start - 1 + end := output.End - hitsTask := []*task.Task{} - for _, taskJson := range hits[start:end] { - t, err := task.NewFromJson(taskJson, queueName) + output.Jobs = []*task.Task{} + for _, json := range jsonResults[start:end] { + t, err := task.NewFromJson(json, output.QueueName) if err != nil { - log.Printf("Couldn't construct task.Task from %+v", taskJson) + log.Printf("Couldn't construct task.Task from %+v", json) continue } - hitsTask = append(hitsTask, t) + output.Jobs = append(output.Jobs, t) } - // log.Printf("page %d: start: %d end: %d total pages: %d", pageWanted, start, end, totalPages) - - return &PagedHits{Hits: hitsTask, Start: start + 1, End: end, PageWanted: pageWanted, Pages: totalPages} + task.PopulateHasLog(output.Jobs) + return } -func searchQueryParams(rq string) (query string, queue string, listType string, page int) { +func searchQueryParams(rq string) (query string, queue string, listType string, page int64) { params, err := url.ParseQuery(rq) if err != nil { log.Printf("Malformed URL query: %s err: %s", rq, err) @@ -112,15 +72,15 @@ func searchQueryParams(rq string) (query string, queue string, listType string, listType = "done" } - page = 1 - if pg, err := strconv.Atoi(params.Get("page")); err == nil && pg > 1 { - page = pg + page, _ = strconv.ParseInt(params.Get("page"), 10, 0) + if page < 1 { + page = 1 } return query, queue, listType, page } -func searchQueueForCommand(query, queueName, listType string) []string { +func searchQueue(query, queueName, listType string) []string { r := myredis.Get() queueKey := fmt.Sprintf("%s:queue:%s:%s", redisHeader, queueName, listType)