X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e95bf5c03b1b956b9a7196c2a6c357e79f6eb60e..35d4eea994c98b4bb65111c9da6e57abbc7e014f:/lib/ctrlctx/db.go diff --git a/lib/ctrlctx/db.go b/lib/ctrlctx/db.go index a764208606..d33fd8ab53 100644 --- a/lib/ctrlctx/db.go +++ b/lib/ctrlctx/db.go @@ -10,6 +10,7 @@ import ( "sync" "git.arvados.org/arvados.git/lib/controller/api" + "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/ctxlog" "github.com/jmoiron/sqlx" @@ -68,7 +69,7 @@ type finishFunc func(*error) // commit or rollback the transaction, if any. // // func example(ctx context.Context) (err error) { -// ctx, finishtx := New(ctx, dber) +// ctx, finishtx := New(ctx, getdb) // defer finishtx(&err) // // ... // tx, err := CurrentTx(ctx) @@ -142,3 +143,45 @@ func CurrentTx(ctx context.Context) (*sqlx.Tx, error) { }) return txn.tx, txn.err } + +var errDBConnection = errors.New("database connection error") + +type DBConnector struct { + PostgreSQL arvados.PostgreSQL + pgdb *sqlx.DB + mtx sync.Mutex +} + +func (dbc *DBConnector) GetDB(ctx context.Context) (*sqlx.DB, error) { + dbc.mtx.Lock() + defer dbc.mtx.Unlock() + if dbc.pgdb != nil { + return dbc.pgdb, nil + } + db, err := sqlx.Open("postgres", dbc.PostgreSQL.Connection.String()) + if err != nil { + ctxlog.FromContext(ctx).WithError(err).Error("postgresql connect failed") + return nil, errDBConnection + } + if p := dbc.PostgreSQL.ConnectionPool; p > 0 { + db.SetMaxOpenConns(p) + } + if err := db.Ping(); err != nil { + ctxlog.FromContext(ctx).WithError(err).Error("postgresql connect succeeded but ping failed") + db.Close() + return nil, errDBConnection + } + dbc.pgdb = db + return db, nil +} + +func (dbc *DBConnector) Close() error { + dbc.mtx.Lock() + defer dbc.mtx.Unlock() + var err error + if dbc.pgdb != nil { + err = dbc.pgdb.Close() + dbc.pgdb = nil + } + return err +}