@@ -2,26 +2,63 @@ 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 dsserr "github.com/interuss/dss/pkg/errors"
811 "github.com/interuss/dss/pkg/raftstore"
912 "github.com/interuss/dss/pkg/raftstore/consensus"
1013 "github.com/interuss/stacktrace"
1114 "go.uber.org/zap"
1215)
1316
17+ const storeID = "aux_"
18+
19+ const (
20+ saveOwnMetadata raftstore.RequestType = "saveOwnMetadata"
21+ getDSSMetadata raftstore.RequestType = "getDSSMetadata"
22+ recordHeartbeat raftstore.RequestType = "recordHeartbeat"
23+ )
24+
25+ type saveOwnMetadataPayload struct {
26+ Locality string `json:"locality"`
27+ PublicEndpoint string `json:"public_endpoint"`
28+ }
29+
1430// repo is a full implementation of aux_.repos.Repository for Raft-based storage.
15- type repo struct {}
31+ type repo struct {
32+ consensus * consensus.Consensus
33+ mem repos.Repository
34+ }
1635
1736func Init (ctx context.Context , logger * zap.Logger ) (* raftstore.Store [repos.Repository ], error ) {
18- store , _ , err := raftstore .Init (ctx , logger , "aux_" , & repo {})
19- return store , err
37+ memStore , err := auxmemstore .Init (ctx , logger )
38+ if err != nil {
39+ return nil , stacktrace .Propagate (err , "failed to initialize aux memstore" )
40+ }
41+
42+ mem , err := memStore .Interact (ctx )
43+ if err != nil {
44+ return nil , stacktrace .Propagate (err , "failed to obtain aux memstore repository" )
45+ }
46+
47+ r := & repo {mem : mem }
48+ store , consensus , err := raftstore .Init (ctx , logger , storeID , r )
49+ if err != nil {
50+ return nil , stacktrace .Propagate (err , "failed to initialize aux raftstore" )
51+ }
52+
53+ r .consensus = consensus
54+ return store , nil
2055}
2156
2257func (r * repo ) GetRepo () repos.Repository { return r }
2358
24- func (r * repo ) IsReadOnly (_ raftstore.RequestType ) bool { return false }
59+ func (r * repo ) IsReadOnly (requestType raftstore.RequestType ) bool {
60+ return requestType == getDSSMetadata
61+ }
2562
2663func (r * repo ) GetSnapshot () ([]byte , error ) {
2764 return nil , stacktrace .NewErrorWithCode (dsserr .NotImplemented , "not implemented yet" )
@@ -31,6 +68,28 @@ func (r *repo) RestoreFromSnapshot([]byte) error {
3168 return stacktrace .NewErrorWithCode (dsserr .NotImplemented , "not implemented yet" )
3269}
3370
34- func (r * repo ) Apply (_ context.Context , _ consensus.Proposal ) (any , error ) {
35- return nil , stacktrace .NewErrorWithCode (dsserr .NotImplemented , "not implemented yet" )
71+ func (r * repo ) Apply (ctx context.Context , proposal consensus.Proposal ) (any , error ) {
72+ switch raftstore .RequestType (proposal .RequestType ) {
73+ case saveOwnMetadata :
74+ var p saveOwnMetadataPayload
75+ if err := json .Unmarshal (proposal .Value , & p ); err != nil {
76+ return nil , stacktrace .Propagate (err , "failed to unmarshal %s payload" , saveOwnMetadata )
77+ }
78+
79+ return nil , r .mem .SaveOwnMetadata (ctx , p .Locality , p .PublicEndpoint )
80+
81+ case getDSSMetadata :
82+ return r .mem .GetDSSMetadata (ctx )
83+
84+ case recordHeartbeat :
85+ var hb auxmodels.Heartbeat
86+ if err := json .Unmarshal (proposal .Value , & hb ); err != nil {
87+ return nil , stacktrace .Propagate (err , "failed to unmarshal %s payload" , recordHeartbeat )
88+ }
89+
90+ return nil , r .mem .RecordHeartbeat (ctx , hb )
91+
92+ default :
93+ return nil , stacktrace .NewError ("unknown request type: %q" , proposal .RequestType )
94+ }
3695}
0 commit comments