Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/fix raft bug #11

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/discord.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
on:
release:
types: [published]

jobs:
github-releases-to-discord:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Github Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.13.1
with:
webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
color: "2105893"
username: "Release Changelog"
avatar_url: "https://github.com/dgate-io.png"
content: "||@everyone||"
footer_title: "Changelog"
footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
footer_timestamp: true
22 changes: 5 additions & 17 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
- server management (start-proxy, stop-proxy, restart, status, logs, stats, etc.)
- cluster management (raft commands, replica commands, etc.) (low priority)
- other commands (backup, restore, etc.) (low priority)
- replace k6 with wrk for performance tests

## Add Module Tests

Expand All @@ -16,9 +15,6 @@
- [ ] - Add option to specify export variables when ambiguous (?)
- [ ] - check how global variable conflicts are handled

## Start using Pkl

replace dgate server config with pkl.

## dgate-cli declaritive config

Expand Down Expand Up @@ -70,10 +66,6 @@ expose metrics for the following:
- Add Transactions
- [ ] - Add transactional support for admin API

## DGate Documentation (dgate.io/docs)

Use Docusaurus to create the documentation for DGate.

## DGate Admin Console (low priority)

Admin Console is a web-based interface that can be used to manage the state of the cluster. Manage resource, view logs, stats, and more. It can also be used to develop and test modules directly in the browser.
Expand Down Expand Up @@ -136,14 +128,6 @@ A good example of a bundle would be a bundle that adds support for OAuth2 authen
Differing from common resource versioning, modules can have multiple versions that can be used at the same time. This can be used to test new versions of modules before deploying them to the cluster.


## DGate CLI - argument variable suggestions

For example, if the user types an argument that is not recognized, the CLI can suggest the correct argument by search the available arguments and finding the closest match.
```
dgate-cli ns mk my-ns nmae=my-ns
Variable 'nmae' is not recognized. Did you mean 'name'?
```

## DGate CLI - help command show required variables

When the user runs the help command, the CLI should show the required variables for the command. For example, if the user runs `dgate-cli ns mk --help`, the CLI should show the required variables for the `ns mk` command. `name` is a required variable for the `ns mk` command. Also, the CLI should show non-required variables.
Expand All @@ -159,4 +143,8 @@ Add stack tracing for typescript modules.

Currently, Raft Implementation is tightly coupled with the Admin API. This makes it difficult to change the Raft Implementation without changing the Admin API. Decouple the Raft Implementation from the Admin API to make it easier to change the Raft Implementation.

## Add Telemetry (sentry, datadog, etc.)
## Add Telemetry (sentry, datadog, etc.)

## ResourceManager callback for resource changes

Add a callback to the ResourceManager that is called when a resource is changed. This can be used to invalidate caches, update modules, and more.
2 changes: 1 addition & 1 deletion functional-tests/raft_tests/raft_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dgate-cli -f domain create name=dm-$id \

dgate-cli -f service create \
name=svc-$id namespace=ns-$id \
urls="http://localhost:8888/$RANDOM"
urls="http://localhost:8081/$RANDOM"

dgate-cli -f route create \
name=rt-$id \
Expand Down
3 changes: 2 additions & 1 deletion functional-tests/raft_tests/test1.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
version: v1
log_level: info
debug: true
log_level: debug

tags:
- "dev"
Expand Down
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ require (
github.com/dop251/goja v0.0.0-20240220182346-e401ed450204
github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c
github.com/google/uuid v1.3.1
github.com/hashicorp/go-hclog v1.6.2
github.com/hashicorp/raft v1.6.0
github.com/hashicorp/go-hclog v1.6.3
github.com/hashicorp/raft v1.7.0
github.com/knadh/koanf/parsers/json v0.1.0
github.com/knadh/koanf/parsers/toml v0.1.0
github.com/knadh/koanf/parsers/yaml v0.1.0
Expand Down Expand Up @@ -46,7 +46,7 @@ require (
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/dop251/base64dec v0.0.0-20231022112746-c6c9f9a96217 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
Expand All @@ -59,12 +59,12 @@ require (
github.com/google/flatbuffers v1.12.1 // indirect
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/knadh/koanf/maps v0.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
Expand All @@ -82,7 +82,7 @@ require (
go.opentelemetry.io/otel/trace v1.26.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
Expand Down Expand Up @@ -125,19 +127,27 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I=
github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack/v2 v2.1.1 h1:xQEY9yB2wnHitoSzk/B9UjXWRQ67QKu5AOm8aFp8N3I=
github.com/hashicorp/go-msgpack/v2 v2.1.1/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=
github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0=
github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/raft v1.6.0 h1:tkIAORZy2GbJ2Trp5eUSggLXDPOJLXC+JJLNMMqtgtM=
github.com/hashicorp/raft v1.6.0/go.mod h1:Xil5pDgeGwRWuX4uPUmwa+7Vagg4N804dz6mhNi6S7o=
github.com/hashicorp/raft v1.7.0 h1:4u24Qn6lQ6uwziM++UgsyiT64Q8GyRn43CV41qPiz1o=
github.com/hashicorp/raft v1.7.0/go.mod h1:N1sKh6Vn47mrWvEArQgILTyng8GoDRNYlgKyK7PMjs0=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
Expand Down Expand Up @@ -182,6 +192,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
Expand Down Expand Up @@ -343,6 +355,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
Expand Down
93 changes: 48 additions & 45 deletions internal/admin/admin_fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,17 @@
return &dgateAdminFSM{cs, logger}
}

func (fsm *dgateAdminFSM) isReplay(log *raft.Log) bool {
return !fsm.cs.Ready() &&
log.Index+1 >= fsm.cs.Raft().LastIndex() &&
log.Index+1 >= fsm.cs.Raft().AppliedIndex()
func (fsm *dgateAdminFSM) isLatestLog(log *raft.Log) bool {
rft := fsm.cs.Raft()
return log.Index == rft.CommitIndex() ||
log.Index+1 == rft.CommitIndex()

Check warning on line 27 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L24-L27

Added lines #L24 - L27 were not covered by tests
}

func (fsm *dgateAdminFSM) checkLast(log *raft.Log) {
rft := fsm.cs.Raft()
if !fsm.cs.Ready() && fsm.isReplay(log) {
fsm.logger.Info("FSM is not ready, setting ready",
zap.Uint64("index", log.Index),
zap.Uint64("applied-index", rft.AppliedIndex()),
zap.Uint64("last-index", rft.LastIndex()),
)
defer func() {
if err := fsm.cs.ReloadState(false); err != nil {
fsm.logger.Error("Error processing change log in FSM", zap.Error(err))
} else {
fsm.cs.SetReady()
}
}()
func (fsm *dgateAdminFSM) reload(cls ...*spec.ChangeLog) {
if err := fsm.cs.ReloadState(false, cls...); err != nil {
fsm.logger.Error("Error processing change log in FSM", zap.Error(err))
} else {
fsm.cs.SetReady()

Check warning on line 34 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L30-L34

Added lines #L30 - L34 were not covered by tests
}
}

Expand Down Expand Up @@ -82,43 +72,56 @@
}

func (fsm *dgateAdminFSM) Apply(log *raft.Log) any {
defer fsm.checkLast(log)
_, err := fsm.applyLog(log)
rft := fsm.cs.Raft()
fsm.logger.Debug("applying log",
zap.Uint64("current", log.Index),
zap.Uint64("applied", rft.AppliedIndex()),
zap.Uint64("commit", rft.CommitIndex()),
zap.Uint64("last", rft.LastIndex()),
)
cl, err := fsm.applyLog(log)
if err != nil && !fsm.cs.Ready() {
fsm.reload(cl)
} else {
fsm.logger.Error("Error processing change log in FSM", zap.Error(err))

Check warning on line 86 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L75-L86

Added lines #L75 - L86 were not covered by tests
}
return err
}

func (fsm *dgateAdminFSM) ApplyBatch(logs []*raft.Log) []any {
lastLog := logs[len(logs)-1]
if fsm.isReplay(lastLog) {
rft := fsm.cs.Raft()
fsm.logger.Info("applying log batch logs",
zap.Int("size", len(logs)),
zap.Uint64("current", lastLog.Index),
zap.Uint64("applied", rft.AppliedIndex()),
zap.Uint64("commit", rft.CommitIndex()),
zap.Uint64("last", rft.LastIndex()),
)
if len(logs) == 0 || logs == nil {
fsm.logger.Warn("No logs to apply in ApplyBatch")
return nil

Check warning on line 94 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L92-L94

Added lines #L92 - L94 were not covered by tests
}
cls := make([]*spec.ChangeLog, 0, len(logs))
defer func() {
if !fsm.cs.Ready() {
fsm.checkLast(logs[len(logs)-1])
return
}

if err := fsm.cs.ReloadState(true, cls...); err != nil {
fsm.logger.Error("Error reloading state @ FSM ApplyBatch", zap.Error(err))
}
}()
lastLog := logs[len(logs)-1]
rft := fsm.cs.Raft()
fsm.logger.Info("applying batch logs",
zap.Int("size", len(logs)),
zap.Uint64("current", lastLog.Index),
zap.Uint64("applied", rft.AppliedIndex()),
zap.Uint64("commit", rft.CommitIndex()),
zap.Uint64("last", rft.LastIndex()),
)

Check warning on line 104 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L96-L104

Added lines #L96 - L104 were not covered by tests

cls := make([]*spec.ChangeLog, 0, len(logs))

Check warning on line 106 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L106

Added line #L106 was not covered by tests
results := make([]any, len(logs))
for i, log := range logs {
var cl *spec.ChangeLog
cl, results[i] = fsm.applyLog(log)
if cl != nil {
var (
cl *spec.ChangeLog
err error
)
if cl, err = fsm.applyLog(log); err != nil {
results[i] = err
fsm.logger.Error("Error processing change log in FSM", zap.Error(err))
} else {

Check warning on line 116 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L109-L116

Added lines #L109 - L116 were not covered by tests
cls = append(cls, cl)
}
}

if fsm.cs.Ready() || fsm.isLatestLog(lastLog) {
fsm.reload(cls...)

Check warning on line 122 in internal/admin/admin_fsm.go

View check run for this annotation

Codecov / codecov/patch

internal/admin/admin_fsm.go#L121-L122

Added lines #L121 - L122 were not covered by tests
}

return results
}

Expand Down
Loading
Loading