Skip to content

Commit

Permalink
fix: db opened multiple times on startup
Browse files Browse the repository at this point in the history
  • Loading branch information
dosco committed Mar 8, 2021
1 parent 9a9715c commit b1bd0f0
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 21 deletions.
1 change: 1 addition & 0 deletions core/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ type GraphJin struct {
conf *Config
db *sql.DB
log *_log.Logger
dbtype string
dbinfo *sdata.DBInfo
schema *sdata.DBSchema
allowList *allow.List
Expand Down
16 changes: 9 additions & 7 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,27 @@ type qres struct {
}

func (gj *GraphJin) initDiscover() error {
if gj.conf.DBType == "" {
gj.dbtype = "postgres"
} else {
gj.dbtype = gj.conf.DBType
}

if err := gj._initDiscover(); err != nil {
return fmt.Errorf("%s: %w", gj.conf.DBType, err)
return fmt.Errorf("%s: %w", gj.dbtype, err)
}
return nil
}

func (gj *GraphJin) _initDiscover() error {
var err error

if gj.conf.DBType == "" {
gj.conf.DBType = "postgres"
}

// If gj.dbinfo is not null then it's probably set
// for tests
if gj.dbinfo == nil {
gj.dbinfo, err = sdata.GetDBInfo(
gj.db,
gj.conf.DBType,
gj.dbtype,
gj.conf.Blocklist)
}

Expand All @@ -89,7 +91,7 @@ func (gj *GraphJin) _initDiscover() error {

func (gj *GraphJin) initSchema() error {
if err := gj._initSchema(); err != nil {
return fmt.Errorf("%s: %w", gj.conf.DBType, err)
return fmt.Errorf("%s: %w", gj.dbtype, err)
}
return nil
}
Expand Down
1 change: 1 addition & 0 deletions core/core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func TestMain(m *testing.M) {
if err != nil {
panic(err)
}
db.SetMaxIdleConns(100)
dbType = v.name

if res := m.Run(); res != 0 {
Expand Down
2 changes: 0 additions & 2 deletions core/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ func (gj *GraphJin) initConfig() error {
Name: "user",
tm: make(map[string]*RoleTable),
}
c.Roles = append(c.Roles, ur)
gj.roles["user"] = &ur
}

Expand All @@ -73,7 +72,6 @@ func (gj *GraphJin) initConfig() error {
Name: "anon",
tm: make(map[string]*RoleTable),
}
c.Roles = append(c.Roles, ur)
gj.roles["anon"] = &ur
}

Expand Down
2 changes: 2 additions & 0 deletions core/internal/psql/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func (co *Compiler) Compile(w *bytes.Buffer, qc *qcode.QCode) (Metadata, error)
return md, fmt.Errorf("qcode is nil")
}

w.WriteString(`/* action='` + qc.Name + `',controller='graphql',framework='graphjin' */ `)

switch qc.Type {
case qcode.QTQuery:
co.CompileQuery(w, qc, &md)
Expand Down
7 changes: 4 additions & 3 deletions core/internal/qcode/qcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type ColKey struct {
type QCode struct {
Type QType
SType QType
Name string
ActionVar string
Selects []Select
Vars Variables
Expand Down Expand Up @@ -246,14 +247,14 @@ type Variables map[string]json.RawMessage
func (co *Compiler) Compile(query []byte, vars Variables, role string) (*QCode, error) {
var err error

qc := QCode{SType: QTQuery, Schema: co.s, Vars: vars}
qc.Roots = qc.rootsA[:0]

op, err := graph.Parse(query, co.c.FragmentFetcher)
if err != nil {
return nil, err
}

qc := QCode{Name: op.Name, SType: QTQuery, Schema: co.s, Vars: vars}
qc.Roots = qc.rootsA[:0]

switch op.Type {
case graph.OpQuery:
qc.Type = QTQuery
Expand Down
9 changes: 5 additions & 4 deletions core/internal/sdata/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,15 @@ func NewDBSchema(
if err != nil {
return nil, err
}
}

// Add aliases to edge index by duplicating
// table nodes
for _, alias := range aliases[t.Name] {
// Add aliases to edge index by duplicating
for t, al := range aliases {
for _, alias := range al {
if _, ok := schema.ei[alias]; ok {
continue
}
if e, ok := schema.ei[t.Name]; ok {
if e, ok := schema.ei[t]; ok {
schema.ei[alias] = e
}
}
Expand Down
4 changes: 4 additions & 0 deletions core/introspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ type intro struct {
}

func (gj *GraphJin) initGraphQLEgine() error {
if gj.prod {
return nil
}

engine := graphql.New()
in := &intro{
Schema: engine.Schema,
Expand Down
54 changes: 54 additions & 0 deletions core/query2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/dosco/graphjin/core"
"github.com/stretchr/testify/assert"
"golang.org/x/sync/errgroup"
)

func TestQuery(t *testing.T) {
Expand Down Expand Up @@ -155,6 +156,59 @@ func TestConfigRoleManagement(t *testing.T) {
assert.Empty(t, conf.Roles)
}

func TestParallelRuns(t *testing.T) {
gql := `query {
me {
id
email
products {
id
}
}
}`

// TODO: introspection engine has race condition in dev
// mode.
conf := &core.Config{Production: true, DisableAllowList: true,
Tables: []core.Table{
{Name: "me", Table: "users"},
},
}

err := conf.AddRoleTable("user", "me", core.Query{
Filters: []string{"{ id: { eq: $user_id } }"},
})
if err != nil {
panic(err)
}

g := errgroup.Group{}

for i := 0; i < 10; i++ {
x := i
g.Go(func() error {
for n := 0; n < 10; n++ {
gj, err := core.NewGraphJin(conf, db)
if err != nil {
return fmt.Errorf("%d: %w", x, err)
}

ctx := context.WithValue(context.Background(), core.UserIDKey, x)
_, err = gj.GraphQL(ctx, gql, nil, nil)
if err != nil {
return fmt.Errorf("%d: %w", x, err)
}
// fmt.Println(x, ">", string(res.Data))
}
return nil
})
}

if err := g.Wait(); err != nil {
t.Error(err)
}
}

var benchGQL = `query {
products(
# returns only 30 items
Expand Down
2 changes: 1 addition & 1 deletion core/subs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func TestSubscription(t *testing.T) {

w := sync.WaitGroup{}

for i := 101; i < 8128; i++ {
for i := 101; i < 5000; i++ {
w.Add(1)
go func(n int) {
id := (rand.Intn(100-1) + 1)
Expand Down
7 changes: 3 additions & 4 deletions internal/serv/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,17 @@ func initDB(servConfig *ServConfig, useDB, useTelemetry bool) (*sql.DB, error) {
}

for i := 1; i < 10; i++ {
db, err = sql.Open(dc.driverName, dc.connString)
if err != nil {
continue
if db, err = sql.Open(dc.driverName, dc.connString); err == nil {
break
}

time.Sleep(time.Duration(i*100) * time.Millisecond)
}

if err != nil {
return nil, fmt.Errorf("unable to open db connection: %v", err)
}

db.SetMaxIdleConns(100)
return db, nil
}

Expand Down

0 comments on commit b1bd0f0

Please sign in to comment.