Monorepo for Tangled tangled.org

appview: add basic issue indexer (wip) #494

merged opened by boltless.me targeting master from boltless.me/core: feat/search
  • Heavily inspired by gitea
  • add GetAllIssues which only receives a paginator and gathers all issues ignoring repoAt field

Signed-off-by: Seongmin Lee boltlessengineer@proton.me

Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:xasnlahkri4ewmbuzly2rlc5/sh.tangled.repo.pull/3lwecnvoz4z22
+94 -209
Interdiff #3 #4
.gitignore

This file has not been changed.

-56
appview/db/issues.go
··· 106 106 return ownerDid, err 107 107 } 108 108 109 - func GetAllIssues(e Execer, page pagination.Page) ([]Issue, error) { 110 - var issues []Issue 111 - rows, err := e.Query( 112 - ` 113 - select 114 - i.id, 115 - i.owner_did, 116 - i.repo_at, 117 - i.issue_id, 118 - i.created, 119 - i.title, 120 - i.body, 121 - i.open, 122 - count(c.id) as comment_count 123 - from 124 - issues i 125 - left join 126 - comments c on i.repo_at = c.repo_at and i.issue_id = c.issue_id 127 - group by 128 - i.id 129 - order by i.created desc 130 - limit ? offset ?`, 131 - page.Limit, 132 - page.Offset, 133 - ) 134 - if err != nil { 135 - return nil, err 136 - } 137 - defer rows.Close() 138 - 139 - for rows.Next() { 140 - var issue Issue 141 - var createdAt string 142 - var metadata IssueMetadata 143 - err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.RepoAt, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) 144 - if err != nil { 145 - return nil, err 146 - } 147 - 148 - createdTime, err := time.Parse(time.RFC3339, createdAt) 149 - if err != nil { 150 - return nil, err 151 - } 152 - issue.Created = createdTime 153 - issue.Metadata = &metadata 154 - 155 - issues = append(issues, issue) 156 - } 157 - 158 - if err := rows.Err(); err != nil { 159 - return nil, err 160 - } 161 - 162 - return issues, nil 163 - } 164 - 165 109 func GetIssuesPaginated(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) ([]Issue, error) { 166 110 var issues []Issue 167 111 openValue := 0
appview/indexer/base36/base36.go

This file has not been changed.

appview/indexer/bleve/batch.go

This file has not been changed.

+9 -4
appview/indexer/indexer.go
··· 2 2 3 3 import ( 4 4 "context" 5 + "log/slog" 5 6 6 - "tangled.sh/tangled.sh/core/appview/db" 7 - issues_indexer "tangled.sh/tangled.sh/core/appview/indexer/issues" 8 - "tangled.sh/tangled.sh/core/appview/notify" 7 + "tangled.org/core/appview/db" 8 + issues_indexer "tangled.org/core/appview/indexer/issues" 9 + "tangled.org/core/appview/notify" 10 + tlog "tangled.org/core/log" 9 11 ) 10 12 11 13 type Indexer struct { 12 14 Issues *issues_indexer.Indexer 15 + logger *slog.Logger 13 16 notify.BaseNotifier 14 17 } 15 18 16 - func New() *Indexer { 19 + func New(logger *slog.Logger) *Indexer { 17 20 return &Indexer { 18 21 issues_indexer.NewIndexer("indexes.bleve"), 22 + logger, 19 23 notify.BaseNotifier{}, 20 24 } 21 25 } 22 26 23 27 // Init initializes all indexers 24 28 func (ix *Indexer) Init(ctx context.Context, db *db.DB) error { 29 + ctx = tlog.IntoContext(ctx, ix.logger) 25 30 ix.Issues.Init(ctx, db) 26 31 return nil 27 32 }
+42 -45
appview/indexer/issues/indexer.go
··· 3 3 import ( 4 4 "context" 5 5 "errors" 6 - "log" 7 6 "os" 8 7 9 8 "github.com/blevesearch/bleve/v2" 10 9 "github.com/blevesearch/bleve/v2/index/upsidedown" 11 10 "github.com/blevesearch/bleve/v2/search/query" 12 - "tangled.sh/tangled.sh/core/appview/db" 13 - "tangled.sh/tangled.sh/core/appview/indexer/base36" 14 - "tangled.sh/tangled.sh/core/appview/indexer/bleve" 15 - "tangled.sh/tangled.sh/core/appview/models" 16 - "tangled.sh/tangled.sh/core/appview/pagination" 11 + "tangled.org/core/appview/db" 12 + "tangled.org/core/appview/indexer/base36" 13 + "tangled.org/core/appview/indexer/bleve" 14 + "tangled.org/core/appview/models" 15 + "tangled.org/core/appview/pagination" 16 + tlog "tangled.org/core/log" 17 17 ) 18 18 19 19 type Indexer struct { ··· 29 29 30 30 // Init initializes the indexer 31 31 func (ix *Indexer) Init(ctx context.Context, e db.Execer) { 32 + l := tlog.FromContext(ctx) 32 33 existed, err := ix.intialize(ctx) 33 34 if err != nil { 34 - log.Fatalf("failed to initialize issue indexer: %v", err) 35 + l.Error("failed to initialize issue indexer", "err", err) 35 36 } 36 37 if !existed { 37 - log.Println("Populating the issue indexer") 38 + l.Debug("Populating the issue indexer") 38 39 err := PopulateIndexer(ctx, ix, e) 39 40 if err != nil { 40 - log.Fatalf("failed to populate issue indexer: %v", err) 41 + l.Error("failed to populate issue indexer", "err", err) 41 42 } 42 43 } 43 - log.Println("Initialized the issue indexer") 44 + l.Info("Initialized the issue indexer") 44 45 } 45 46 46 - func (ix *Indexer) intialize(_ context.Context) (bool, error) { 47 + func (ix *Indexer) intialize(ctx context.Context) (bool, error) { 47 48 if ix.indexer != nil { 48 49 return false, errors.New("indexer is already initialized") 49 50 } 50 51 51 - indexer, err := openIndexer(ix.path) 52 + indexer, err := openIndexer(ctx, ix.path) 52 53 if err != nil { 53 - return false, nil 54 + return false, err 54 55 } 55 56 if indexer != nil { 56 57 ix.indexer = indexer ··· 68 69 return false, nil 69 70 } 70 71 71 - func openIndexer(path string) (bleve.Index, error) { 72 - _, err := os.Stat(path) 72 + func openIndexer(ctx context.Context, path string) (bleve.Index, error) { 73 + l := tlog.FromContext(ctx) 73 74 indexer, err := bleve.Open(path) 74 75 if err != nil { 75 76 if errors.Is(err, upsidedown.IncompatibleVersion) { 76 - log.Println("Indexer was built with a previous version of bleve, deleting and rebuilding") 77 + l.Info("Indexer was built with a previous version of bleve, deleting and rebuilding") 77 78 return nil, os.RemoveAll(path) 78 79 } 79 80 return nil, nil ··· 82 83 } 83 84 84 85 func PopulateIndexer(ctx context.Context, ix *Indexer, e db.Execer) error { 85 - page := pagination.FirstPage() 86 - for { 87 - issues, err := db.GetAllIssues(e, page) 88 - if err != nil { 89 - return err 90 - } 91 - var dataList []*IssueData 92 - for _, issue := range issues { 93 - issue, _, err := db.GetIssueWithComments(e, issue.RepoAt, issue.IssueId) 94 - if err != nil { 95 - return err 86 + l := tlog.FromContext(ctx) 87 + count := 0 88 + err := pagination.IterateAll( 89 + func(page pagination.Page) ([]models.Issue, error) { 90 + return db.GetIssuesPaginated(e, page) 91 + }, 92 + func(issues []models.Issue) error { 93 + var dataList []*IssueData 94 + for _, issue := range issues { 95 + dataList = append(dataList, &IssueData{ 96 + ID: issue.Id, 97 + IssueID: issue.IssueId, 98 + Title: issue.Title, 99 + Body: issue.Body, 100 + IsOpen: issue.Open, 101 + }) 102 + err := ix.Index(ctx, dataList...) 103 + if err != nil { 104 + return err 105 + } 96 106 } 97 - dataList = append(dataList, &IssueData{ 98 - ID: issue.ID, 99 - IssueID: issue.IssueId, 100 - Title: issue.Title, 101 - Body: issue.Body, 102 - IsOpen: issue.Open, 103 - }) 104 - } 105 - err = ix.Index(ctx, dataList...) 106 - if err != nil { 107 - return err 108 - } 109 - if len(issues) < page.Limit { 110 - break 111 - } 112 - page = page.Next() 113 - } 114 - return nil 107 + return nil 108 + }, 109 + ) 110 + l.Info("issues indexed", "count", count) 111 + return err 115 112 } 116 113 117 114 // IssueData data stored and will be indexed
+6 -6
appview/indexer/notifier.go
··· 3 3 import ( 4 4 "context" 5 5 6 - "tangled.sh/tangled.sh/core/appview/db" 7 - issues_indexer "tangled.sh/tangled.sh/core/appview/indexer/issues" 8 - "tangled.sh/tangled.sh/core/appview/notify" 6 + issues_indexer "tangled.org/core/appview/indexer/issues" 7 + "tangled.org/core/appview/models" 8 + "tangled.org/core/appview/notify" 9 9 ) 10 10 11 11 var _ notify.Notifier = &Indexer{} 12 12 13 - func (ix *Indexer) NewIssue(ctx context.Context, issue *db.Issue) { 13 + func (ix *Indexer) NewIssue(ctx context.Context, issue *models.Issue) { 14 14 ix.Issues.Index(ctx, &issues_indexer.IssueData{ 15 - ID: issue.ID, 15 + ID: issue.Id, 16 16 IssueID: issue.IssueId, 17 17 Title: issue.Title, 18 18 Body: issue.Body, ··· 21 21 }) 22 22 } 23 23 24 - func (ix *Indexer) NewPullComment(ctx context.Context, comment *db.PullComment) { 24 + func (ix *Indexer) NewPullComment(ctx context.Context, comment *models.PullComment) { 25 25 panic("unimplemented") 26 26 }
appview/issues/issues.go

This patch was likely rebased, as context lines do not match.

+1 -1
appview/models/search.go
··· 1 1 package models 2 2 3 - import "tangled.sh/tangled.sh/core/appview/pagination" 3 + import "tangled.org/core/appview/pagination" 4 4 5 5 type IssueSearchOptions struct { 6 6 Keyword string
+1 -1
appview/pages/pages.go
··· 781 781 Issues []db.Issue 782 782 Page pagination.Page 783 783 FilteringByOpen bool 784 - FilterQuery string 785 784 } 786 785 787 786 func (p *Pages) RepoIssues(w io.Writer, params RepoIssuesParams) error { ··· 971 970 LabelDefs map[string]*models.LabelDefinition 972 971 Page pagination.Page 973 972 FilteringByOpen bool 973 + FilterQuery string 974 974 } 975 975 976 976 func (p *Pages) RepoIssues(w io.Writer, params RepoIssuesParams) error {
+2 -1
appview/state/router.go
··· 230 230 } 231 231 232 232 func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { 233 - issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.indexer.Issues) 233 + issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier) 234 234 return issues.Router(mw) 235 235 } 236 236 ··· 262 262 s.config, 263 263 s.notifier, 264 264 s.validator, 265 + s.indexer.Issues, 265 266 log.SubLogger(s.logger, "issues"), 266 267 ) 267 268 return issues.Router(mw)
+10 -10
appview/state/state.go
··· 14 14 "tangled.org/core/appview" 15 15 "tangled.org/core/appview/config" 16 16 "tangled.org/core/appview/db" 17 + "tangled.org/core/appview/indexer" 17 18 "tangled.org/core/appview/models" 18 19 "tangled.org/core/appview/notify" 19 20 dbnotify "tangled.org/core/appview/notify/db" 20 21 "tangled.sh/tangled.sh/core/appview/cache/session" 21 22 "tangled.sh/tangled.sh/core/appview/config" 22 23 "tangled.sh/tangled.sh/core/appview/db" 23 - "tangled.sh/tangled.sh/core/appview/indexer" 24 24 "tangled.sh/tangled.sh/core/appview/notify" 25 25 "tangled.sh/tangled.sh/core/appview/oauth" 26 26 "tangled.sh/tangled.sh/core/appview/pages" ··· 38 38 type State struct { 39 39 db *db.DB 40 40 notifier notify.Notifier 41 - indexer *indexer.Indexer 42 41 oauth *oauth.OAuth 43 42 enforcer *rbac.Enforcer 44 43 pages *pages.Pages 45 44 type State struct { 46 45 db *db.DB 47 46 notifier notify.Notifier 47 + indexer *indexer.Indexer 48 48 oauth *oauth.OAuth 49 49 enforcer *rbac.Enforcer 50 50 pages *pages.Pages ··· 58 58 return nil, fmt.Errorf("failed to create db: %w", err) 59 59 } 60 60 61 - indexer := indexer.New() 62 - err = indexer.Init(ctx, d) 63 - if err != nil { 64 - return nil, fmt.Errorf("failed to create indexer: %w", err) 65 - } 66 - 67 61 enforcer, err := rbac.NewEnforcer(config.Core.DbPath) 68 62 if err != nil { 69 63 return nil, fmt.Errorf("failed to create enforcer: %w", err) ··· 73 67 return nil, fmt.Errorf("failed to create db: %w", err) 74 68 } 75 69 70 + indexer := indexer.New(log.SubLogger(logger, "indexer")) 71 + err = indexer.Init(ctx, d) 72 + if err != nil { 73 + return nil, fmt.Errorf("failed to create indexer: %w", err) 74 + } 75 + 76 76 enforcer, err := rbac.NewEnforcer(config.Core.DbPath) 77 77 if err != nil { 78 78 return nil, fmt.Errorf("failed to create enforcer: %w", err) ··· 144 144 if !config.Core.Dev { 145 145 notifiers = append(notifiers, posthogService.NewPosthogNotifier(posthog)) 146 146 } 147 - notifiers = append(notifiers, indexer) 148 147 notifier := notify.NewMergedNotifier(notifiers...) 149 148 150 149 state := &State{ 151 150 d, 152 151 notifier, 153 - indexer, 154 152 oauth, 155 153 enforcer, 156 154 pgs, ··· 169 167 if !config.Core.Dev { 170 168 notifiers = append(notifiers, phnotify.NewPosthogNotifier(posthog)) 171 169 } 170 + notifiers = append(notifiers, indexer) 172 171 notifier := notify.NewMergedNotifier(notifiers...) 173 172 174 173 state := &State{ 175 174 d, 176 175 notifier, 176 + indexer, 177 177 oauth, 178 178 enforcer, 179 179 pages,
-27
go.mod
··· 53 53 dario.cat/mergo v1.0.1 // indirect 54 54 github.com/Microsoft/go-winio v0.6.2 // indirect 55 55 github.com/ProtonMail/go-crypto v1.3.0 // indirect 56 - github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect 57 56 github.com/alecthomas/repr v0.4.0 // indirect 58 57 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect 59 58 github.com/aymerick/douceur v0.2.0 // indirect 60 59 github.com/beorn7/perks v1.0.1 // indirect 61 - github.com/bits-and-blooms/bitset v1.22.0 // indirect 62 - github.com/blevesearch/bleve/v2 v2.5.3 // indirect 63 - github.com/blevesearch/bleve_index_api v1.2.8 // indirect 64 - github.com/blevesearch/geo v0.2.4 // indirect 65 - github.com/blevesearch/go-faiss v1.0.25 // indirect 66 - github.com/blevesearch/go-porterstemmer v1.0.3 // indirect 67 - github.com/blevesearch/gtreap v0.1.1 // indirect 68 - github.com/blevesearch/mmap-go v1.0.4 // indirect 69 - github.com/blevesearch/scorch_segment_api/v2 v2.3.10 // indirect 70 - github.com/blevesearch/segment v0.9.1 // indirect 71 - github.com/blevesearch/snowballstem v0.9.0 // indirect 72 - github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect 73 - github.com/blevesearch/vellum v1.1.0 // indirect 74 - github.com/blevesearch/zapx/v11 v11.4.2 // indirect 75 - github.com/blevesearch/zapx/v12 v12.4.2 // indirect 76 - github.com/blevesearch/zapx/v13 v13.4.2 // indirect 77 - github.com/blevesearch/zapx/v14 v14.4.2 // indirect 78 - github.com/blevesearch/zapx/v15 v15.4.2 // indirect 79 - github.com/blevesearch/zapx/v16 v16.2.4 // indirect 80 60 github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect 81 61 github.com/casbin/govaluate v1.3.0 // indirect 82 62 github.com/cenkalti/backoff/v4 v4.3.0 // indirect ··· 108 88 github.com/golang-jwt/jwt/v5 v5.2.3 // indirect 109 89 github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect 110 90 github.com/golang/mock v1.6.0 // indirect 111 - github.com/golang/protobuf v1.5.4 // indirect 112 - github.com/golang/snappy v0.0.4 // indirect 113 91 github.com/google/go-querystring v1.1.0 // indirect 114 92 github.com/gorilla/css v1.0.1 // indirect 115 93 github.com/gorilla/securecookie v1.1.2 // indirect ··· 135 113 github.com/ipfs/go-log v1.0.5 // indirect 136 114 github.com/ipfs/go-log/v2 v2.6.0 // indirect 137 115 github.com/ipfs/go-metrics-interface v0.3.0 // indirect 138 - github.com/json-iterator/go v1.1.12 // indirect 139 116 github.com/kevinburke/ssh_config v1.2.0 // indirect 140 117 github.com/klauspost/compress v1.18.0 // indirect 141 118 github.com/klauspost/cpuid/v2 v2.3.0 // indirect ··· 150 127 github.com/moby/docker-image-spec v1.3.1 // indirect 151 128 github.com/moby/sys/atomicwriter v0.1.0 // indirect 152 129 github.com/moby/term v0.5.2 // indirect 153 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 154 - github.com/modern-go/reflect2 v1.0.2 // indirect 155 130 github.com/morikuni/aec v1.0.0 // indirect 156 131 github.com/mr-tron/base58 v1.2.0 // indirect 157 - github.com/mschoch/smat v0.2.0 // indirect 158 132 github.com/multiformats/go-base32 v0.1.0 // indirect 159 133 github.com/multiformats/go-base36 v0.2.0 // indirect 160 134 github.com/multiformats/go-multibase v0.2.0 // indirect ··· 182 156 github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 183 157 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect 184 158 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect 185 - go.etcd.io/bbolt v1.4.0 // indirect 186 159 go.opentelemetry.io/auto/sdk v1.1.0 // indirect 187 160 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect 188 161 go.opentelemetry.io/otel v1.37.0 // indirect
-58
go.sum
··· 9 9 github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 10 10 github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= 11 11 github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= 12 - github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg= 13 - github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0= 14 12 github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= 15 13 github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= 16 14 github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= ··· 25 23 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= 26 24 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 27 25 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 28 - github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 29 - github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= 30 - github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 31 - github.com/blevesearch/bleve/v2 v2.5.3 h1:9l1xtKaETv64SZc1jc4Sy0N804laSa/LeMbYddq1YEM= 32 - github.com/blevesearch/bleve/v2 v2.5.3/go.mod h1:Z/e8aWjiq8HeX+nW8qROSxiE0830yQA071dwR3yoMzw= 33 - github.com/blevesearch/bleve_index_api v1.2.8 h1:Y98Pu5/MdlkRyLM0qDHostYo7i+Vv1cDNhqTeR4Sy6Y= 34 - github.com/blevesearch/bleve_index_api v1.2.8/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0= 35 - github.com/blevesearch/geo v0.2.4 h1:ECIGQhw+QALCZaDcogRTNSJYQXRtC8/m8IKiA706cqk= 36 - github.com/blevesearch/geo v0.2.4/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8= 37 - github.com/blevesearch/go-faiss v1.0.25 h1:lel1rkOUGbT1CJ0YgzKwC7k+XH0XVBHnCVWahdCXk4U= 38 - github.com/blevesearch/go-faiss v1.0.25/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk= 39 - github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= 40 - github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M= 41 - github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y= 42 - github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk= 43 - github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= 44 - github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= 45 - github.com/blevesearch/scorch_segment_api/v2 v2.3.10 h1:Yqk0XD1mE0fDZAJXTjawJ8If/85JxnLd8v5vG/jWE/s= 46 - github.com/blevesearch/scorch_segment_api/v2 v2.3.10/go.mod h1:Z3e6ChN3qyN35yaQpl00MfI5s8AxUJbpTR/DL8QOQ+8= 47 - github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= 48 - github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= 49 - github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s= 50 - github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs= 51 - github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A= 52 - github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ= 53 - github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w= 54 - github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y= 55 - github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs= 56 - github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc= 57 - github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE= 58 - github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58= 59 - github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks= 60 - github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk= 61 - github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0= 62 - github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8= 63 - github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k= 64 - github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw= 65 - github.com/blevesearch/zapx/v16 v16.2.4 h1:tGgfvleXTAkwsD5mEzgM3zCS/7pgocTCnO1oyAUjlww= 66 - github.com/blevesearch/zapx/v16 v16.2.4/go.mod h1:Rti/REtuuMmzwsI8/C/qIzRaEoSK/wiFYw5e5ctUKKs= 67 26 github.com/bluesky-social/indigo v0.0.0-20250724221105-5827c8fb61bb h1:BqMNDZMfXwiRTJ6NvQotJ0qInn37JH5U8E+TF01CFHQ= 68 27 github.com/bluesky-social/indigo v0.0.0-20250724221105-5827c8fb61bb/go.mod h1:0XUyOCRtL4/OiyeqMTmr6RlVHQMDgw3LS7CfibuZR5Q= 69 28 github.com/bluesky-social/jetstream v0.0.0-20241210005130-ea96859b93d1 h1:CFvRtYNSnWRAi/98M3O466t9dYuwtesNbu6FVPymRrA= ··· 193 152 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 194 153 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 195 154 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 196 - github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 197 - github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 198 - github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= 199 - github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 200 155 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 201 156 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 202 157 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= ··· 208 163 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 209 164 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 210 165 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 211 - github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 212 166 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 213 167 github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 214 168 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= ··· 291 245 github.com/ipfs/go-metrics-interface v0.3.0/go.mod h1:OxxQjZDGocXVdyTPocns6cOLwHieqej/jos7H4POwoY= 292 246 github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 293 247 github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 294 - github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 295 - github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 296 248 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 297 249 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 298 250 github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= ··· 344 296 github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= 345 297 github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= 346 298 github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= 347 - github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 348 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 349 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 350 - github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 351 - github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 352 299 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= 353 300 github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 354 301 github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= 355 302 github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 356 - github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= 357 - github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= 358 303 github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= 359 304 github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= 360 305 github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= ··· 494 439 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= 495 440 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q= 496 441 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I= 497 - go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= 498 - go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= 499 442 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 500 443 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 501 444 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= ··· 697 640 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 698 641 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 699 642 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 700 - gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 701 643 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 702 644 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 703 645 gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
+23
appview/pagination/page.go
··· 29 29 Limit: p.Limit, 30 30 } 31 31 } 32 + 33 + func IterateAll[T any]( 34 + fetch func(page Page) ([]T, error), 35 + handle func(items []T) error, 36 + ) error { 37 + page := FirstPage() 38 + for { 39 + items, err := fetch(page) 40 + if err != nil { 41 + return err 42 + } 43 + 44 + err = handle(items) 45 + if err != nil { 46 + return err 47 + } 48 + if len(items) < page.Limit { 49 + break 50 + } 51 + page = page.Next() 52 + } 53 + return nil 54 + }

History

15 rounds 2 comments
sign up or login to add to the discussion
1 commit
expand
appview: add basic issue indexer
expand 0 comments
pull request successfully merged
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 1 comment

this changeset largely lgtm!

1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 1 comment
  • this is an N+1 query, because we first get all issues and then make one query for each issue. understandably this only needs to happen when populating the indices but we could improve this by just making one query
  • we can use a pagination free API for getting issues with comments while populating indexer
  • more of a note to self: search index should also handle issue deletions
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer
expand 0 comments
1 commit
expand
appview: add basic issue indexer (wip)
expand 0 comments