Skip to content

Commit 611eb74

Browse files
authored
Merge pull request #177 from anyproto/GO-5601-update-diff-version
GO-5061: Add diff migration
2 parents a7da797 + 65d0a48 commit 611eb74

File tree

7 files changed

+496
-38
lines changed

7 files changed

+496
-38
lines changed

go.mod

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
module github.com/anyproto/any-sync-node
22

3-
go 1.23.8
3+
go 1.23.10
44

55
toolchain go1.24.0
66

77
require (
88
github.com/ahmetb/govvv v0.3.0
99
github.com/akrylysov/pogreb v0.10.3-0.20240803013244-523613e335e9
1010
github.com/anyproto/any-store v0.3.3
11-
github.com/anyproto/any-sync v0.9.1
11+
github.com/anyproto/any-sync v0.9.5
1212
github.com/anyproto/go-chash v0.1.0
1313
github.com/cheggaaa/mb/v3 v3.0.2
1414
github.com/planetscale/vtprotobuf v0.6.0
15-
github.com/prometheus/client_golang v1.22.0
15+
github.com/prometheus/client_golang v1.23.0
1616
github.com/stretchr/testify v1.10.0
1717
go.uber.org/atomic v1.11.0
1818
go.uber.org/mock v0.5.2
@@ -30,7 +30,7 @@ require (
3030
github.com/anyproto/go-slip10 v1.0.0 // indirect
3131
github.com/anyproto/go-slip21 v1.0.0 // indirect
3232
github.com/anyproto/go-sqlite v1.4.2-any // indirect
33-
github.com/anyproto/lexid v0.0.4 // indirect
33+
github.com/anyproto/lexid v0.0.6 // indirect
3434
github.com/beorn7/perks v1.0.1 // indirect
3535
github.com/btcsuite/btcd v0.22.1 // indirect
3636
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
@@ -47,7 +47,7 @@ require (
4747
github.com/gobwas/glob v0.2.3 // indirect
4848
github.com/goccy/go-graphviz v0.2.9 // indirect
4949
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
50-
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
50+
github.com/golang/snappy v1.0.0 // indirect
5151
github.com/google/uuid v1.6.0 // indirect
5252
github.com/hashicorp/yamux v0.1.2 // indirect
5353
github.com/huandu/skiplist v1.2.1 // indirect
@@ -56,25 +56,25 @@ require (
5656
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
5757
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
5858
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
59-
github.com/libp2p/go-libp2p v0.42.0 // indirect
59+
github.com/libp2p/go-libp2p v0.42.1 // indirect
6060
github.com/mattn/go-isatty v0.0.20 // indirect
6161
github.com/minio/sha256-simd v1.0.1 // indirect
6262
github.com/mr-tron/base58 v1.2.0 // indirect
6363
github.com/multiformats/go-base32 v0.1.0 // indirect
6464
github.com/multiformats/go-base36 v0.2.0 // indirect
6565
github.com/multiformats/go-multiaddr v0.16.0 // indirect
6666
github.com/multiformats/go-multibase v0.2.0 // indirect
67-
github.com/multiformats/go-multicodec v0.9.1 // indirect
67+
github.com/multiformats/go-multicodec v0.9.2 // indirect
6868
github.com/multiformats/go-multihash v0.2.3 // indirect
6969
github.com/multiformats/go-multistream v0.6.1 // indirect
7070
github.com/multiformats/go-varint v0.0.7 // indirect
7171
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
7272
github.com/ncruces/go-strftime v0.1.9 // indirect
7373
github.com/pmezard/go-difflib v1.0.0 // indirect
7474
github.com/prometheus/client_model v0.6.2 // indirect
75-
github.com/prometheus/common v0.64.0 // indirect
75+
github.com/prometheus/common v0.65.0 // indirect
7676
github.com/prometheus/procfs v0.16.1 // indirect
77-
github.com/quic-go/quic-go v0.53.0 // indirect
77+
github.com/quic-go/quic-go v0.54.0 // indirect
7878
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
7979
github.com/spaolacci/murmur3 v1.1.0 // indirect
8080
github.com/tetratelabs/wazero v1.8.1 // indirect

go.sum

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ github.com/akrylysov/pogreb v0.10.3-0.20240803013244-523613e335e9 h1:GnBlbnor8ge
99
github.com/akrylysov/pogreb v0.10.3-0.20240803013244-523613e335e9/go.mod h1:fPb3n+7H42SxX84B4/os7POrR+UGRKSRr3kNS5+xq/c=
1010
github.com/anyproto/any-store v0.3.3 h1:dNzR6YTXt5VaR1aPy4cWlvQ3ozpdO68ABZGA5SfWAPY=
1111
github.com/anyproto/any-store v0.3.3/go.mod h1:337LBJI+JsUsUS1qbKKmtReVhLHW1Mqn4KQux9aEE5A=
12-
github.com/anyproto/any-sync v0.9.1 h1:Jgdn5APJqRWd8k3nuBg7AQ6FzqCmRwWx1q/w+tPrEHU=
13-
github.com/anyproto/any-sync v0.9.1/go.mod h1:WTPTp7QBZEF2eB+q3xRQjM1/atT8gah4KVEjzjTGsbo=
12+
github.com/anyproto/any-sync v0.9.5 h1:6VL3xIxVtQFl2ReuL/FqI2X0CyQyyy0v5wBqwyDSpkE=
13+
github.com/anyproto/any-sync v0.9.5/go.mod h1:K5M81ElCD2Bar00MqISPDkS8ew1NTvLCkNvuS342gpU=
1414
github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY=
1515
github.com/anyproto/go-chash v0.1.0/go.mod h1:0UjNQi3PDazP0fINpFYu6VKhuna+W/V+1vpXHAfNgLY=
1616
github.com/anyproto/go-slip10 v1.0.0 h1:uAEtSuudR3jJBOfkOXf3bErxVoxbuKwdoJN55M1i6IA=
@@ -19,8 +19,8 @@ github.com/anyproto/go-slip21 v1.0.0 h1:CI7lUqTIwmPOEGVAj4jyNLoICvueh++0U2HoAi3m
1919
github.com/anyproto/go-slip21 v1.0.0/go.mod h1:gbIJt7HAdr5DuT4f2pFTKCBSUWYsm/fysHBNqgsuxT0=
2020
github.com/anyproto/go-sqlite v1.4.2-any h1:ZTIcq/u2mYYJ6rJB4I3Ds5QH/7IlONebMiG14FyZcD4=
2121
github.com/anyproto/go-sqlite v1.4.2-any/go.mod h1:nW7TvS+4bzPU2vNaPlPFNPYcejK5RdjH6qZY2kjT3Io=
22-
github.com/anyproto/lexid v0.0.4 h1:2ztI0y5pNdtojd3vChw/YV/P6IO9pB7PccYysImDxWI=
23-
github.com/anyproto/lexid v0.0.4/go.mod h1:2RfpYiZkgoNmSDklXdwCCwGlso1FIp9Te8ZtoF3/Ehg=
22+
github.com/anyproto/lexid v0.0.6 h1:lTJd9K11vU1xoBs1dkZVv8VtYfCBo373lNd9kAgXEio=
23+
github.com/anyproto/lexid v0.0.6/go.mod h1:2RfpYiZkgoNmSDklXdwCCwGlso1FIp9Te8ZtoF3/Ehg=
2424
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
2525
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
2626
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
@@ -71,8 +71,8 @@ github.com/goccy/go-graphviz v0.2.9/go.mod h1:hssjl/qbvUXGmloY81BwXt2nqoApKo7DFg
7171
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
7272
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
7373
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
74-
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
75-
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
74+
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
75+
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
7676
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
7777
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
7878
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -105,8 +105,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
105105
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
106106
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
107107
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
108-
github.com/libp2p/go-libp2p v0.42.0 h1:A8foZk+ZEhZTv0Jb++7xUFlrFhBDv4j2Vh/uq4YX+KE=
109-
github.com/libp2p/go-libp2p v0.42.0/go.mod h1:4NGcjbD9OIvFiSRb0XueCO19zJ4kSPK5vkyyOUYmMro=
108+
github.com/libp2p/go-libp2p v0.42.1 h1:Rt8+5thie729NQk1gx1h/2t/+VIafWcqR1I+Kvw+UTg=
109+
github.com/libp2p/go-libp2p v0.42.1/go.mod h1:4NGcjbD9OIvFiSRb0XueCO19zJ4kSPK5vkyyOUYmMro=
110110
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
111111
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
112112
github.com/libp2p/go-yamux/v5 v5.0.1 h1:f0WoX/bEF2E8SbE4c/k1Mo+/9z0O4oC/hWEA+nfYRSg=
@@ -125,8 +125,8 @@ github.com/multiformats/go-multiaddr v0.16.0 h1:oGWEVKioVQcdIOBlYM8BH1rZDWOGJSqr
125125
github.com/multiformats/go-multiaddr v0.16.0/go.mod h1:JSVUmXDjsVFiW7RjIFMP7+Ev+h1DTbiJgVeTV/tcmP0=
126126
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
127127
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
128-
github.com/multiformats/go-multicodec v0.9.1 h1:x/Fuxr7ZuR4jJV4Os5g444F7xC4XmyUaT/FWtE+9Zjo=
129-
github.com/multiformats/go-multicodec v0.9.1/go.mod h1:LLWNMtyV5ithSBUo3vFIMaeDy+h3EbkMTek1m+Fybbo=
128+
github.com/multiformats/go-multicodec v0.9.2 h1:YrlXCuqxjqm3bXl+vBq5LKz5pz4mvAsugdqy78k0pXQ=
129+
github.com/multiformats/go-multicodec v0.9.2/go.mod h1:LLWNMtyV5ithSBUo3vFIMaeDy+h3EbkMTek1m+Fybbo=
130130
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
131131
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
132132
github.com/multiformats/go-multistream v0.6.1 h1:4aoX5v6T+yWmc2raBHsTvzmFhOI8WVOer28DeBBEYdQ=
@@ -146,16 +146,16 @@ github.com/planetscale/vtprotobuf v0.6.0 h1:nBeETjudeJ5ZgBHUz1fVHvbqUKnYOXNhsIEa
146146
github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
147147
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
148148
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
149-
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
150-
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
149+
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
150+
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
151151
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
152152
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
153-
github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=
154-
github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
153+
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
154+
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
155155
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
156156
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
157-
github.com/quic-go/quic-go v0.53.0 h1:QHX46sISpG2S03dPeZBgVIZp8dGagIaiu2FiVYvpCZI=
158-
github.com/quic-go/quic-go v0.53.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
157+
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
158+
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
159159
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
160160
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
161161
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=

nodespace/rpchandler.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,9 @@ func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncR
279279
}
280280

281281
func (r *rpcHandler) tryNodeHeadSync(req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse) {
282-
if len(req.Ranges) == 1 && (req.Ranges[0].From == 0 && req.Ranges[0].To == math.MaxUint64) {
282+
if len(req.Ranges) == 1 && !req.Ranges[0].Elements && (req.Ranges[0].From == 0 && req.Ranges[0].To == math.MaxUint64) {
283283
switch req.DiffType {
284-
case spacesyncproto.DiffType_V2:
285-
if req.Ranges[0].Elements {
286-
return nil
287-
}
284+
case spacesyncproto.DiffType_V3:
288285
hash, err := r.s.nodeHead.GetHead(req.SpaceId)
289286
if err != nil {
290287
return
@@ -295,7 +292,7 @@ func (r *rpcHandler) tryNodeHeadSync(req *spacesyncproto.HeadSyncRequest) (resp
295292
}
296293
log.Debug("got head sync with nodehead", zap.String("spaceId", req.SpaceId))
297294
return &spacesyncproto.HeadSyncResponse{
298-
DiffType: spacesyncproto.DiffType_V2,
295+
DiffType: spacesyncproto.DiffType_V3,
299296
Results: []*spacesyncproto.HeadSyncResult{
300297
{
301298
Hash: hashB,
@@ -315,6 +312,7 @@ func (r *rpcHandler) tryNodeHeadSync(req *spacesyncproto.HeadSyncRequest) (resp
315312
}
316313
log.Debug("got head sync with old nodehead", zap.String("spaceId", req.SpaceId))
317314
return &spacesyncproto.HeadSyncResponse{
315+
DiffType: spacesyncproto.DiffType_V2,
318316
Results: []*spacesyncproto.HeadSyncResult{
319317
{
320318
Hash: hashB,

nodestorage/indexstorage.go

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,29 @@ var (
2626
)
2727

2828
const (
29-
IndexStorageName = ".index"
30-
delCollName = "deletionIndex"
31-
hashCollName = "hashesIndex"
32-
newHashKey = "nh"
33-
oldHashKey = "oh"
34-
statusKey = "s"
35-
recordIdKey = "r"
29+
IndexStorageName = ".index"
30+
delCollName = "deletionIndex"
31+
hashCollName = "hashesIndex"
32+
migrationStateCollName = "migrationState"
33+
newHashKey = "nh"
34+
oldHashKey = "oh"
35+
statusKey = "s"
36+
recordIdKey = "r"
37+
diffMigrationKey = "diffState"
38+
diffVersionKey = "diffVersion"
3639
)
3740

3841
type IndexStorage interface {
3942
UpdateHash(ctx context.Context, update SpaceUpdate) (err error)
4043
RemoveHash(ctx context.Context, spaceId string) (err error)
4144
ReadHashes(ctx context.Context, iterFunc func(update SpaceUpdate) (bool, error)) (err error)
45+
UpdateHashes(ctx context.Context, updateFunc func(spaceId, newHash, oldHash string) (newNewHash, newOldHash string, shouldUpdate bool)) (err error)
4246
SetSpaceStatus(ctx context.Context, spaceId string, status SpaceStatus, recId string) (err error)
4347
SpaceStatus(ctx context.Context, spaceId string) (status SpaceStatus, err error)
4448
LastRecordId(ctx context.Context) (id string, err error)
49+
GetDiffMigrationVersion(ctx context.Context) (version int, err error)
50+
SetDiffMigrationVersion(ctx context.Context, version int) (err error)
51+
RunMigrations(ctx context.Context) (err error)
4552
Close() (err error)
4653
}
4754

@@ -166,6 +173,100 @@ func (d *indexStorage) LastRecordId(ctx context.Context) (id string, err error)
166173
return "", ErrNoLastRecordId
167174
}
168175

176+
func (d *indexStorage) RunMigrations(ctx context.Context) (err error) {
177+
diffMigration, err := newDiffMigration(d, log)
178+
if err != nil {
179+
return fmt.Errorf("failed to create diff migration: %w", err)
180+
}
181+
182+
if err := diffMigration.Run(ctx); err != nil {
183+
return fmt.Errorf("diff migration failed: %w", err)
184+
}
185+
186+
return nil
187+
}
188+
189+
func (d *indexStorage) UpdateHashes(ctx context.Context, updateFunc func(spaceId, newHash, oldHash string) (newNewHash, newOldHash string, shouldUpdate bool)) (err error) {
190+
iter, err := d.hashesColl.Find(query.All{}).Iter(ctx)
191+
if err != nil {
192+
return err
193+
}
194+
defer iter.Close()
195+
196+
tx, err := d.hashesColl.WriteTx(ctx)
197+
if err != nil {
198+
return err
199+
}
200+
defer tx.Rollback()
201+
202+
for iter.Next() {
203+
doc, err := iter.Doc()
204+
if err != nil {
205+
return err
206+
}
207+
208+
value := doc.Value()
209+
spaceId := value.GetString("id")
210+
newHash := value.GetString(newHashKey)
211+
oldHash := value.GetString(oldHashKey)
212+
213+
newNewHash, newOldHash, shouldUpdate := updateFunc(spaceId, newHash, oldHash)
214+
if !shouldUpdate {
215+
continue
216+
}
217+
218+
arena := d.arenaPool.Get()
219+
updatedDoc := arena.NewObject()
220+
updatedDoc.Set("id", arena.NewString(spaceId))
221+
updatedDoc.Set(newHashKey, arena.NewString(newNewHash))
222+
updatedDoc.Set(oldHashKey, arena.NewString(newOldHash))
223+
224+
err = d.hashesColl.UpsertOne(tx.Context(), updatedDoc)
225+
d.arenaPool.Put(arena)
226+
if err != nil {
227+
return err
228+
}
229+
}
230+
231+
return tx.Commit()
232+
}
233+
234+
func (d *indexStorage) GetDiffMigrationVersion(ctx context.Context) (version int, err error) {
235+
migrationColl, err := d.db.Collection(ctx, migrationStateCollName)
236+
if err != nil {
237+
return 0, err
238+
}
239+
240+
doc, err := migrationColl.FindId(ctx, diffMigrationKey)
241+
if err != nil {
242+
if errors.Is(err, anystore.ErrDocNotFound) {
243+
return 0, nil
244+
}
245+
return 0, err
246+
}
247+
248+
return int(doc.Value().GetFloat64(diffVersionKey)), nil
249+
}
250+
251+
func (d *indexStorage) SetDiffMigrationVersion(ctx context.Context, version int) (err error) {
252+
migrationColl, err := d.db.Collection(ctx, migrationStateCollName)
253+
if err != nil {
254+
return err
255+
}
256+
257+
mod := query.ModifyFunc(func(a *anyenc.Arena, v *anyenc.Value) (result *anyenc.Value, modified bool, err error) {
258+
if v == nil {
259+
v = a.NewObject()
260+
v.Set("id", a.NewString(diffMigrationKey))
261+
}
262+
v.Set(diffVersionKey, a.NewNumberFloat64(float64(version)))
263+
return v, true, nil
264+
})
265+
266+
_, err = migrationColl.UpsertId(ctx, diffMigrationKey, mod)
267+
return err
268+
}
269+
169270
func (d *indexStorage) Close() (err error) {
170271
return d.db.Close()
171272
}

nodestorage/migration.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package nodestorage
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/anyproto/any-sync/app/logger"
8+
"go.uber.org/zap"
9+
)
10+
11+
const (
12+
targetMigrationVersion = 3
13+
)
14+
15+
type Migration interface {
16+
Run(ctx context.Context) error
17+
}
18+
19+
type diffMigration struct {
20+
indexStorage IndexStorage
21+
logger logger.CtxLogger
22+
}
23+
24+
func newDiffMigration(is IndexStorage, log logger.CtxLogger) (*diffMigration, error) {
25+
return &diffMigration{
26+
indexStorage: is,
27+
logger: log,
28+
}, nil
29+
}
30+
31+
func (m *diffMigration) Run(ctx context.Context) error {
32+
m.logger.Info("starting diff migration v2 to v3")
33+
34+
currentVersion, err := m.indexStorage.GetDiffMigrationVersion(ctx)
35+
if err != nil {
36+
return fmt.Errorf("failed to get migration version: %w", err)
37+
}
38+
39+
if currentVersion >= targetMigrationVersion {
40+
m.logger.Info("diff migration already completed", zap.Int("version", currentVersion))
41+
return nil
42+
}
43+
44+
err = m.migrateHashIndex(ctx)
45+
if err != nil {
46+
return fmt.Errorf("failed to migrate hash index: %w", err)
47+
}
48+
49+
err = m.indexStorage.SetDiffMigrationVersion(ctx, targetMigrationVersion)
50+
if err != nil {
51+
return fmt.Errorf("failed to set migration version: %w", err)
52+
}
53+
54+
m.logger.Info("diff migration completed successfully")
55+
return nil
56+
}
57+
58+
func (m *diffMigration) migrateHashIndex(ctx context.Context) error {
59+
migratedCount := 0
60+
61+
err := m.indexStorage.UpdateHashes(ctx, func(spaceId, newHash, oldHash string) (newNewHash, newOldHash string, shouldUpdate bool) {
62+
migratedCount++
63+
return newHash, newHash, true
64+
})
65+
66+
if err != nil {
67+
return fmt.Errorf("failed to update hashes: %w", err)
68+
}
69+
70+
m.logger.Info("hash index migration completed", zap.Int("migrated_count", migratedCount))
71+
return nil
72+
}

0 commit comments

Comments
 (0)