···135135 db.AutoMigrate(SequenceTracker{})
136136 db.Exec("CREATE INDEX IF NOT EXISTS reposts_subject_idx ON reposts (subject)")
137137 db.Exec("CREATE INDEX IF NOT EXISTS posts_reply_to_idx ON posts (reply_to)")
138138+ db.Exec("CREATE INDEX IF NOT EXISTS posts_in_thread_idx ON posts (in_thread)")
138139139140 ctx := context.TODO()
140141
+38-12
xrpc/unspecced/getPostThreadV2.go
···77 "log/slog"
88 "net/http"
99 "strconv"
1010+ "sync"
10111112 "github.com/bluesky-social/indigo/api/bsky"
1213 "github.com/labstack/echo/v4"
1314 "github.com/whyrusleeping/konbini/hydration"
1415 "github.com/whyrusleeping/konbini/views"
1516 "github.com/whyrusleeping/market/models"
1717+ "go.opentelemetry.io/otel"
1618 "gorm.io/gorm"
1719)
2020+2121+var tracer = otel.Tracer("xrpc/unspecced")
18221923// HandleGetPostThreadV2 implements app.bsky.unspecced.getPostThreadV2
2024func HandleGetPostThreadV2(c echo.Context, db *gorm.DB, hydrator *hydration.Hydrator) error {
2121- ctx := c.Request().Context()
2525+ ctx, span := tracer.Start(c.Request().Context(), "getPostThreadV2")
2626+ defer span.End()
2227 ctx = context.WithValue(ctx, "auto-fetch", true)
23282429 // Parse parameters
···152157 return nil, nil
153158 }
154159155155- var out []*bsky.UnspeccedGetPostThreadV2_ThreadItem
156156- for _, child := range curnode.children {
157157- out = append(out, buildThreadItem(ctx, hydrator, child, depth+1, viewer))
158158- if child.missing {
159159- continue
160160- }
160160+ type parThreadResults struct {
161161+ node *bsky.UnspeccedGetPostThreadV2_ThreadItem
162162+ children []*bsky.UnspeccedGetPostThreadV2_ThreadItem
163163+ }
164164+165165+ results := make([]parThreadResults, len(curnode.children))
166166+167167+ var wg sync.WaitGroup
168168+ for i := range curnode.children {
169169+ ix := i
170170+ wg.Go(func() {
171171+ child := curnode.children[ix]
172172+173173+ results[ix].node = buildThreadItem(ctx, hydrator, child, depth+1, viewer)
174174+ if child.missing {
175175+ return
176176+ }
177177+178178+ sub, err := collectReplies(ctx, hydrator, child, depth+1, below-1, branchingFactor, sort, viewer)
179179+ if err != nil {
180180+ slog.Error("failed to collect replies", "node", child.uri, "error", err)
181181+ return
182182+ }
183183+184184+ results[ix].children = sub
185185+ })
186186+ }
161187162162- sub, err := collectReplies(ctx, hydrator, child, depth+1, below-1, branchingFactor, sort, viewer)
163163- if err != nil {
164164- return nil, err
165165- }
188188+ wg.Wait()
166189167167- out = append(out, sub...)
190190+ var out []*bsky.UnspeccedGetPostThreadV2_ThreadItem
191191+ for _, res := range results {
192192+ out = append(out, res.node)
193193+ out = append(out, res.children...)
168194 }
169195170196 return out, nil