Skip to content

Commit

Permalink
perpage setting applies to search results
Browse files Browse the repository at this point in the history
simplify search results code
  • Loading branch information
SergeyTsalkov committed Nov 15, 2019
1 parent d3b54e3 commit 8b8d118
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 111 deletions.
101 changes: 55 additions & 46 deletions web/joblist.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ import (
"strconv"

"brooce/task"

"github.com/go-redis/redis"
)

type joblistOutputType struct {
ListType string
QueueName string
Page int64
Pages int64
PerPage int64
Length int64
Start int64
End int64
Expand All @@ -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
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
}
90 changes: 25 additions & 65 deletions web/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package web
import (
"fmt"
"log"
"math"
"net/http"
"net/url"
"strconv"
Expand All @@ -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)
Expand All @@ -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)

Expand Down

0 comments on commit 8b8d118

Please sign in to comment.