@@ -2,39 +2,96 @@ package raftstore
22
33import (
44 "context"
5+ "encoding/json"
56
7+ auxmodels "github.com/interuss/dss/pkg/aux_/models"
68 "github.com/interuss/dss/pkg/aux_/repos"
9+ auxmemstore "github.com/interuss/dss/pkg/aux_/store/memstore"
710 auxraftparams "github.com/interuss/dss/pkg/aux_/store/raftstore/params"
8- dsserr "github.com/interuss/dss/pkg/errors "
11+ "github.com/interuss/dss/pkg/memstore "
912 "github.com/interuss/dss/pkg/raftstore"
1013 "github.com/interuss/dss/pkg/raftstore/consensus"
1114 "github.com/interuss/stacktrace"
1215 "go.uber.org/zap"
1316)
1417
18+ const storeID = "aux_"
19+
20+ const (
21+ saveOwnMetadata raftstore.RequestType = "saveOwnMetadata"
22+ getDSSMetadata raftstore.RequestType = "getDSSMetadata"
23+ recordHeartbeat raftstore.RequestType = "recordHeartbeat"
24+ )
25+
1526// repo is a full implementation of aux_.repos.Repository for Raft-based storage.
16- type repo struct {}
27+ type repo struct {
28+ consensus * consensus.Consensus
29+ memStore * memstore.Store [repos.Repository ]
30+ }
1731
1832func Init (ctx context.Context , logger * zap.Logger ) (* raftstore.Store [repos.Repository ], error ) {
1933 params , err := auxraftparams .GetConnectParameters ()
2034 if err != nil {
2135 return nil , stacktrace .Propagate (err , "failed to get aux raft parameters" )
2236 }
23- return raftstore .Init (ctx , logger , params , "aux" , & repo {})
37+
38+ memStore , err := auxmemstore .Init (ctx , logger )
39+ if err != nil {
40+ return nil , stacktrace .Propagate (err , "failed to initialize aux memstore" )
41+ }
42+
43+ r := & repo {memStore : memStore }
44+ store , err := raftstore .Init (ctx , logger , params , r )
45+ if err != nil {
46+ return nil , stacktrace .Propagate (err , "failed to initialize aux raftstore" )
47+ }
48+
49+ r .consensus = store .Consensus
50+
51+ return store , nil
2452}
2553
2654func (r * repo ) GetRepo () repos.Repository { return r }
2755
28- func (r * repo ) IsReadOnly (_ raftstore.RequestType ) bool { return false }
56+ func (r * repo ) IsReadOnly (requestType raftstore.RequestType ) bool {
57+ return requestType == getDSSMetadata
58+ }
2959
3060func (r * repo ) GetSnapshot () ([]byte , error ) {
31- return nil , stacktrace . NewErrorWithCode ( dsserr . NotImplemented , "not implemented yet" )
61+ return r . memStore . GetSnapshot ( )
3262}
3363
34- func (r * repo ) RestoreFromSnapshot ([]byte ) error {
35- return stacktrace . NewErrorWithCode ( dsserr . NotImplemented , "not implemented yet" )
64+ func (r * repo ) RestoreFromSnapshot (data []byte ) error {
65+ return r . memStore . RestoreFromSnapshot ( data )
3666}
3767
38- func (r * repo ) Apply (_ context.Context , _ consensus.Proposal ) (any , error ) {
39- return nil , stacktrace .NewErrorWithCode (dsserr .NotImplemented , "not implemented yet" )
68+ func (r * repo ) Apply (ctx context.Context , proposal consensus.Proposal ) (any , error ) {
69+ mem , err := r .memStore .Interact (ctx )
70+ if err != nil {
71+ return nil , stacktrace .Propagate (err , "failed to obtain aux memstore repository" )
72+ }
73+
74+ switch raftstore .RequestType (proposal .RequestType ) {
75+ case saveOwnMetadata :
76+ var p saveOwnMetadataPayload
77+ if err := json .Unmarshal (proposal .Value , & p ); err != nil {
78+ return nil , stacktrace .Propagate (err , "failed to unmarshal %s payload" , saveOwnMetadata )
79+ }
80+
81+ return nil , mem .SaveOwnMetadata (ctx , p .Locality , p .PublicEndpoint )
82+
83+ case getDSSMetadata :
84+ return mem .GetDSSMetadata (ctx )
85+
86+ case recordHeartbeat :
87+ var hb auxmodels.Heartbeat
88+ if err := json .Unmarshal (proposal .Value , & hb ); err != nil {
89+ return nil , stacktrace .Propagate (err , "failed to unmarshal %s payload" , recordHeartbeat )
90+ }
91+
92+ return nil , mem .RecordHeartbeat (ctx , hb )
93+
94+ default :
95+ return nil , stacktrace .NewError ("unknown request type: %q" , proposal .RequestType )
96+ }
4097}
0 commit comments