refactor: move handler register to apps

This commit is contained in:
Jon Lundy 2022-08-19 13:57:07 -06:00
parent 814c974e93
commit 0a964cb631
Signed by untrusted user who does not match committer: xuu
GPG Key ID: C63E6D61F3035024
5 changed files with 43 additions and 88 deletions

View File

@ -1,55 +0,0 @@
package gql_ev
import (
"context"
"net/http"
"reflect"
"github.com/sour-is/ev/app/msgbus"
"github.com/sour-is/ev/app/salty"
"github.com/sour-is/ev/internal/graph/generated"
"github.com/sour-is/ev/internal/logz"
)
type Resolver struct {
msgbus.MsgbusResolver
salty.SaltyResolver
}
func New(ctx context.Context, m msgbus.MsgbusResolver, s salty.SaltyResolver) (*Resolver, error) {
_, span := logz.Span(ctx)
defer span.End()
r := &Resolver{m, s}
return r, nil
}
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return r }
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return r }
// Subscription returns generated.SubscriptionResolver implementation.
func (r *Resolver) Subscription() generated.SubscriptionResolver { return r }
// ChainMiddlewares will check all embeded resolvers for a GetMiddleware func and add to handler.
func (r *Resolver) ChainMiddlewares(h http.Handler) http.Handler {
v := reflect.ValueOf(r) // Get reflected value of *Resolver
v = reflect.Indirect(v) // Get the pointed value (returns a zero value on nil)
n := v.NumField() // Get number of fields to iterate over.
for i := 0; i < n; i++ {
f := v.Field(i)
if !f.CanInterface() { // Skip non-interface types.
continue
}
if iface, ok := f.Interface().(interface {
GetMiddleware() func(http.Handler) http.Handler
}); ok {
h = iface.GetMiddleware()(h) // Append only items that fulfill the interface.
}
}
return h
}

View File

@ -70,6 +70,9 @@ var upgrader = websocket.Upgrader{
}, },
} }
func (s *service) RegisterHTTP(mux *http.ServeMux) {
mux.Handle("/inbox/", logz.Htrace(http.StripPrefix("/inbox/", s), "inbox"))
}
func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
ctx, span := logz.Span(ctx) ctx, span := logz.Span(ctx)

View File

@ -69,6 +69,9 @@ func (s *service) BaseURL() string {
} }
return s.baseURL return s.baseURL
} }
func(s *service) RegisterHTTP(mux *http.ServeMux) {
mux.Handle("/.well-known/salty/", logz.Htrace(s, "lookup"))
}
func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
ctx, span := logz.Span(ctx) ctx, span := logz.Span(ctx)

View File

@ -31,11 +31,9 @@ func Meter(ctx context.Context) metric.Meter {
} }
return global.Meter("") return global.Meter("")
} }
func PromHTTP(ctx context.Context) http.Handler { func NewHTTP(ctx context.Context) *httpHandle {
if t := fromContext[contextKey, *prometheus.Exporter](ctx, promHTTPKey); t != nil { t := fromContext[contextKey, *prometheus.Exporter](ctx, promHTTPKey)
return t return &httpHandle{t}
}
return http.NotFoundHandler()
} }
func initMetrics(ctx context.Context, name string) (context.Context, func() error) { func initMetrics(ctx context.Context, name string) (context.Context, func() error) {
@ -88,3 +86,14 @@ func initMetrics(ctx context.Context, name string) (context.Context, func() erro
return cont.Stop(ctx) return cont.Stop(ctx)
} }
} }
type httpHandle struct {
exp *prometheus.Exporter
}
func (h *httpHandle) RegisterHTTP(mux *http.ServeMux) {
if h.exp == nil {
return
}
mux.Handle("/metrics", h.exp)
}

51
main.go
View File

@ -9,16 +9,12 @@ import (
"path" "path"
"time" "time"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/ravilushqa/otelgqlgen"
"github.com/rs/cors" "github.com/rs/cors"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"github.com/sour-is/ev/api/gql_ev" "github.com/sour-is/ev/app/gql"
"github.com/sour-is/ev/app/msgbus" "github.com/sour-is/ev/app/msgbus"
"github.com/sour-is/ev/app/playground"
"github.com/sour-is/ev/app/salty" "github.com/sour-is/ev/app/salty"
"github.com/sour-is/ev/internal/graph/generated"
"github.com/sour-is/ev/internal/logz" "github.com/sour-is/ev/internal/logz"
"github.com/sour-is/ev/pkg/es" "github.com/sour-is/ev/pkg/es"
diskstore "github.com/sour-is/ev/pkg/es/driver/disk-store" diskstore "github.com/sour-is/ev/pkg/es/driver/disk-store"
@ -38,12 +34,6 @@ func main() {
ctx, stop := logz.Init(ctx, AppName) ctx, stop := logz.Init(ctx, AppName)
defer stop() defer stop()
Mup, err := logz.Meter(ctx).SyncInt64().UpDownCounter("up")
if err != nil {
log.Fatal(err)
}
Mup.Add(ctx, 1)
if err := run(ctx); err != nil && err != http.ErrServerClosed { if err := run(ctx); err != nil && err != http.ErrServerClosed {
log.Fatal(err) log.Fatal(err)
} }
@ -67,41 +57,35 @@ func run(ctx context.Context) error {
Addr: env("EV_HTTP", ":8080"), Addr: env("EV_HTTP", ":8080"),
} }
saltySVC, err := salty.New(ctx, es, path.Join(env("EV_BASE_URL", "http://localhost" + s.Addr), "inbox")) salty, err := salty.New(ctx, es, path.Join(env("EV_BASE_URL", "http://localhost"+s.Addr), "inbox"))
if err != nil { if err != nil {
span.RecordError(err) span.RecordError(err)
return err return err
} }
msgbusSVC, err := msgbus.New(ctx, es) msgbus, err := msgbus.New(ctx, es)
if err != nil { if err != nil {
span.RecordError(err) span.RecordError(err)
return err return err
} }
res, err := gql_ev.New(ctx, msgbusSVC, saltySVC) gql, err := gql.New(ctx, msgbus, salty)
if err != nil { if err != nil {
span.RecordError(err) span.RecordError(err)
return err return err
} }
gql := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: res}))
gql.Use(otelgqlgen.Middleware())
s.Handler = httpMux(logz.NewHTTP(ctx), msgbus, salty, gql)
mux := http.NewServeMux()
mux.Handle("/", playground.Handler("GraphQL playground", "/gql"))
mux.Handle("/gql", logz.Htrace(res.ChainMiddlewares(gql), "gql"))
mux.Handle("/metrics", logz.PromHTTP(ctx))
mux.Handle("/inbox/", logz.Htrace(http.StripPrefix("/inbox/", msgbusSVC), "inbox"))
mux.Handle("/.well-known/salty/", logz.Htrace(saltySVC, "lookup"))
s.Handler = cors.AllowAll().Handler(mux)
log.Print("Listen on ", s.Addr) log.Print("Listen on ", s.Addr)
span.AddEvent("begin listen and serve") span.AddEvent("begin listen and serve")
Mup, err := logz.Meter(ctx).SyncInt64().UpDownCounter("up")
if err != nil {
return err
}
Mup.Add(ctx, 1)
g.Go(s.ListenAndServe) g.Go(s.ListenAndServe)
g.Go(func() error { g.Go(func() error {
@ -113,7 +97,11 @@ func run(ctx context.Context) error {
span.End() span.End()
} }
return g.Wait()
if err := g.Wait(); err != nil && err != http.ErrServerClosed {
return err
}
return nil
} }
func env(name, defaultValue string) string { func env(name, defaultValue string) string {
if v := os.Getenv(name); v != "" { if v := os.Getenv(name); v != "" {
@ -122,3 +110,10 @@ func env(name, defaultValue string) string {
} }
return defaultValue return defaultValue
} }
func httpMux(fns ...interface{ RegisterHTTP(*http.ServeMux) }) http.Handler {
mux := http.NewServeMux()
for _, fn := range fns {
fn.RegisterHTTP(mux)
}
return cors.AllowAll().Handler(mux)
}