Skip to content

Commit 62cc9df

Browse files
committed
[raft/aux] Add aux Raftstore
1 parent ee03a27 commit 62cc9df

3 files changed

Lines changed: 103 additions & 15 deletions

File tree

pkg/aux_/store/raftstore/dss.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,50 @@ package raftstore
22

33
import (
44
"context"
5+
"strconv"
56

67
auxmodels "github.com/interuss/dss/pkg/aux_/models"
7-
dsserr "github.com/interuss/dss/pkg/errors"
8+
"github.com/interuss/dss/pkg/raftstore/consensus"
9+
raftparams "github.com/interuss/dss/pkg/raftstore/params"
810
"github.com/interuss/stacktrace"
911
)
1012

11-
// SaveOwnMetadata returns nil instead of dsserr.NotImplemented because it is needed to allow the server to startup.
12-
func (r *repo) SaveOwnMetadata(_ context.Context, locality string, publicEndpoint string) error {
13-
return nil
13+
func (r *repo) SaveOwnMetadata(ctx context.Context, locality string, publicEndpoint string) error {
14+
p, err := consensus.NewProposal(ctx, storeID, saveOwnMetadata, saveOwnMetadataPayload{
15+
Locality: locality,
16+
PublicEndpoint: publicEndpoint,
17+
}, false, nil)
18+
if err != nil {
19+
return stacktrace.Propagate(err, "failed to build %s proposal", saveOwnMetadata)
20+
}
21+
_, err = r.consensus.ProposeValue(ctx, p)
22+
return stacktrace.Propagate(err, "failed to propose %s", saveOwnMetadata)
1423
}
1524

16-
func (r *repo) GetDSSMetadata(_ context.Context) ([]*auxmodels.DSSMetadata, error) {
17-
return nil, stacktrace.NewErrorWithCode(dsserr.NotImplemented, "GetDSSMetadata not implemented for raftstore")
25+
func (r *repo) GetDSSMetadata(ctx context.Context) ([]*auxmodels.DSSMetadata, error) {
26+
p, err := consensus.NewProposal(ctx, storeID, getDSSMetadata, nil, true, nil)
27+
if err != nil {
28+
return nil, stacktrace.Propagate(err, "failed to build %s proposal", getDSSMetadata)
29+
}
30+
result, err := r.consensus.ProposeValue(ctx, p)
31+
if err != nil {
32+
return nil, stacktrace.Propagate(err, "failed to propose %s", getDSSMetadata)
33+
}
34+
if result == nil {
35+
return nil, nil
36+
}
37+
return result.([]*auxmodels.DSSMetadata), nil
1838
}
1939

20-
func (r *repo) RecordHeartbeat(_ context.Context, heartbeat auxmodels.Heartbeat) error {
21-
return stacktrace.NewErrorWithCode(dsserr.NotImplemented, "RecordHeartbeat not implemented for raftstore")
40+
func (r *repo) RecordHeartbeat(ctx context.Context, heartbeat auxmodels.Heartbeat) error {
41+
p, err := consensus.NewProposal(ctx, storeID, recordHeartbeat, heartbeat, false, nil)
42+
if err != nil {
43+
return stacktrace.Propagate(err, "failed to build %s proposal", recordHeartbeat)
44+
}
45+
_, err = r.consensus.ProposeValue(ctx, p)
46+
return stacktrace.Propagate(err, "failed to propose %s", recordHeartbeat)
2247
}
2348

2449
func (r *repo) GetDSSAirspaceRepresentationID(_ context.Context) (string, error) {
25-
return "", stacktrace.NewErrorWithCode(dsserr.NotImplemented, "GetDSSAirspaceRepresentationID not implemented for raftstore")
50+
return strconv.Itoa(int(raftparams.GetClusterID())), nil
2651
}

pkg/aux_/store/raftstore/store.go

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,63 @@ package raftstore
22

33
import (
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

1736
func 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

2257
func (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

2663
func (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
}

pkg/raftstore/params/params.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,7 @@ func init() {
145145
func GetConnectParameters() ConnectParameters {
146146
return connectParameters
147147
}
148+
149+
func GetClusterID() uint64 {
150+
return connectParameters.ClusterID
151+
}

0 commit comments

Comments
 (0)