Futher reduce allocations on the compiler hot path
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
package serv
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/flect"
|
||||
)
|
||||
|
||||
@ -84,8 +86,8 @@ type configRemote struct {
|
||||
} `mapstructure:"set_headers"`
|
||||
}
|
||||
|
||||
func (c *config) getAliasMap() map[string]string {
|
||||
m := make(map[string]string, len(c.DB.Tables))
|
||||
func (c *config) getAliasMap() map[string][]string {
|
||||
m := make(map[string][]string, len(c.DB.Tables))
|
||||
|
||||
for i := range c.DB.Tables {
|
||||
t := c.DB.Tables[i]
|
||||
@ -93,7 +95,9 @@ func (c *config) getAliasMap() map[string]string {
|
||||
if len(t.Table) == 0 {
|
||||
continue
|
||||
}
|
||||
m[flect.Pluralize(t.Name)] = t.Table
|
||||
|
||||
k := strings.ToLower(t.Table)
|
||||
m[k] = append(m[k], strings.ToLower(t.Name))
|
||||
}
|
||||
return m
|
||||
}
|
||||
@ -107,12 +111,16 @@ func (c *config) getFilterMap() map[string][]string {
|
||||
if len(t.Filter) == 0 {
|
||||
continue
|
||||
}
|
||||
name := flect.Pluralize(t.Name)
|
||||
singular := flect.Singularize(t.Name)
|
||||
plural := flect.Pluralize(t.Name)
|
||||
|
||||
if t.Filter[0] == "none" {
|
||||
m[name] = []string{}
|
||||
m[singular] = []string{}
|
||||
m[plural] = []string{}
|
||||
|
||||
} else {
|
||||
m[name] = t.Filter
|
||||
m[singular] = t.Filter
|
||||
m[plural] = t.Filter
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,6 @@ func (c *coreContext) resolveRemotes(
|
||||
|
||||
to[n] = jsn.Field{[]byte(s.FieldName), ob.Bytes()}
|
||||
}(i, id, s)
|
||||
fmt.Println(">>>", i)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
|
33
serv/reso.go
33
serv/reso.go
@ -22,16 +22,21 @@ type resolvFn struct {
|
||||
Fn func(r *http.Request, id []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
func initResolvers() {
|
||||
func initResolvers() error {
|
||||
rmap = make(map[uint64]*resolvFn)
|
||||
|
||||
for _, t := range conf.DB.Tables {
|
||||
initRemotes(t)
|
||||
err := initRemotes(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func initRemotes(t configTable) {
|
||||
func initRemotes(t configTable) error {
|
||||
h := xxhash.New()
|
||||
var err error
|
||||
|
||||
for _, r := range t.Remotes {
|
||||
// defines the table column to be used as an id in the
|
||||
@ -41,24 +46,26 @@ func initRemotes(t configTable) {
|
||||
// if no table column specified in the config then
|
||||
// use the primary key of the table as the id
|
||||
if len(idcol) == 0 {
|
||||
idcol = pcompile.IDColumn(t.Name)
|
||||
idcol, err = pcompile.IDColumn(t.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
idk := fmt.Sprintf("__%s_%s", t.Name, idcol)
|
||||
|
||||
// register a relationship between the remote data
|
||||
// and the database table
|
||||
|
||||
h.WriteString(strings.ToLower(r.Name))
|
||||
h.WriteString(t.Name)
|
||||
key := h.Sum64()
|
||||
h.Reset()
|
||||
|
||||
val := &psql.DBRel{
|
||||
Type: psql.RelRemote,
|
||||
Col1: idcol,
|
||||
Col2: idk,
|
||||
}
|
||||
pcompile.AddRelationship(key, val)
|
||||
|
||||
err := pcompile.AddRelationship(strings.ToLower(r.Name), t.Name, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the function thats called to resolve this remote
|
||||
// data request
|
||||
@ -81,6 +88,8 @@ func initRemotes(t configTable) {
|
||||
// index resolver obj by IDField
|
||||
rmap[xxhash.Sum64(rf.IDField)] = rf
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildFn(r configRemote) func(*http.Request, []byte) ([]byte, error) {
|
||||
@ -88,7 +97,8 @@ func buildFn(r configRemote) func(*http.Request, []byte) ([]byte, error) {
|
||||
client := &http.Client{}
|
||||
|
||||
fn := func(inReq *http.Request, id []byte) ([]byte, error) {
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf(reqURL, id), nil)
|
||||
uri := fmt.Sprintf(reqURL, id)
|
||||
req, err := http.NewRequest("GET", uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -107,6 +117,7 @@ func buildFn(r configRemote) func(*http.Request, []byte) ([]byte, error) {
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msgf("Failed to connect to: %s", uri)
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
23
serv/serv.go
23
serv/serv.go
@ -150,7 +150,7 @@ func initDB(c *config) (*pg.DB, error) {
|
||||
}
|
||||
|
||||
func initCompilers(c *config) (*qcode.Compiler, *psql.Compiler, error) {
|
||||
schema, err := psql.NewDBSchema(db)
|
||||
schema, err := psql.NewDBSchema(db, c.getAliasMap())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -167,9 +167,8 @@ func initCompilers(c *config) (*qcode.Compiler, *psql.Compiler, error) {
|
||||
}
|
||||
|
||||
pc := psql.NewCompiler(psql.Config{
|
||||
Schema: schema,
|
||||
Vars: c.DB.Variables,
|
||||
TableMap: c.getAliasMap(),
|
||||
Schema: schema,
|
||||
Vars: c.DB.Variables,
|
||||
})
|
||||
|
||||
return qc, pc, nil
|
||||
@ -182,20 +181,22 @@ func Init() {
|
||||
|
||||
conf, err = initConf()
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err)
|
||||
logger.Fatal().Err(err).Msg("failed to read config")
|
||||
}
|
||||
|
||||
db, err = initDB(conf)
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err)
|
||||
logger.Fatal().Err(err).Msg("failed to connect to database")
|
||||
}
|
||||
|
||||
qcompile, pcompile, err = initCompilers(conf)
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err)
|
||||
logger.Fatal().Err(err).Msg("failed to connect to database")
|
||||
}
|
||||
|
||||
initResolvers()
|
||||
if err := initResolvers(); err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to initialized resolvers")
|
||||
}
|
||||
|
||||
startHTTP()
|
||||
}
|
||||
@ -216,21 +217,21 @@ func startHTTP() {
|
||||
<-sigint
|
||||
|
||||
if err := srv.Shutdown(context.Background()); err != nil {
|
||||
logger.Printf("http: %v", err)
|
||||
logger.Error().Err(err).Msg("shutdown signal received")
|
||||
}
|
||||
close(idleConnsClosed)
|
||||
}()
|
||||
|
||||
srv.RegisterOnShutdown(func() {
|
||||
if err := db.Close(); err != nil {
|
||||
logger.Error().Err(err)
|
||||
logger.Error().Err(err).Msg("db closed")
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Printf("%s listening on %s (%s)\n", serverName, conf.HostPort, conf.Env)
|
||||
|
||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||
fmt.Println(err)
|
||||
logger.Error().Err(err).Msg("server closed")
|
||||
}
|
||||
|
||||
<-idleConnsClosed
|
||||
|
Reference in New Issue
Block a user