Skip to content

Commit

Permalink
refactor for each network to be on different handle
Browse files Browse the repository at this point in the history
  • Loading branch information
MakMuftic committed Mar 13, 2024
1 parent e08df13 commit bab8413
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 64 deletions.
2 changes: 1 addition & 1 deletion internal/proxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type HealthCheckConfig struct {
}

type ProxyConfig struct { // nolint:revive
Port string `yaml:"port"`
Path string `yaml:"path"`
UpstreamTimeout time.Duration `yaml:"upstreamTimeout"`
}

Expand Down
74 changes: 14 additions & 60 deletions internal/rpcgateway/rpcgateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,28 @@ package rpcgateway
import (
"context"
"fmt"
"github.com/sygmaprotocol/rpc-gateway/internal/util"

Check failure on line 6 in internal/rpcgateway/rpcgateway.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"log/slog"
"net/http"
"os"
"time"

"github.com/sygmaprotocol/rpc-gateway/internal/util"

"github.com/carlmjohnson/flowmatic"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httplog/v2"
"github.com/pkg/errors"
"github.com/sygmaprotocol/rpc-gateway/internal/metrics"
"github.com/sygmaprotocol/rpc-gateway/internal/proxy"
)

type RPCGateway struct {
config RPCGatewayConfig
proxy *proxy.Proxy
hcm *proxy.HealthCheckManager
server *http.Server
metrics *metrics.Server
}

func (r *RPCGateway) ServeHTTP(w http.ResponseWriter, req *http.Request) {
r.server.Handler.ServeHTTP(w, req)
config RPCGatewayConfig
proxy *proxy.Proxy
hcm *proxy.HealthCheckManager
}

func (r *RPCGateway) Start(c context.Context) error {
return flowmatic.Do(
func() error {
return errors.Wrap(r.hcm.Start(c), "failed to start health check manager")
},
func() error {
return errors.Wrap(r.server.ListenAndServe(), "failed to start rpc-gateway")
},
func() error {
return errors.Wrap(r.metrics.Start(), "failed to start metrics server")
},
)
}

Expand All @@ -50,27 +33,15 @@ func (r *RPCGateway) Stop(c context.Context) error {
func() error {
return errors.Wrap(r.hcm.Stop(c), "failed to stop health check manager")
},
func() error {
return errors.Wrap(r.server.Close(), "failed to stop rpc-gateway")
},
func() error {
return errors.Wrap(r.metrics.Stop(), "failed to stop metrics server")
},
)
}

func NewRPCGateway(config RPCGatewayConfig, metricsServer *metrics.Server) (*RPCGateway, error) {
func NewRPCGateway(config RPCGatewayConfig, router *chi.Mux, metricsServer *metrics.Server) (*RPCGateway, error) {

Check warning on line 39 in internal/rpcgateway/rpcgateway.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'metricsServer' seems to be unused, consider removing or renaming it as _ (revive)
logLevel := slog.LevelWarn
if os.Getenv("DEBUG") == "true" {
logLevel = slog.LevelDebug
}

logger := httplog.NewLogger("rpc-gateway", httplog.Options{
JSON: true,
RequestHeaders: true,
LogLevel: logLevel,
})

hcm, err := proxy.NewHealthCheckManager(
proxy.HealthCheckManagerConfig{
Targets: config.Targets,
Expand All @@ -97,42 +68,25 @@ func NewRPCGateway(config RPCGatewayConfig, metricsServer *metrics.Server) (*RPC
return nil, errors.Wrap(err, "proxy failed")
}

r := chi.NewRouter()
r.Use(httplog.RequestLogger(logger))

// Recoverer is a middleware that recovers from panics, logs the panic (and
// a backtrace), and returns a HTTP 500 (Internal Server Error) status if
// possible. Recoverer prints a request ID if one is provided.
//
r.Use(middleware.Recoverer)

r.Handle("/", proxy)
router.Handle(fmt.Sprintf("/%s", config.Proxy.Path), proxy)

return &RPCGateway{
config: config,
proxy: proxy,
hcm: hcm,
metrics: metricsServer,
server: &http.Server{
Addr: fmt.Sprintf(":%s", config.Proxy.Port),
Handler: r,
WriteTimeout: time.Second * 15,
ReadTimeout: time.Second * 15,
ReadHeaderTimeout: time.Second * 5,
},
config: config,
proxy: proxy,
hcm: hcm,
}, nil
}

// NewRPCGatewayFromConfigFile creates an instance of RPCGateway from provided
// configuration file.
func NewRPCGatewayFromConfigFile(s string, server *metrics.Server) (*RPCGateway, error) {
config, err := util.LoadYamlFile[RPCGatewayConfig](s)
func NewRPCGatewayFromConfigFile(fileOrUrl string, router *chi.Mux, metricsServer *metrics.Server) (*RPCGateway, error) {

Check warning on line 82 in internal/rpcgateway/rpcgateway.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: func parameter fileOrUrl should be fileOrURL (revive)
config, err := util.LoadYamlFile[RPCGatewayConfig](fileOrUrl)
if err != nil {
return nil, errors.Wrap(err, "failed to load config")
}

fmt.Println("Starting RPC Gateway for " + config.Name + " on port: " + config.Proxy.Port)
fmt.Println("Starting RPC Gateway for " + config.Name + " on path: /" + config.Proxy.Path)

// Pass the metrics server as an argument to NewRPCGateway.
return NewRPCGateway(*config, server)
// Pass the metrics router as an argument to NewRPCGateway.
return NewRPCGateway(*config, router, metricsServer)
}
42 changes: 39 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ package main
import (
"context"
"fmt"
"github.com/go-chi/chi/v5"

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httplog/v2"
"log/slog"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/sygmaprotocol/rpc-gateway/internal/metrics"
"github.com/sygmaprotocol/rpc-gateway/internal/util"
Expand All @@ -22,6 +28,7 @@ type MetricsConfig struct {

type Config struct {
Metrics MetricsConfig `yaml:"metrics"`
Port string `yaml:"port"`
Gateways []GatewayConfig `yaml:"gateways"`
}

Expand Down Expand Up @@ -51,20 +58,49 @@ func main() {
return errors.Wrap(err, "failed to load config")
}

logLevel := slog.LevelWarn
if os.Getenv("DEBUG") == "true" {
logLevel = slog.LevelDebug
}

logger := httplog.NewLogger("rpc-gateway", httplog.Options{
JSON: true,
RequestHeaders: true,
LogLevel: logLevel,
})

metricsServer := metrics.NewServer(metrics.Config{Port: uint(config.Metrics.Port)})

r := chi.NewRouter()
r.Use(httplog.RequestLogger(logger))
r.Use(middleware.Recoverer)
server := &http.Server{
Addr: fmt.Sprintf(":%s", config.Port),
Handler: r,
WriteTimeout: time.Second * 15,
ReadTimeout: time.Second * 15,
ReadHeaderTimeout: time.Second * 5,
}
defer server.Close()

var wg sync.WaitGroup
for _, gatewayConfig := range config.Gateways {
wg.Add(1)
go func(gwConfig GatewayConfig) {
defer wg.Done()
err := startGateway(c, gwConfig, metricsServer)
err := startGateway(c, gwConfig, r, metricsServer)
if err != nil {
fmt.Fprintf(os.Stderr, "error starting gateway '%s': %v\n", gwConfig.Name, err)
}
}(gatewayConfig)
}

fmt.Println("Starting RPC Gateway server on port: " + config.Port)
err = server.ListenAndServe()
if err != nil {
return err
}

wg.Wait()

return nil
Expand All @@ -76,8 +112,8 @@ func main() {
}
}

func startGateway(ctx context.Context, config GatewayConfig, server *metrics.Server) error {
service, err := rpcgateway.NewRPCGatewayFromConfigFile(config.ConfigFile, server)
func startGateway(ctx context.Context, config GatewayConfig, router *chi.Mux, metricsServer *metrics.Server) error {
service, err := rpcgateway.NewRPCGatewayFromConfigFile(config.ConfigFile, router, metricsServer)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("%s rpc-gateway failed", config.Name))
}
Expand Down

0 comments on commit bab8413

Please sign in to comment.