mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Use retry func while trying to ping SQL datastore (#630)
* Use retry func while trying to ping SQL datastore - implements retry func specifically for SQL datastore ping - fmt fixes - using sqlx.Db.PingContext instead of sqlx.Db.Ping - propogate context to SQL datastore * Rely on context from ServerOpt * Consolidate log instances * Cleanup * Fix server usage in API tests
This commit is contained in:
committed by
Reed Allman
parent
4a85806544
commit
faaf5846ce
@@ -1,17 +1,19 @@
|
|||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/datastore/internal/datastoreutil"
|
"github.com/fnproject/fn/api/datastore/internal/datastoreutil"
|
||||||
"github.com/fnproject/fn/api/datastore/sql"
|
"github.com/fnproject/fn/api/datastore/sql"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(dbURL string) (models.Datastore, error) {
|
func New(ctx context.Context, dbURL string) (models.Datastore, error) {
|
||||||
ds, err := newds(dbURL) // teehee
|
ds, err := newds(ctx, dbURL) // teehee
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -19,15 +21,16 @@ func New(dbURL string) (models.Datastore, error) {
|
|||||||
return datastoreutil.MetricDS(datastoreutil.NewValidator(ds)), nil
|
return datastoreutil.MetricDS(datastoreutil.NewValidator(ds)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newds(dbURL string) (models.Datastore, error) {
|
func newds(ctx context.Context, dbURL string) (models.Datastore, error) {
|
||||||
|
log := common.Logger(ctx)
|
||||||
u, err := url.Parse(dbURL)
|
u, err := url.Parse(dbURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{"url": dbURL}).Fatal("bad DB URL")
|
log.WithError(err).WithFields(logrus.Fields{"url": dbURL}).Fatal("bad DB URL")
|
||||||
}
|
}
|
||||||
logrus.WithFields(logrus.Fields{"db": u.Scheme}).Debug("creating new datastore")
|
log.WithFields(logrus.Fields{"db": u.Scheme}).Debug("creating new datastore")
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "sqlite3", "postgres", "mysql":
|
case "sqlite3", "postgres", "mysql":
|
||||||
return sql.New(u)
|
return sql.New(ctx, u)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("db type not supported %v", u.Scheme)
|
return nil, fmt.Errorf("db type not supported %v", u.Scheme)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/datastore/sql/migrations"
|
"github.com/fnproject/fn/api/datastore/sql/migrations"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
@@ -96,14 +97,15 @@ type sqlStore struct {
|
|||||||
|
|
||||||
// New will open the db specified by url, create any tables necessary
|
// New will open the db specified by url, create any tables necessary
|
||||||
// and return a models.Datastore safe for concurrent usage.
|
// and return a models.Datastore safe for concurrent usage.
|
||||||
func New(url *url.URL) (models.Datastore, error) {
|
func New(ctx context.Context, url *url.URL) (models.Datastore, error) {
|
||||||
return newDS(url)
|
return newDS(ctx, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for test methods, return concrete type, but don't expose
|
// for test methods, return concrete type, but don't expose
|
||||||
func newDS(url *url.URL) (*sqlStore, error) {
|
func newDS(ctx context.Context, url *url.URL) (*sqlStore, error) {
|
||||||
driver := url.Scheme
|
driver := url.Scheme
|
||||||
|
|
||||||
|
log := common.Logger(ctx)
|
||||||
// driver must be one of these for sqlx to work, double check:
|
// driver must be one of these for sqlx to work, double check:
|
||||||
switch driver {
|
switch driver {
|
||||||
case "postgres", "pgx", "mysql", "sqlite3":
|
case "postgres", "pgx", "mysql", "sqlite3":
|
||||||
@@ -128,25 +130,25 @@ func newDS(url *url.URL) (*sqlStore, error) {
|
|||||||
|
|
||||||
sqldb, err := sql.Open(driver, uri)
|
sqldb, err := sql.Open(driver, uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithFields(logrus.Fields{"url": uri}).WithError(err).Error("couldn't open db")
|
log.WithFields(logrus.Fields{"url": uri}).WithError(err).Error("couldn't open db")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
db := sqlx.NewDb(sqldb, driver)
|
db := sqlx.NewDb(sqldb, driver)
|
||||||
// force a connection and test that it worked
|
// force a connection and test that it worked
|
||||||
err = db.Ping()
|
err = pingWithRetry(ctx, 10, time.Second*1, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithFields(logrus.Fields{"url": uri}).WithError(err).Error("couldn't ping db")
|
log.WithFields(logrus.Fields{"url": uri}).WithError(err).Error("couldn't ping db")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
maxIdleConns := 256 // TODO we need to strip this out of the URL probably
|
maxIdleConns := 256 // TODO we need to strip this out of the URL probably
|
||||||
db.SetMaxIdleConns(maxIdleConns)
|
db.SetMaxIdleConns(maxIdleConns)
|
||||||
logrus.WithFields(logrus.Fields{"max_idle_connections": maxIdleConns, "datastore": driver}).Info("datastore dialed")
|
log.WithFields(logrus.Fields{"max_idle_connections": maxIdleConns, "datastore": driver}).Info("datastore dialed")
|
||||||
|
|
||||||
err = runMigrations(url.String(), checkExistence(db)) // original url string
|
err = runMigrations(url.String(), checkExistence(db)) // original url string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Error("error running migrations")
|
log.WithError(err).Error("error running migrations")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +157,7 @@ func newDS(url *url.URL) (*sqlStore, error) {
|
|||||||
db.SetMaxOpenConns(1)
|
db.SetMaxOpenConns(1)
|
||||||
}
|
}
|
||||||
for _, v := range tables {
|
for _, v := range tables {
|
||||||
_, err = db.Exec(v)
|
_, err = db.ExecContext(ctx, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -164,6 +166,17 @@ func newDS(url *url.URL) (*sqlStore, error) {
|
|||||||
return &sqlStore{db: db}, nil
|
return &sqlStore{db: db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pingWithRetry(ctx context.Context, attempts int, sleep time.Duration, db *sqlx.DB) (err error) {
|
||||||
|
for i := 0; i < attempts; i++ {
|
||||||
|
err = db.PingContext(ctx)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
time.Sleep(sleep)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// checkExistence checks if tables have been created yet, it is not concerned
|
// checkExistence checks if tables have been created yet, it is not concerned
|
||||||
// about the existence of the schema migration version (since migrations were
|
// about the existence of the schema migration version (since migrations were
|
||||||
// added to existing dbs, we need to know whether the db exists without migrations
|
// added to existing dbs, we need to know whether the db exists without migrations
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"context"
|
||||||
"github.com/fnproject/fn/api/datastore/internal/datastoretest"
|
"github.com/fnproject/fn/api/datastore/internal/datastoretest"
|
||||||
"github.com/fnproject/fn/api/datastore/internal/datastoreutil"
|
"github.com/fnproject/fn/api/datastore/internal/datastoreutil"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
@@ -15,8 +16,8 @@ import (
|
|||||||
// * run all down migrations
|
// * run all down migrations
|
||||||
// * run all up migrations
|
// * run all up migrations
|
||||||
// [ then run tests against that db ]
|
// [ then run tests against that db ]
|
||||||
func newWithMigrations(url *url.URL) (*sqlStore, error) {
|
func newWithMigrations(ctx context.Context, url *url.URL) (*sqlStore, error) {
|
||||||
ds, err := newDS(url)
|
ds, err := newDS(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -32,7 +33,7 @@ func newWithMigrations(url *url.URL) (*sqlStore, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// go through New, to ensure our Up logic works in there...
|
// go through New, to ensure our Up logic works in there...
|
||||||
ds, err = newDS(url)
|
ds, err = newDS(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -41,6 +42,7 @@ func newWithMigrations(url *url.URL) (*sqlStore, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDatastore(t *testing.T) {
|
func TestDatastore(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
defer os.RemoveAll("sqlite_test_dir")
|
defer os.RemoveAll("sqlite_test_dir")
|
||||||
u, err := url.Parse("sqlite3://sqlite_test_dir")
|
u, err := url.Parse("sqlite3://sqlite_test_dir")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -48,7 +50,7 @@ func TestDatastore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
f := func(t *testing.T) models.Datastore {
|
f := func(t *testing.T) models.Datastore {
|
||||||
os.RemoveAll("sqlite_test_dir")
|
os.RemoveAll("sqlite_test_dir")
|
||||||
ds, err := newDS(u)
|
ds, err := newDS(ctx, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -67,7 +69,7 @@ func TestDatastore(t *testing.T) {
|
|||||||
|
|
||||||
both := func(u *url.URL) {
|
both := func(u *url.URL) {
|
||||||
f := func(t *testing.T) models.Datastore {
|
f := func(t *testing.T) models.Datastore {
|
||||||
ds, err := newDS(u)
|
ds, err := newDS(ctx, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -83,7 +85,7 @@ func TestDatastore(t *testing.T) {
|
|||||||
|
|
||||||
f = func(t *testing.T) models.Datastore {
|
f = func(t *testing.T) models.Datastore {
|
||||||
t.Log("with migrations now!")
|
t.Log("with migrations now!")
|
||||||
ds, err := newWithMigrations(u)
|
ds, err := newWithMigrations(ctx, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,21 +4,24 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/datastore/sql"
|
"github.com/fnproject/fn/api/datastore/sql"
|
||||||
"github.com/fnproject/fn/api/logs/s3"
|
"github.com/fnproject/fn/api/logs/s3"
|
||||||
"github.com/fnproject/fn/api/models"
|
"github.com/fnproject/fn/api/models"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(dbURL string) (models.LogStore, error) {
|
func New(ctx context.Context, dbURL string) (models.LogStore, error) {
|
||||||
|
log := common.Logger(ctx)
|
||||||
u, err := url.Parse(dbURL)
|
u, err := url.Parse(dbURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{"url": dbURL}).Fatal("bad DB URL")
|
log.WithError(err).WithFields(logrus.Fields{"url": dbURL}).Fatal("bad DB URL")
|
||||||
}
|
}
|
||||||
logrus.WithFields(logrus.Fields{"db": u.Scheme}).Debug("creating log store")
|
log.WithFields(logrus.Fields{"db": u.Scheme}).Debug("creating log store")
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "sqlite3", "postgres", "mysql":
|
case "sqlite3", "postgres", "mysql":
|
||||||
return sql.New(u)
|
return sql.New(ctx, u)
|
||||||
case "s3":
|
case "s3":
|
||||||
return s3.New(u)
|
return s3.New(u)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"context"
|
||||||
"github.com/fnproject/fn/api/datastore/sql"
|
"github.com/fnproject/fn/api/datastore/sql"
|
||||||
logTesting "github.com/fnproject/fn/api/logs/testing"
|
logTesting "github.com/fnproject/fn/api/logs/testing"
|
||||||
)
|
)
|
||||||
@@ -13,12 +14,13 @@ const tmpLogDb = "/tmp/func_test_log.db"
|
|||||||
|
|
||||||
func TestDatastore(t *testing.T) {
|
func TestDatastore(t *testing.T) {
|
||||||
os.Remove(tmpLogDb)
|
os.Remove(tmpLogDb)
|
||||||
|
ctx := context.Background()
|
||||||
uLog, err := url.Parse("sqlite3://" + tmpLogDb)
|
uLog, err := url.Parse("sqlite3://" + tmpLogDb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to parse url: %v", err)
|
t.Fatalf("failed to parse url: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds, err := sql.New(uLog)
|
ds, err := sql.New(ctx, uLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create sqlite3 datastore: %v", err)
|
t.Fatalf("failed to create sqlite3 datastore: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/fnproject/fn/api/agent"
|
"github.com/fnproject/fn/api/agent"
|
||||||
"github.com/fnproject/fn/api/agent/hybrid"
|
"github.com/fnproject/fn/api/agent/hybrid"
|
||||||
|
"github.com/fnproject/fn/api/common"
|
||||||
"github.com/fnproject/fn/api/datastore"
|
"github.com/fnproject/fn/api/datastore"
|
||||||
"github.com/fnproject/fn/api/id"
|
"github.com/fnproject/fn/api/id"
|
||||||
"github.com/fnproject/fn/api/logs"
|
"github.com/fnproject/fn/api/logs"
|
||||||
@@ -116,74 +117,96 @@ func pwd() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WithDBURL(dbURL string) ServerOption {
|
func WithDBURL(dbURL string) ServerOption {
|
||||||
if dbURL != "" {
|
return func(ctx context.Context, s *Server) error {
|
||||||
ds, err := datastore.New(dbURL)
|
if dbURL != "" {
|
||||||
if err != nil {
|
ds, err := datastore.New(ctx, dbURL)
|
||||||
logrus.WithError(err).Fatalln("Error initializing datastore.")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.datastore = ds
|
||||||
}
|
}
|
||||||
return WithDatastore(ds)
|
return nil
|
||||||
}
|
}
|
||||||
return noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithMQURL(mqURL string) ServerOption {
|
func WithMQURL(mqURL string) ServerOption {
|
||||||
if mqURL != "" {
|
return func(ctx context.Context, s *Server) error {
|
||||||
mq, err := mqs.New(mqURL)
|
if mqURL != "" {
|
||||||
if err != nil {
|
mq, err := mqs.New(mqURL)
|
||||||
logrus.WithError(err).Fatal("Error initializing message queue.")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.mq = mq
|
||||||
}
|
}
|
||||||
return WithMQ(mq)
|
return nil
|
||||||
}
|
}
|
||||||
return noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithLogURL(logstoreURL string) ServerOption {
|
func WithLogURL(logstoreURL string) ServerOption {
|
||||||
if ldb := logstoreURL; ldb != "" {
|
return func(ctx context.Context, s *Server) error {
|
||||||
logDB, err := logs.New(logstoreURL)
|
if ldb := logstoreURL; ldb != "" {
|
||||||
if err != nil {
|
logDB, err := logs.New(ctx, logstoreURL)
|
||||||
logrus.WithError(err).Fatal("Error initializing logs store.")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.logstore = logDB
|
||||||
}
|
}
|
||||||
return WithLogstore(logDB)
|
return nil
|
||||||
}
|
}
|
||||||
return noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRunnerURL(runnerURL string) ServerOption {
|
func WithRunnerURL(runnerURL string) ServerOption {
|
||||||
if runnerURL != "" {
|
return func(ctx context.Context, s *Server) error {
|
||||||
cl, err := hybrid.NewClient(runnerURL)
|
if runnerURL != "" {
|
||||||
if err != nil {
|
cl, err := hybrid.NewClient(runnerURL)
|
||||||
logrus.WithError(err).Fatal("Error initializing runner API client.")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.agent = agent.New(agent.NewCachedDataAccess(cl))
|
||||||
}
|
}
|
||||||
return WithAgent(agent.New(agent.NewCachedDataAccess(cl)))
|
return nil
|
||||||
}
|
}
|
||||||
return noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func noop(s *Server) {}
|
|
||||||
|
|
||||||
func WithType(t ServerNodeType) ServerOption {
|
func WithType(t ServerNodeType) ServerOption {
|
||||||
return func(s *Server) { s.nodeType = t }
|
return func(ctx context.Context, s *Server) error {
|
||||||
|
s.nodeType = t
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithDatastore(ds models.Datastore) ServerOption {
|
func WithDatastore(ds models.Datastore) ServerOption {
|
||||||
return func(s *Server) { s.datastore = ds }
|
return func(ctx context.Context, s *Server) error {
|
||||||
|
s.datastore = ds
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithMQ(mq models.MessageQueue) ServerOption {
|
func WithMQ(mq models.MessageQueue) ServerOption {
|
||||||
return func(s *Server) { s.mq = mq }
|
return func(ctx context.Context, s *Server) error {
|
||||||
|
s.mq = mq
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithLogstore(ls models.LogStore) ServerOption {
|
func WithLogstore(ls models.LogStore) ServerOption {
|
||||||
return func(s *Server) { s.logstore = ls }
|
return func(ctx context.Context, s *Server) error {
|
||||||
|
s.logstore = ls
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithAgent(agent agent.Agent) ServerOption {
|
func WithAgent(agent agent.Agent) ServerOption {
|
||||||
return func(s *Server) { s.agent = agent }
|
return func(ctx context.Context, s *Server) error {
|
||||||
|
s.agent = agent
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Functions server with the opts given. For convenience, users may
|
// New creates a new Functions server with the opts given. For convenience, users may
|
||||||
// prefer to use NewFromEnv but New is more flexible if needed.
|
// prefer to use NewFromEnv but New is more flexible if needed.
|
||||||
func New(ctx context.Context, opts ...ServerOption) *Server {
|
func New(ctx context.Context, opts ...ServerOption) *Server {
|
||||||
|
log := common.Logger(ctx)
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Router: gin.New(),
|
Router: gin.New(),
|
||||||
// Almost everything else is configured through opts (see NewFromEnv for ex.) or below
|
// Almost everything else is configured through opts (see NewFromEnv for ex.) or below
|
||||||
@@ -193,7 +216,10 @@ func New(ctx context.Context, opts ...ServerOption) *Server {
|
|||||||
if opt == nil {
|
if opt == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
opt(s)
|
err := opt(ctx, s)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Fatal("Error during server opt initialization.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.logstore == nil { // TODO seems weird?
|
if s.logstore == nil { // TODO seems weird?
|
||||||
@@ -205,18 +231,18 @@ func New(ctx context.Context, opts ...ServerOption) *Server {
|
|||||||
switch s.nodeType {
|
switch s.nodeType {
|
||||||
case ServerTypeAPI:
|
case ServerTypeAPI:
|
||||||
if s.agent != nil {
|
if s.agent != nil {
|
||||||
logrus.Info("shutting down agent configured for api node")
|
log.Info("shutting down agent configured for api node")
|
||||||
s.agent.Close()
|
s.agent.Close()
|
||||||
}
|
}
|
||||||
s.agent = nil
|
s.agent = nil
|
||||||
case ServerTypeRunner:
|
case ServerTypeRunner:
|
||||||
if s.agent == nil {
|
if s.agent == nil {
|
||||||
logrus.Fatal("No agent started for a runner node, add FN_RUNNER_API_URL to configuration.")
|
log.Fatal("No agent started for a runner node, add FN_RUNNER_API_URL to configuration.")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
s.nodeType = ServerTypeFull
|
s.nodeType = ServerTypeFull
|
||||||
if s.datastore == nil || s.logstore == nil || s.mq == nil {
|
if s.datastore == nil || s.logstore == nil || s.mq == nil {
|
||||||
logrus.Fatal("Full nodes must configure FN_DB_URL, FN_LOG_URL, FN_MQ_URL.")
|
log.Fatal("Full nodes must configure FN_DB_URL, FN_LOG_URL, FN_MQ_URL.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO force caller to use WithAgent option? at this point we need to use the ds/ls/mq configured after all opts are run.
|
// TODO force caller to use WithAgent option? at this point we need to use the ds/ls/mq configured after all opts are run.
|
||||||
|
|||||||
@@ -8,17 +8,19 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerOption func(*Server)
|
type ServerOption func(context.Context, *Server) error
|
||||||
|
|
||||||
func EnableShutdownEndpoint(halt context.CancelFunc) ServerOption {
|
func EnableShutdownEndpoint(ctx context.Context, halt context.CancelFunc) ServerOption {
|
||||||
return func(s *Server) {
|
return func(ctx context.Context, s *Server) error {
|
||||||
s.Router.GET("/shutdown", s.handleShutdown(halt))
|
s.Router.GET("/shutdown", s.handleShutdown(halt))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LimitRequestBody(max int64) ServerOption {
|
func LimitRequestBody(max int64) ServerOption {
|
||||||
return func(s *Server) {
|
return func(ctx context.Context, s *Server) error {
|
||||||
s.Router.Use(limitRequestBody(max))
|
s.Router.Use(limitRequestBody(max))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func getErrorResponse(t *testing.T, rec *httptest.ResponseRecorder) models.Error
|
|||||||
|
|
||||||
func prepareDB(ctx context.Context, t *testing.T) (models.Datastore, models.LogStore, func()) {
|
func prepareDB(ctx context.Context, t *testing.T) (models.Datastore, models.LogStore, func()) {
|
||||||
os.Remove(tmpDatastoreTests)
|
os.Remove(tmpDatastoreTests)
|
||||||
ds, err := datastore.New("sqlite3://" + tmpDatastoreTests)
|
ds, err := datastore.New(ctx, "sqlite3://"+tmpDatastoreTests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error when creating datastore: %s", err)
|
t.Fatalf("Error when creating datastore: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user