+7
-2
atproto/identity/identity.go
+7
-2
atproto/identity/identity.go
···
65
65
base := BaseDirectory{
66
66
PLCURL: DefaultPLCURL,
67
67
HTTPClient: http.Client{
68
-
Timeout: time.Second * 15,
68
+
Timeout: time.Second * 10,
69
+
Transport: &http.Transport{
70
+
// would want this around 100ms for services doing lots of handle resolution. Impacts PLC connections as well, but not too bad.
71
+
IdleConnTimeout: time.Millisecond * 1000,
72
+
MaxIdleConns: 100,
73
+
},
69
74
},
70
75
Resolver: net.Resolver{
71
76
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
72
-
d := net.Dialer{Timeout: time.Second * 5}
77
+
d := net.Dialer{Timeout: time.Second * 3}
73
78
return d.DialContext(ctx, network, address)
74
79
},
75
80
},
+74
-7
bgs/bgs.go
+74
-7
bgs/bgs.go
···
27
27
"github.com/bluesky-social/indigo/models"
28
28
"github.com/bluesky-social/indigo/repomgr"
29
29
"github.com/bluesky-social/indigo/xrpc"
30
+
lru "github.com/hashicorp/golang-lru/v2"
30
31
"golang.org/x/sync/semaphore"
31
32
"golang.org/x/time/rate"
32
33
···
87
88
88
89
// Management of Compaction
89
90
compactor *Compactor
91
+
92
+
// User cache
93
+
userCache *lru.Cache[string, *User]
90
94
}
91
95
92
96
type PDSResync struct {
···
136
140
db.AutoMigrate(models.PDS{})
137
141
db.AutoMigrate(models.DomainBan{})
138
142
143
+
uc, _ := lru.New[string, *User](1_000_000)
144
+
139
145
bgs := &BGS{
140
146
Index: ix,
141
147
db: db,
···
151
157
consumers: make(map[uint64]*SocketConsumer),
152
158
153
159
pdsResyncs: make(map[uint]*PDSResync),
160
+
161
+
userCache: uc,
154
162
}
155
163
156
164
ix.CreateExternalUser = bgs.createExternalUser
···
521
529
522
530
// UpstreamStatus is the state of the user as reported by the upstream PDS
523
531
UpstreamStatus string `gorm:"index"`
532
+
533
+
lk sync.Mutex
534
+
}
535
+
536
+
func (u *User) SetTakenDown(v bool) {
537
+
u.lk.Lock()
538
+
defer u.lk.Unlock()
539
+
u.TakenDown = v
540
+
}
541
+
542
+
func (u *User) GetTakenDown() bool {
543
+
u.lk.Lock()
544
+
defer u.lk.Unlock()
545
+
return u.TakenDown
546
+
}
547
+
548
+
func (u *User) SetTombstoned(v bool) {
549
+
u.lk.Lock()
550
+
defer u.lk.Unlock()
551
+
u.Tombstoned = v
552
+
}
553
+
554
+
func (u *User) GetTombstoned() bool {
555
+
u.lk.Lock()
556
+
defer u.lk.Unlock()
557
+
return u.Tombstoned
558
+
}
559
+
560
+
func (u *User) SetUpstreamStatus(v string) {
561
+
u.lk.Lock()
562
+
defer u.lk.Unlock()
563
+
u.UpstreamStatus = v
564
+
}
565
+
566
+
func (u *User) GetUpstreamStatus() string {
567
+
u.lk.Lock()
568
+
defer u.lk.Unlock()
569
+
return u.UpstreamStatus
524
570
}
525
571
526
572
type addTargetBody struct {
···
771
817
ctx, span := tracer.Start(ctx, "lookupUserByDid")
772
818
defer span.End()
773
819
820
+
cu, ok := bgs.userCache.Get(did)
821
+
if ok {
822
+
return cu, nil
823
+
}
824
+
774
825
var u User
775
826
if err := bgs.db.Find(&u, "did = ?", did).Error; err != nil {
776
827
return nil, err
···
779
830
if u.ID == 0 {
780
831
return nil, gorm.ErrRecordNotFound
781
832
}
833
+
834
+
bgs.userCache.Add(did, &u)
782
835
783
836
return &u, nil
784
837
}
···
823
876
repoCommitsReceivedCounter.WithLabelValues(host.Host).Add(1)
824
877
evt := env.RepoCommit
825
878
log.Debugw("bgs got repo append event", "seq", evt.Seq, "pdsHost", host.Host, "repo", evt.Repo)
879
+
880
+
s := time.Now()
826
881
u, err := bgs.lookupUserByDid(ctx, evt.Repo)
882
+
userLookupDuration.Observe(time.Since(s).Seconds())
827
883
if err != nil {
828
884
if !errors.Is(err, gorm.ErrRecordNotFound) {
829
885
return fmt.Errorf("looking up event user: %w", err)
830
886
}
831
887
832
888
newUsersDiscovered.Inc()
889
+
start := time.Now()
833
890
subj, err := bgs.createExternalUser(ctx, evt.Repo)
891
+
newUserDiscoveryDuration.Observe(time.Since(start).Seconds())
834
892
if err != nil {
835
893
return fmt.Errorf("fed event create external user: %w", err)
836
894
}
···
840
898
u.Did = evt.Repo
841
899
}
842
900
843
-
span.SetAttributes(attribute.String("upstream_status", u.UpstreamStatus))
901
+
ustatus := u.GetUpstreamStatus()
902
+
span.SetAttributes(attribute.String("upstream_status", ustatus))
844
903
845
-
if u.TakenDown || u.UpstreamStatus == events.AccountStatusTakendown {
846
-
span.SetAttributes(attribute.Bool("taken_down_by_relay_admin", u.TakenDown))
904
+
if u.GetTakenDown() || ustatus == events.AccountStatusTakendown {
905
+
span.SetAttributes(attribute.Bool("taken_down_by_relay_admin", u.GetTakenDown()))
847
906
log.Debugw("dropping commit event from taken down user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
848
907
return nil
849
908
}
850
909
851
-
if u.UpstreamStatus == events.AccountStatusSuspended {
910
+
if ustatus == events.AccountStatusSuspended {
852
911
log.Debugw("dropping commit event from suspended user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
853
912
return nil
854
913
}
855
914
856
-
if u.UpstreamStatus == events.AccountStatusDeactivated {
915
+
if ustatus == events.AccountStatusDeactivated {
857
916
log.Debugw("dropping commit event from deactivated user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host)
858
917
return nil
859
918
}
···
877
936
}
878
937
}
879
938
880
-
if u.Tombstoned {
939
+
if u.GetTombstoned() {
881
940
span.SetAttributes(attribute.Bool("tombstoned", true))
882
941
// we've checked the authority of the users PDS, so reinstate the account
883
942
if err := bgs.db.Model(&User{}).Where("id = ?", u.ID).UpdateColumn("tombstoned", false).Error; err != nil {
884
943
return fmt.Errorf("failed to un-tombstone a user: %w", err)
885
944
}
945
+
u.SetTombstoned(false)
886
946
887
947
ai, err := bgs.Index.LookupUser(ctx, u.ID)
888
948
if err != nil {
···
1041
1101
return fmt.Errorf("failed to look up user by did: %w", err)
1042
1102
}
1043
1103
1044
-
if u.TakenDown {
1104
+
if u.GetTakenDown() {
1045
1105
shouldBeActive = false
1046
1106
status = &events.AccountStatusTakendown
1047
1107
}
···
1370
1430
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusActive).Error; err != nil {
1371
1431
return fmt.Errorf("failed to set user active status: %w", err)
1372
1432
}
1433
+
u.SetUpstreamStatus(events.AccountStatusActive)
1373
1434
case events.AccountStatusDeactivated:
1374
1435
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusDeactivated).Error; err != nil {
1375
1436
return fmt.Errorf("failed to set user deactivation status: %w", err)
1376
1437
}
1438
+
u.SetUpstreamStatus(events.AccountStatusDeactivated)
1377
1439
case events.AccountStatusSuspended:
1378
1440
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusSuspended).Error; err != nil {
1379
1441
return fmt.Errorf("failed to set user suspension status: %w", err)
1380
1442
}
1443
+
u.SetUpstreamStatus(events.AccountStatusSuspended)
1381
1444
case events.AccountStatusTakendown:
1382
1445
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("upstream_status", events.AccountStatusTakendown).Error; err != nil {
1383
1446
return fmt.Errorf("failed to set user taken down status: %w", err)
1384
1447
}
1448
+
u.SetUpstreamStatus(events.AccountStatusTakendown)
1385
1449
1386
1450
if err := bgs.db.Model(&models.ActorInfo{}).Where("uid = ?", u.ID).UpdateColumns(map[string]any{
1387
1451
"handle": nil,
···
1396
1460
}).Error; err != nil {
1397
1461
return err
1398
1462
}
1463
+
u.SetUpstreamStatus(events.AccountStatusDeleted)
1399
1464
1400
1465
if err := bgs.db.Model(&models.ActorInfo{}).Where("uid = ?", u.ID).UpdateColumns(map[string]any{
1401
1466
"handle": nil,
···
1422
1487
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("taken_down", true).Error; err != nil {
1423
1488
return err
1424
1489
}
1490
+
u.SetTakenDown(true)
1425
1491
1426
1492
if err := bgs.repoman.TakeDownRepo(ctx, u.ID); err != nil {
1427
1493
return err
···
1443
1509
if err := bgs.db.Model(User{}).Where("id = ?", u.ID).Update("taken_down", false).Error; err != nil {
1444
1510
return err
1445
1511
}
1512
+
u.SetTakenDown(false)
1446
1513
1447
1514
return nil
1448
1515
}
+1
-1
bgs/compactor.go
+1
-1
bgs/compactor.go
···
349
349
return state, nil
350
350
}
351
351
352
-
func (c *Compactor) EnqueueRepo(ctx context.Context, user User, fast bool) {
352
+
func (c *Compactor) EnqueueRepo(ctx context.Context, user *User, fast bool) {
353
353
ctx, span := otel.Tracer("compactor").Start(ctx, "EnqueueRepo")
354
354
defer span.End()
355
355
log.Infow("enqueueing compaction for repo", "repo", user.Did, "uid", user.ID, "fast", fast)
+18
-15
bgs/handlers.go
+18
-15
bgs/handlers.go
···
34
34
return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
35
35
}
36
36
37
-
if u.Tombstoned {
37
+
if u.GetTombstoned() {
38
38
return nil, fmt.Errorf("account was deleted")
39
39
}
40
40
41
-
if u.TakenDown {
41
+
if u.GetTakenDown() {
42
42
return nil, fmt.Errorf("account was taken down by the Relay")
43
43
}
44
44
45
-
if u.UpstreamStatus == events.AccountStatusTakendown {
45
+
ustatus := u.GetUpstreamStatus()
46
+
if ustatus == events.AccountStatusTakendown {
46
47
return nil, fmt.Errorf("account was taken down by its PDS")
47
48
}
48
49
49
-
if u.UpstreamStatus == events.AccountStatusDeactivated {
50
+
if ustatus == events.AccountStatusDeactivated {
50
51
return nil, fmt.Errorf("account is temporarily deactivated")
51
52
}
52
53
53
-
if u.UpstreamStatus == events.AccountStatusSuspended {
54
+
if ustatus == events.AccountStatusSuspended {
54
55
return nil, fmt.Errorf("account is suspended by its PDS")
55
56
}
56
57
···
91
92
return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
92
93
}
93
94
94
-
if u.Tombstoned {
95
+
if u.GetTombstoned() {
95
96
return nil, fmt.Errorf("account was deleted")
96
97
}
97
98
98
-
if u.TakenDown {
99
+
if u.GetTakenDown() {
99
100
return nil, fmt.Errorf("account was taken down by the Relay")
100
101
}
101
102
102
-
if u.UpstreamStatus == events.AccountStatusTakendown {
103
+
ustatus := u.GetUpstreamStatus()
104
+
if ustatus == events.AccountStatusTakendown {
103
105
return nil, fmt.Errorf("account was taken down by its PDS")
104
106
}
105
107
106
-
if u.UpstreamStatus == events.AccountStatusDeactivated {
108
+
if ustatus == events.AccountStatusDeactivated {
107
109
return nil, fmt.Errorf("account is temporarily deactivated")
108
110
}
109
111
110
-
if u.UpstreamStatus == events.AccountStatusSuspended {
112
+
if ustatus == events.AccountStatusSuspended {
111
113
return nil, fmt.Errorf("account is suspended by its PDS")
112
114
}
113
115
···
253
255
return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user")
254
256
}
255
257
256
-
if u.Tombstoned {
258
+
if u.GetTombstoned() {
257
259
return nil, fmt.Errorf("account was deleted")
258
260
}
259
261
260
-
if u.TakenDown {
262
+
if u.GetTakenDown() {
261
263
return nil, fmt.Errorf("account was taken down by the Relay")
262
264
}
263
265
264
-
if u.UpstreamStatus == events.AccountStatusTakendown {
266
+
ustatus := u.GetUpstreamStatus()
267
+
if ustatus == events.AccountStatusTakendown {
265
268
return nil, fmt.Errorf("account was taken down by its PDS")
266
269
}
267
270
268
-
if u.UpstreamStatus == events.AccountStatusDeactivated {
271
+
if ustatus == events.AccountStatusDeactivated {
269
272
return nil, fmt.Errorf("account is temporarily deactivated")
270
273
}
271
274
272
-
if u.UpstreamStatus == events.AccountStatusSuspended {
275
+
if ustatus == events.AccountStatusSuspended {
273
276
return nil, fmt.Errorf("account is suspended by its PDS")
274
277
}
275
278
+12
bgs/metrics.go
+12
bgs/metrics.go
···
81
81
Buckets: prometheus.ExponentialBuckets(100, 10, 8),
82
82
}, []string{"code", "method", "path"})
83
83
84
+
var userLookupDuration = promauto.NewHistogram(prometheus.HistogramOpts{
85
+
Name: "relay_user_lookup_duration",
86
+
Help: "A histogram of user lookup latencies",
87
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
88
+
})
89
+
90
+
var newUserDiscoveryDuration = promauto.NewHistogram(prometheus.HistogramOpts{
91
+
Name: "relay_new_user_discovery_duration",
92
+
Help: "A histogram of new user discovery latencies",
93
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
94
+
})
95
+
84
96
// MetricsMiddleware defines handler function for metrics middleware
85
97
func MetricsMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
86
98
return func(c echo.Context) error {
+24
-13
carstore/bs.go
+24
-13
carstore/bs.go
···
62
62
}
63
63
64
64
type FileCarStore struct {
65
-
meta *CarStoreGormMeta
66
-
rootDir string
65
+
meta *CarStoreGormMeta
66
+
rootDirs []string
67
67
68
68
lscLk sync.Mutex
69
69
lastShardCache map[models.Uid]*CarShard
70
70
}
71
71
72
-
func NewCarStore(meta *gorm.DB, root string) (CarStore, error) {
73
-
if _, err := os.Stat(root); err != nil {
74
-
if !os.IsNotExist(err) {
75
-
return nil, err
76
-
}
72
+
func NewCarStore(meta *gorm.DB, roots []string) (CarStore, error) {
73
+
for _, root := range roots {
74
+
if _, err := os.Stat(root); err != nil {
75
+
if !os.IsNotExist(err) {
76
+
return nil, err
77
+
}
77
78
78
-
if err := os.Mkdir(root, 0775); err != nil {
79
-
return nil, err
79
+
if err := os.Mkdir(root, 0775); err != nil {
80
+
return nil, err
81
+
}
80
82
}
81
83
}
82
84
if err := meta.AutoMigrate(&CarShard{}, &blockRef{}); err != nil {
···
88
90
89
91
return &FileCarStore{
90
92
meta: &CarStoreGormMeta{meta: meta},
91
-
rootDir: root,
93
+
rootDirs: roots,
92
94
lastShardCache: make(map[models.Uid]*CarShard),
93
95
}, nil
94
96
}
···
541
543
func fnameForShard(user models.Uid, seq int) string {
542
544
return fmt.Sprintf("sh-%d-%d", user, seq)
543
545
}
546
+
547
+
func (cs *FileCarStore) dirForUser(user models.Uid) string {
548
+
return cs.rootDirs[int(user)%len(cs.rootDirs)]
549
+
}
550
+
544
551
func (cs *FileCarStore) openNewShardFile(ctx context.Context, user models.Uid, seq int) (*os.File, string, error) {
545
552
// TODO: some overwrite protections
546
-
fname := filepath.Join(cs.rootDir, fnameForShard(user, seq))
553
+
fname := filepath.Join(cs.dirForUser(user), fnameForShard(user, seq))
547
554
fi, err := os.Create(fname)
548
555
if err != nil {
549
556
return nil, "", err
···
557
564
defer span.End()
558
565
559
566
// TODO: some overwrite protections
560
-
fname := filepath.Join(cs.rootDir, fnameForShard(user, seq))
567
+
fname := filepath.Join(cs.dirForUser(user), fnameForShard(user, seq))
561
568
if err := os.WriteFile(fname, data, 0664); err != nil {
562
569
return "", err
563
570
}
···
638
645
offset += nw
639
646
}
640
647
648
+
start := time.Now()
641
649
path, err := cs.writeNewShardFile(ctx, user, seq, buf.Bytes())
642
650
if err != nil {
643
651
return nil, fmt.Errorf("failed to write shard file: %w", err)
644
652
}
653
+
writeShardFileDuration.Observe(time.Since(start).Seconds())
645
654
646
655
shard := CarShard{
647
656
Root: models.DbCID{CID: root},
···
652
661
Rev: rev,
653
662
}
654
663
664
+
start = time.Now()
655
665
if err := cs.putShard(ctx, &shard, brefs, rmcids, false); err != nil {
656
666
return nil, err
657
667
}
668
+
writeShardMetadataDuration.Observe(time.Since(start).Seconds())
658
669
659
670
return buf.Bytes(), nil
660
671
}
···
982
993
// TODO: some overwrite protections
983
994
// NOTE CreateTemp is used for creating a non-colliding file, but we keep it and don't delete it so don't think of it as "temporary".
984
995
// This creates "sh-%d-%d%s" with some random stuff in the last position
985
-
fi, err := os.CreateTemp(cs.rootDir, fnameForShard(user, seq))
996
+
fi, err := os.CreateTemp(cs.dirForUser(user), fnameForShard(user, seq))
986
997
if err != nil {
987
998
return nil, "", err
988
999
}
+18
carstore/metrics.go
+18
carstore/metrics.go
···
1
+
package carstore
2
+
3
+
import (
4
+
"github.com/prometheus/client_golang/prometheus"
5
+
"github.com/prometheus/client_golang/prometheus/promauto"
6
+
)
7
+
8
+
var writeShardFileDuration = promauto.NewHistogram(prometheus.HistogramOpts{
9
+
Name: "carstore_write_shard_file_duration",
10
+
Help: "Duration of writing shard file to disk",
11
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
12
+
})
13
+
14
+
var writeShardMetadataDuration = promauto.NewHistogram(prometheus.HistogramOpts{
15
+
Name: "carstore_write_shard_metadata_duration",
16
+
Help: "Duration of writing shard metadata to DB",
17
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
18
+
})
+8
-3
carstore/repo_test.go
+8
-3
carstore/repo_test.go
···
30
30
return nil, nil, err
31
31
}
32
32
33
-
sharddir := filepath.Join(tempdir, "shards")
34
-
if err := os.MkdirAll(sharddir, 0775); err != nil {
33
+
sharddir1 := filepath.Join(tempdir, "shards1")
34
+
if err := os.MkdirAll(sharddir1, 0775); err != nil {
35
+
return nil, nil, err
36
+
}
37
+
38
+
sharddir2 := filepath.Join(tempdir, "shards2")
39
+
if err := os.MkdirAll(sharddir2, 0775); err != nil {
35
40
return nil, nil, err
36
41
}
37
42
···
45
50
return nil, nil, err
46
51
}
47
52
48
-
cs, err := NewCarStore(db, sharddir)
53
+
cs, err := NewCarStore(db, []string{sharddir1, sharddir2})
49
54
if err != nil {
50
55
return nil, nil, err
51
56
}
+17
-2
cmd/bigsky/main.go
+17
-2
cmd/bigsky/main.go
···
200
200
EnvVars: []string{"RELAY_NUM_COMPACTION_WORKERS"},
201
201
Value: 2,
202
202
},
203
+
&cli.StringSliceFlag{
204
+
Name: "carstore-shard-dirs",
205
+
Usage: "specify list of shard directories for carstore storage, overrides default storage within datadir",
206
+
EnvVars: []string{"RELAY_CARSTORE_SHARD_DIRS"},
207
+
},
203
208
}
204
209
205
210
app.Action = runBigsky
···
312
317
}
313
318
}
314
319
315
-
os.MkdirAll(filepath.Dir(csdir), os.ModePerm)
316
-
cstore, err := carstore.NewCarStore(csdb, csdir)
320
+
csdirs := []string{csdir}
321
+
if paramDirs := cctx.StringSlice("carstore-shard-dirs"); len(paramDirs) > 0 {
322
+
csdirs = paramDirs
323
+
}
324
+
325
+
for _, csd := range csdirs {
326
+
if err := os.MkdirAll(filepath.Dir(csd), os.ModePerm); err != nil {
327
+
return err
328
+
}
329
+
}
330
+
331
+
cstore, err := carstore.NewCarStore(csdb, csdirs)
317
332
if err != nil {
318
333
return err
319
334
}
+1
-1
cmd/laputa/main.go
+1
-1
cmd/laputa/main.go
+1
-1
cmd/supercollider/main.go
+1
-1
cmd/supercollider/main.go
+6
did/metrics.go
+6
did/metrics.go
···
9
9
Name: "multiresolver_resolved_dids_total",
10
10
Help: "Total number of DIDs resolved",
11
11
}, []string{"resolver"})
12
+
13
+
var mrResolveDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
14
+
Name: "indigo_multiresolver_resolve_duration_seconds",
15
+
Help: "A histogram of resolve latencies",
16
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
17
+
}, []string{"resolver"})
+6
did/multi.go
+6
did/multi.go
···
3
3
import (
4
4
"context"
5
5
"fmt"
6
+
"time"
6
7
7
8
"github.com/whyrusleeping/go-did"
8
9
)
···
43
44
}
44
45
45
46
func (mr *MultiResolver) GetDocument(ctx context.Context, didstr string) (*did.Document, error) {
47
+
s := time.Now()
48
+
46
49
pdid, err := did.ParseDID(didstr)
47
50
if err != nil {
48
51
return nil, err
49
52
}
50
53
51
54
method := pdid.Protocol()
55
+
defer func() {
56
+
mrResolveDuration.WithLabelValues(method).Observe(time.Since(s).Seconds())
57
+
}()
52
58
53
59
res, ok := mr.handlers[method]
54
60
if !ok {
+1
-1
events/dbpersist_test.go
+1
-1
events/dbpersist_test.go
+1
-1
indexer/posts_test.go
+1
-1
indexer/posts_test.go
+1
-1
pds/handlers_test.go
+1
-1
pds/handlers_test.go
+1
-1
repomgr/bench_test.go
+1
-1
repomgr/bench_test.go
+2
-2
repomgr/ingest_test.go
+2
-2
repomgr/ingest_test.go
···
50
50
t.Fatal(err)
51
51
}
52
52
53
-
cs, err := carstore.NewCarStore(cardb, cspath)
53
+
cs, err := carstore.NewCarStore(cardb, []string{cspath})
54
54
if err != nil {
55
55
t.Fatal(err)
56
56
}
···
80
80
t.Fatal(err)
81
81
}
82
82
83
-
cs, err := carstore.NewCarStore(cardb, cspath)
83
+
cs, err := carstore.NewCarStore(cardb, []string{cspath})
84
84
if err != nil {
85
85
t.Fatal(err)
86
86
}
+18
repomgr/metrics.go
+18
repomgr/metrics.go
···
9
9
Name: "repomgr_repo_ops_imported",
10
10
Help: "Number of repo ops imported",
11
11
})
12
+
13
+
var openAndSigCheckDuration = promauto.NewHistogram(prometheus.HistogramOpts{
14
+
Name: "repomgr_open_and_sig_check_duration",
15
+
Help: "Duration of opening and signature check",
16
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
17
+
})
18
+
19
+
var calcDiffDuration = promauto.NewHistogram(prometheus.HistogramOpts{
20
+
Name: "repomgr_calc_diff_duration",
21
+
Help: "Duration of calculating diff",
22
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
23
+
})
24
+
25
+
var writeCarSliceDuration = promauto.NewHistogram(prometheus.HistogramOpts{
26
+
Name: "repomgr_write_car_slice_duration",
27
+
Help: "Duration of writing car slice",
28
+
Buckets: prometheus.ExponentialBuckets(0.001, 2, 15),
29
+
})
+7
-1
repomgr/repomgr.go
+7
-1
repomgr/repomgr.go
···
8
8
"io"
9
9
"strings"
10
10
"sync"
11
+
"time"
11
12
12
13
atproto "github.com/bluesky-social/indigo/api/atproto"
13
14
bsky "github.com/bluesky-social/indigo/api/bsky"
···
538
539
unlock := rm.lockUser(ctx, uid)
539
540
defer unlock()
540
541
542
+
start := time.Now()
541
543
root, ds, err := rm.cs.ImportSlice(ctx, uid, since, carslice)
542
544
if err != nil {
543
545
return fmt.Errorf("importing external carslice: %w", err)
···
551
553
if err := rm.CheckRepoSig(ctx, r, did); err != nil {
552
554
return err
553
555
}
556
+
openAndSigCheckDuration.Observe(time.Since(start).Seconds())
554
557
555
558
var skipcids map[cid.Cid]bool
556
559
if ds.BaseCid().Defined() {
···
571
574
}
572
575
}
573
576
577
+
start = time.Now()
574
578
if err := ds.CalcDiff(ctx, skipcids); err != nil {
575
579
return fmt.Errorf("failed while calculating mst diff (since=%v): %w", since, err)
576
-
577
580
}
581
+
calcDiffDuration.Observe(time.Since(start).Seconds())
578
582
579
583
evtops := make([]RepoOp, 0, len(ops))
580
584
···
631
635
}
632
636
}
633
637
638
+
start = time.Now()
634
639
rslice, err := ds.CloseWithRoot(ctx, root, nrev)
635
640
if err != nil {
636
641
return fmt.Errorf("close with root: %w", err)
637
642
}
643
+
writeCarSliceDuration.Observe(time.Since(start).Seconds())
638
644
639
645
if rm.events != nil {
640
646
rm.events(ctx, &RepoEvent{
+2
-2
testing/utils.go
+2
-2
testing/utils.go
···
117
117
return nil, err
118
118
}
119
119
120
-
cs, err := carstore.NewCarStore(cardb, cspath)
120
+
cs, err := carstore.NewCarStore(cardb, []string{cspath})
121
121
if err != nil {
122
122
return nil, err
123
123
}
···
550
550
return nil, err
551
551
}
552
552
553
-
cs, err := carstore.NewCarStore(cardb, cspath)
553
+
cs, err := carstore.NewCarStore(cardb, []string{cspath})
554
554
if err != nil {
555
555
return nil, err
556
556
}