···2727 "github.com/bluesky-social/indigo/models"
2828 "github.com/bluesky-social/indigo/repomgr"
2929 "github.com/bluesky-social/indigo/xrpc"
3030+ lru "github.com/hashicorp/golang-lru/v2"
3031 "golang.org/x/sync/semaphore"
3132 "golang.org/x/time/rate"
3233···87888889 // Management of Compaction
8990 compactor *Compactor
9191+9292+ // User cache
9393+ userCache *lru.Cache[string, *User]
9094}
91959296type PDSResync struct {
···136140 db.AutoMigrate(models.PDS{})
137141 db.AutoMigrate(models.DomainBan{})
138142143143+ uc, _ := lru.New[string, *User](1_000_000)
144144+139145 bgs := &BGS{
140146 Index: ix,
141147 db: db,
···151157 consumers: make(map[uint64]*SocketConsumer),
152158153159 pdsResyncs: make(map[uint]*PDSResync),
160160+161161+ userCache: uc,
154162 }
155163156164 ix.CreateExternalUser = bgs.createExternalUser
···521529522530 // UpstreamStatus is the state of the user as reported by the upstream PDS
523531 UpstreamStatus string `gorm:"index"`
532532+533533+ lk sync.Mutex
534534+}
535535+536536+func (u *User) SetTakenDown(v bool) {
537537+ u.lk.Lock()
538538+ defer u.lk.Unlock()
539539+ u.TakenDown = v
540540+}
541541+542542+func (u *User) GetTakenDown() bool {
543543+ u.lk.Lock()
544544+ defer u.lk.Unlock()
545545+ return u.TakenDown
546546+}
547547+548548+func (u *User) SetTombstoned(v bool) {
549549+ u.lk.Lock()
550550+ defer u.lk.Unlock()
551551+ u.Tombstoned = v
552552+}
553553+554554+func (u *User) GetTombstoned() bool {
555555+ u.lk.Lock()
556556+ defer u.lk.Unlock()
557557+ return u.Tombstoned
558558+}
559559+560560+func (u *User) SetUpstreamStatus(v string) {
561561+ u.lk.Lock()
562562+ defer u.lk.Unlock()
563563+ u.UpstreamStatus = v
564564+}
565565+566566+func (u *User) GetUpstreamStatus() string {
567567+ u.lk.Lock()
568568+ defer u.lk.Unlock()
569569+ return u.UpstreamStatus
524570}
525571526572type addTargetBody struct {
···771817 ctx, span := tracer.Start(ctx, "lookupUserByDid")
772818 defer span.End()
773819820820+ cu, ok := bgs.userCache.Get(did)
821821+ if ok {
822822+ return cu, nil
823823+ }
824824+774825 var u User
775826 if err := bgs.db.Find(&u, "did = ?", did).Error; err != nil {
776827 return nil, err
···779830 if u.ID == 0 {
780831 return nil, gorm.ErrRecordNotFound
781832 }
833833+834834+ bgs.userCache.Add(did, &u)
782835783836 return &u, nil
784837}
···840893 u.Did = evt.Repo
841894 }
842895843843- span.SetAttributes(attribute.String("upstream_status", u.UpstreamStatus))
896896+ ustatus := u.GetUpstreamStatus()
897897+ span.SetAttributes(attribute.String("upstream_status", ustatus))
844898845845- if u.TakenDown || u.UpstreamStatus == events.AccountStatusTakendown {
846846- span.SetAttributes(attribute.Bool("taken_down_by_relay_admin", u.TakenDown))
899899+ if u.GetTakenDown() || ustatus == events.AccountStatusTakendown {
900900+ span.SetAttributes(attribute.Bool("taken_down_by_relay_admin", u.GetTakenDown()))
847901 log.Debugw("dropping commit event from taken down user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
848902 return nil
849903 }
850904851851- if u.UpstreamStatus == events.AccountStatusSuspended {
905905+ if ustatus == events.AccountStatusSuspended {
852906 log.Debugw("dropping commit event from suspended user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
853907 return nil
854908 }
855909856856- if u.UpstreamStatus == events.AccountStatusDeactivated {
910910+ if ustatus == events.AccountStatusDeactivated {
857911 log.Debugw("dropping commit event from deactivated user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
858912 return nil
859913 }
···877931 }
878932 }
879933880880- if u.Tombstoned {
934934+ if u.GetTombstoned() {
881935 span.SetAttributes(attribute.Bool("tombstoned", true))
882936 // we've checked the authority of the users PDS, so reinstate the account
883937 if err := bgs.db.Model(&User{}).Where("id = ?", u.ID).UpdateColumn("tombstoned", false).Error; err != nil {
884938 return fmt.Errorf("failed to un-tombstone a user: %w", err)
885939 }
940940+ u.SetTombstoned(false)
886941887942 ai, err := bgs.Index.LookupUser(ctx, u.ID)
888943 if err != nil {
···10411096 return fmt.Errorf("failed to look up user by did: %w", err)
10421097 }
1043109810441044- if u.TakenDown {
10991099+ if u.GetTakenDown() {
10451100 shouldBeActive = false
10461101 status = &events.AccountStatusTakendown
10471102 }
···13701425 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusActive).Error; err != nil {
13711426 return fmt.Errorf("failed to set user active status: %w", err)
13721427 }
14281428+ u.SetUpstreamStatus(events.AccountStatusActive)
13731429 case events.AccountStatusDeactivated:
13741430 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusDeactivated).Error; err != nil {
13751431 return fmt.Errorf("failed to set user deactivation status: %w", err)
13761432 }
14331433+ u.SetUpstreamStatus(events.AccountStatusDeactivated)
13771434 case events.AccountStatusSuspended:
13781435 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusSuspended).Error; err != nil {
13791436 return fmt.Errorf("failed to set user suspension status: %w", err)
13801437 }
14381438+ u.SetUpstreamStatus(events.AccountStatusSuspended)
13811439 case events.AccountStatusTakendown:
13821440 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusTakendown).Error; err != nil {
13831441 return fmt.Errorf("failed to set user taken down status: %w", err)
13841442 }
14431443+ u.SetUpstreamStatus(events.AccountStatusTakendown)
1385144413861445 if err := bgs.db.Model(&models.ActorInfo{}).Where("uid = ?", u.ID).UpdateColumns(map[string]any{
13871446 "handle": nil,
···13961455 }).Error; err != nil {
13971456 return err
13981457 }
14581458+ u.SetUpstreamStatus(events.AccountStatusDeleted)
1399145914001460 if err := bgs.db.Model(&models.ActorInfo{}).Where("uid = ?", u.ID).UpdateColumns(map[string]any{
14011461 "handle": nil,
···14221482 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("taken_down", true).Error; err != nil {
14231483 return err
14241484 }
14851485+ u.SetTakenDown(true)
1425148614261487 if err := bgs.repoman.TakeDownRepo(ctx, u.ID); err != nil {
14271488 return err
···14431504 if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("taken_down", false).Error; err != nil {
14441505 return err
14451506 }
15071507+ u.SetTakenDown(false)
1446150814471509 return nil
14481510}
+1-1
bgs/compactor.go
···349349 return state, nil
350350}
351351352352-func (c *Compactor) EnqueueRepo(ctx context.Context, user User, fast bool) {
352352+func (c *Compactor) EnqueueRepo(ctx context.Context, user *User, fast bool) {
353353 ctx, span := otel.Tracer("compactor").Start(ctx, "EnqueueRepo")
354354 defer span.End()
355355 log.Infow("enqueueing compaction for repo", "repo", user.Did, "uid", user.ID, "fast", fast)
+18-15
bgs/handlers.go
···3434 return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
3535 }
36363737- if u.Tombstoned {
3737+ if u.GetTombstoned() {
3838 return nil, fmt.Errorf("account was deleted")
3939 }
40404141- if u.TakenDown {
4141+ if u.GetTakenDown() {
4242 return nil, fmt.Errorf("account was taken down by the Relay")
4343 }
44444545- if u.UpstreamStatus == events.AccountStatusTakendown {
4545+ ustatus := u.GetUpstreamStatus()
4646+ if ustatus == events.AccountStatusTakendown {
4647 return nil, fmt.Errorf("account was taken down by its PDS")
4748 }
48494949- if u.UpstreamStatus == events.AccountStatusDeactivated {
5050+ if ustatus == events.AccountStatusDeactivated {
5051 return nil, fmt.Errorf("account is temporarily deactivated")
5152 }
52535353- if u.UpstreamStatus == events.AccountStatusSuspended {
5454+ if ustatus == events.AccountStatusSuspended {
5455 return nil, fmt.Errorf("account is suspended by its PDS")
5556 }
5657···9192 return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
9293 }
93949494- if u.Tombstoned {
9595+ if u.GetTombstoned() {
9596 return nil, fmt.Errorf("account was deleted")
9697 }
97989898- if u.TakenDown {
9999+ if u.GetTakenDown() {
99100 return nil, fmt.Errorf("account was taken down by the Relay")
100101 }
101102102102- if u.UpstreamStatus == events.AccountStatusTakendown {
103103+ ustatus := u.GetUpstreamStatus()
104104+ if ustatus == events.AccountStatusTakendown {
103105 return nil, fmt.Errorf("account was taken down by its PDS")
104106 }
105107106106- if u.UpstreamStatus == events.AccountStatusDeactivated {
108108+ if ustatus == events.AccountStatusDeactivated {
107109 return nil, fmt.Errorf("account is temporarily deactivated")
108110 }
109111110110- if u.UpstreamStatus == events.AccountStatusSuspended {
112112+ if ustatus == events.AccountStatusSuspended {
111113 return nil, fmt.Errorf("account is suspended by its PDS")
112114 }
113115···253255 return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
254256 }
255257256256- if u.Tombstoned {
258258+ if u.GetTombstoned() {
257259 return nil, fmt.Errorf("account was deleted")
258260 }
259261260260- if u.TakenDown {
262262+ if u.GetTakenDown() {
261263 return nil, fmt.Errorf("account was taken down by the Relay")
262264 }
263265264264- if u.UpstreamStatus == events.AccountStatusTakendown {
266266+ ustatus := u.GetUpstreamStatus()
267267+ if ustatus == events.AccountStatusTakendown {
265268 return nil, fmt.Errorf("account was taken down by its PDS")
266269 }
267270268268- if u.UpstreamStatus == events.AccountStatusDeactivated {
271271+ if ustatus == events.AccountStatusDeactivated {
269272 return nil, fmt.Errorf("account is temporarily deactivated")
270273 }
271274272272- if u.UpstreamStatus == events.AccountStatusSuspended {
275275+ if ustatus == events.AccountStatusSuspended {
273276 return nil, fmt.Errorf("account is suspended by its PDS")
274277 }
275278