Skip to content

Commit

Permalink
on-update functionality in example
Browse files Browse the repository at this point in the history
  • Loading branch information
rbroggi committed Jul 24, 2024
1 parent 8ed4b76 commit 5de39c4
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 33 deletions.
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@ dependencies_up: dependencies_down
tests:
go test -v ./...

.PHONY: example
.PHONY: build-example
## example: runs an http-server locally
example:
build-example:
go build -o bin/server github.com/rbroggi/streamingconfig/example/server
./bin/server
go build -o bin/app github.com/rbroggi/streamingconfig/example/app

.PHONY: run-example-server
## run-example-server: runs an http-server locally
run-example-server: build-example
./bin/server

.PHONY: run-example-app
## run-example-app: runs an http-server locally
run-example-app: build-example
./bin/app
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,17 @@ make dependencies_up
make tests
```

### Run example server
### Run example

Start by starting the dependencies (mongo), and run the example-server which is a simple HTTP server to receive GET,POST requests for reading/updating configurations.
```shell
make dependencies_up
make example
make run-example-server
```

Optionally, you can also start a second server to check that the changes happening in one server will be reflected in the other:
on a different shell, run the sample APP, which is an app that receives changes upon changes that happen in the configuration through the server API endpoints.

```shell
HTTP_PORT=8081 make example
make run-example-app
```

#### Getting latest configuration request
Expand Down
64 changes: 64 additions & 0 deletions example/app/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import (
"context"
"fmt"
"log"
"log/slog"
"os"
"os/signal"
"syscall"
"time"

config "github.com/rbroggi/streamingconfig"
appcfg "github.com/rbroggi/streamingconfig/example/config"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
runnableCtx, cancelRunnables := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancelRunnables()
_, done := initRepo(runnableCtx)
// until shutdown signal is sent
<-runnableCtx.Done()
<-done
}

func initRepo(ctx context.Context) (*config.WatchedRepo[*appcfg.Conf], <-chan struct{}) {
lgr := slog.Default()
db := getDb()
repo, err := config.NewWatchedRepo[*appcfg.Conf](
config.Args{
Logger: lgr,
DB: db,
}, config.WithOnUpdate[*appcfg.Conf](func(conf *appcfg.Conf) {
lgr.With("cfg", conf).Debug("config updated")
slog.SetLogLoggerLevel(conf.LogLevel)
}))
if err != nil {
log.Fatal(err)
}
done, err := repo.Start(ctx)
if err != nil {
log.Fatal(err)
}
return repo, done
}

func getDb() *mongo.Database {
ctx, cnl := context.WithTimeout(context.Background(), 5*time.Second)
defer cnl()
// use test name as db name to parallel tests.
opts := options.Client()
opts.ApplyURI("mongodb://localhost:27017/?connect=direct")
client, err := mongo.Connect(ctx, opts)
if err != nil {
panic(fmt.Errorf("run `make dependencies_up` before, error: %w", err))
}
err = client.Ping(ctx, nil)
if err != nil {
panic(fmt.Errorf("error %v\nrun `make dependencies_up` before running main\n", err))
}
return client.Database("test")
}
27 changes: 27 additions & 0 deletions example/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package config

import (
"errors"
"log/slog"

config "github.com/rbroggi/streamingconfig"
)

type Conf struct {
LogLevel slog.Level `json:"logLevel" default:"\"DEBUG\""`
Name string `json:"name" default:"john"`
Age int `json:"age"`
Friends []string `json:"friends" default:"[\"mark\",\"tom\",\"jack\"]"`
}

func (c *Conf) Update(new config.Config) error {
newCfg, ok := new.(*Conf)
if !ok {
return errors.New("wrong configuration")
}
c.Name = newCfg.Name
c.Age = newCfg.Age
c.Friends = newCfg.Friends
c.LogLevel = newCfg.LogLevel
return nil
}
7 changes: 4 additions & 3 deletions example/server/configs.http
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ PUT http://localhost:8080/configs/latest
user-id: pippo

{
"name": "gloria",
"age": 38,
"friends": ["joe", "mark"]
"name": "john",
"logLevel": "DEBUG",
"age": 40,
"friends": ["jack", "doug"]
}

### List config versions
Expand Down
22 changes: 3 additions & 19 deletions example/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,12 @@ import (
"time"

config "github.com/rbroggi/streamingconfig"
appcfg "github.com/rbroggi/streamingconfig/example/config"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

type conf struct {
Name string `json:"name" default:"john"`
Age int `json:"age"`
Friends []string `json:"friends" default:"[\"mark\",\"tom\",\"jack\"]"`
}

func (c *conf) Update(new config.Config) error {
newCfg, ok := new.(*conf)
if !ok {
return errors.New("wrong configuration")
}
c.Name = newCfg.Name
c.Age = newCfg.Age
c.Friends = newCfg.Friends
return nil
}

func main() {
port := os.Getenv("HTTP_PORT")
if port == "" {
Expand Down Expand Up @@ -75,10 +59,10 @@ func main() {
<-done
}

func initRepo(ctx context.Context) (*config.WatchedRepo[*conf], <-chan struct{}) {
func initRepo(ctx context.Context) (*config.WatchedRepo[*appcfg.Conf], <-chan struct{}) {
lgr := slog.Default()
db := getDb()
repo, err := config.NewWatchedRepo[*conf](
repo, err := config.NewWatchedRepo[*appcfg.Conf](
config.Args{
Logger: lgr,
DB: db,
Expand Down
7 changes: 4 additions & 3 deletions example/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (
"strconv"

config "github.com/rbroggi/streamingconfig"
appcfg "github.com/rbroggi/streamingconfig/example/config"
)

type server struct {
lgr *slog.Logger
repo *config.WatchedRepo[*conf]
repo *config.WatchedRepo[*appcfg.Conf]
}

// latestConfigHandler returns the latest configuration
Expand Down Expand Up @@ -50,7 +51,7 @@ func (s *server) putConfigHandler(w http.ResponseWriter, r *http.Request) {
// Close the body to avoid leaks
defer r.Body.Close()

cfg := new(conf)
cfg := new(appcfg.Conf)
err = json.Unmarshal(body, cfg)
if err != nil {
s.lgr.With("error", err).ErrorContext(r.Context(), "unmarshalling request into configuration")
Expand All @@ -59,7 +60,7 @@ func (s *server) putConfigHandler(w http.ResponseWriter, r *http.Request) {
return
}

updated, err := s.repo.UpdateConfig(r.Context(), config.UpdateConfigCmd[*conf]{
updated, err := s.repo.UpdateConfig(r.Context(), config.UpdateConfigCmd[*appcfg.Conf]{
By: userID,
Config: cfg,
})
Expand Down

0 comments on commit 5de39c4

Please sign in to comment.