Fix TestSendParallel by using only a single DB connection
see https://github.com/mattn/go-sqlite3/issues/274 see https://github.com/mattn/go-sqlite3/issues/209 see https://stackoverflow.com/questions/32479071/sqlite3-error-database-is-locked-in-golang
This commit is contained in:
parent
e90cfe34e9
commit
00d77e508d
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
|
- diff my currently used scnsend script vs the one in the docs here
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
- in my script: use (backupname || hostname) for sendername
|
- in my script: use (backupname || hostname) for sendername
|
||||||
|
@ -13,7 +13,9 @@ func NewEngine(cfg scn.Config) *gin.Engine {
|
|||||||
engine.RedirectFixedPath = false
|
engine.RedirectFixedPath = false
|
||||||
engine.RedirectTrailingSlash = false
|
engine.RedirectTrailingSlash = false
|
||||||
|
|
||||||
|
if cfg.Cors {
|
||||||
engine.Use(CorsMiddleware())
|
engine.Use(CorsMiddleware())
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.GinDebug {
|
if cfg.GinDebug {
|
||||||
ginlogger := gin.Logger()
|
ginlogger := gin.Logger()
|
||||||
|
@ -51,6 +51,16 @@ func (j dataHTTPResponse) Write(g *gin.Context) {
|
|||||||
g.Data(j.statusCode, j.contentType, j.data)
|
g.Data(j.statusCode, j.contentType, j.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errorHTTPResponse struct {
|
||||||
|
statusCode int
|
||||||
|
data any
|
||||||
|
error error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j errorHTTPResponse) Write(g *gin.Context) {
|
||||||
|
g.JSON(j.statusCode, j.data)
|
||||||
|
}
|
||||||
|
|
||||||
func Status(sc int) HTTPResponse {
|
func Status(sc int) HTTPResponse {
|
||||||
return &emptyHTTPResponse{statusCode: sc}
|
return &emptyHTTPResponse{statusCode: sc}
|
||||||
}
|
}
|
||||||
@ -98,7 +108,7 @@ func createApiError(g *gin.Context, ident string, status int, errorid apierr.API
|
|||||||
Msg(fmt.Sprintf("[%s] %s", ident, msg))
|
Msg(fmt.Sprintf("[%s] %s", ident, msg))
|
||||||
|
|
||||||
if scn.Conf.ReturnRawErrors {
|
if scn.Conf.ReturnRawErrors {
|
||||||
return &jsonHTTPResponse{
|
return &errorHTTPResponse{
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
data: apiError{
|
data: apiError{
|
||||||
Success: false,
|
Success: false,
|
||||||
@ -108,9 +118,10 @@ func createApiError(g *gin.Context, ident string, status int, errorid apierr.API
|
|||||||
RawError: langext.Ptr(langext.Conditional(e == nil, "", fmt.Sprintf("%+v", e))),
|
RawError: langext.Ptr(langext.Conditional(e == nil, "", fmt.Sprintf("%+v", e))),
|
||||||
Trace: string(debug.Stack()),
|
Trace: string(debug.Stack()),
|
||||||
},
|
},
|
||||||
|
error: e,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return &jsonHTTPResponse{
|
return &errorHTTPResponse{
|
||||||
statusCode: status,
|
statusCode: status,
|
||||||
data: apiError{
|
data: apiError{
|
||||||
Success: false,
|
Success: false,
|
||||||
@ -118,6 +129,7 @@ func createApiError(g *gin.Context, ident string, status int, errorid apierr.API
|
|||||||
ErrorHighlight: int(highlight),
|
ErrorHighlight: int(highlight),
|
||||||
Message: msg,
|
Message: msg,
|
||||||
},
|
},
|
||||||
|
error: e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ type Config struct {
|
|||||||
DBConnMaxLifetime time.Duration `env:"SCN_DB_CONNEXTIONMAXLIFETIME"`
|
DBConnMaxLifetime time.Duration `env:"SCN_DB_CONNEXTIONMAXLIFETIME"`
|
||||||
DBConnMaxIdleTime time.Duration `env:"SCN_DB_CONNEXTIONMAXIDLETIME"`
|
DBConnMaxIdleTime time.Duration `env:"SCN_DB_CONNEXTIONMAXIDLETIME"`
|
||||||
DBCheckForeignKeys bool `env:"SCN_DB_CHECKFOREIGNKEYS"`
|
DBCheckForeignKeys bool `env:"SCN_DB_CHECKFOREIGNKEYS"`
|
||||||
|
DBSingleConn bool `env:"SCN_DB_SINGLECONNECTION"`
|
||||||
RequestTimeout time.Duration `env:"SCN_REQUEST_TIMEOUT"`
|
RequestTimeout time.Duration `env:"SCN_REQUEST_TIMEOUT"`
|
||||||
ReturnRawErrors bool `env:"SCN_ERROR_RETURN"`
|
ReturnRawErrors bool `env:"SCN_ERROR_RETURN"`
|
||||||
DummyFirebase bool `env:"SCN_DUMMY_FB"`
|
DummyFirebase bool `env:"SCN_DUMMY_FB"`
|
||||||
@ -39,6 +40,7 @@ type Config struct {
|
|||||||
GoogleAPIPrivateKey string `env:"SCN_GOOG_PRIVATEKEY"`
|
GoogleAPIPrivateKey string `env:"SCN_GOOG_PRIVATEKEY"`
|
||||||
GooglePackageName string `env:"SCN_GOOG_PACKAGENAME"`
|
GooglePackageName string `env:"SCN_GOOG_PACKAGENAME"`
|
||||||
GoogleProProductID string `env:"SCN_GOOG_PROPRODUCTID"`
|
GoogleProProductID string `env:"SCN_GOOG_PROPRODUCTID"`
|
||||||
|
Cors bool `env:"SCN_CORS"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var Conf Config
|
var Conf Config
|
||||||
@ -55,6 +57,7 @@ var configLocHost = func() Config {
|
|||||||
DBJournal: "WAL",
|
DBJournal: "WAL",
|
||||||
DBTimeout: 5 * time.Second,
|
DBTimeout: 5 * time.Second,
|
||||||
DBCheckForeignKeys: false,
|
DBCheckForeignKeys: false,
|
||||||
|
DBSingleConn: true,
|
||||||
DBMaxOpenConns: 5,
|
DBMaxOpenConns: 5,
|
||||||
DBMaxIdleConns: 5,
|
DBMaxIdleConns: 5,
|
||||||
DBConnMaxLifetime: 60 * time.Minute,
|
DBConnMaxLifetime: 60 * time.Minute,
|
||||||
@ -74,6 +77,7 @@ var configLocHost = func() Config {
|
|||||||
GoogleAPIPrivateKey: "",
|
GoogleAPIPrivateKey: "",
|
||||||
GooglePackageName: "",
|
GooglePackageName: "",
|
||||||
GoogleProProductID: "",
|
GoogleProProductID: "",
|
||||||
|
Cors: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +93,7 @@ var configLocDocker = func() Config {
|
|||||||
DBJournal: "WAL",
|
DBJournal: "WAL",
|
||||||
DBTimeout: 5 * time.Second,
|
DBTimeout: 5 * time.Second,
|
||||||
DBCheckForeignKeys: false,
|
DBCheckForeignKeys: false,
|
||||||
|
DBSingleConn: true,
|
||||||
DBMaxOpenConns: 5,
|
DBMaxOpenConns: 5,
|
||||||
DBMaxIdleConns: 5,
|
DBMaxIdleConns: 5,
|
||||||
DBConnMaxLifetime: 60 * time.Minute,
|
DBConnMaxLifetime: 60 * time.Minute,
|
||||||
@ -108,6 +113,7 @@ var configLocDocker = func() Config {
|
|||||||
GoogleAPIPrivateKey: "",
|
GoogleAPIPrivateKey: "",
|
||||||
GooglePackageName: "",
|
GooglePackageName: "",
|
||||||
GoogleProProductID: "",
|
GoogleProProductID: "",
|
||||||
|
Cors: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +129,7 @@ var configDev = func() Config {
|
|||||||
DBJournal: "WAL",
|
DBJournal: "WAL",
|
||||||
DBTimeout: 5 * time.Second,
|
DBTimeout: 5 * time.Second,
|
||||||
DBCheckForeignKeys: false,
|
DBCheckForeignKeys: false,
|
||||||
|
DBSingleConn: true,
|
||||||
DBMaxOpenConns: 5,
|
DBMaxOpenConns: 5,
|
||||||
DBMaxIdleConns: 5,
|
DBMaxIdleConns: 5,
|
||||||
DBConnMaxLifetime: 60 * time.Minute,
|
DBConnMaxLifetime: 60 * time.Minute,
|
||||||
@ -142,6 +149,7 @@ var configDev = func() Config {
|
|||||||
GoogleAPIPrivateKey: confEnv("SCN_GOOG_PRIVATEKEY"),
|
GoogleAPIPrivateKey: confEnv("SCN_GOOG_PRIVATEKEY"),
|
||||||
GooglePackageName: confEnv("SCN_GOOG_PACKAGENAME"),
|
GooglePackageName: confEnv("SCN_GOOG_PACKAGENAME"),
|
||||||
GoogleProProductID: confEnv("SCN_GOOG_PROPRODUCTID"),
|
GoogleProProductID: confEnv("SCN_GOOG_PROPRODUCTID"),
|
||||||
|
Cors: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +165,7 @@ var configStag = func() Config {
|
|||||||
DBJournal: "WAL",
|
DBJournal: "WAL",
|
||||||
DBTimeout: 5 * time.Second,
|
DBTimeout: 5 * time.Second,
|
||||||
DBCheckForeignKeys: false,
|
DBCheckForeignKeys: false,
|
||||||
|
DBSingleConn: true,
|
||||||
DBMaxOpenConns: 5,
|
DBMaxOpenConns: 5,
|
||||||
DBMaxIdleConns: 5,
|
DBMaxIdleConns: 5,
|
||||||
DBConnMaxLifetime: 60 * time.Minute,
|
DBConnMaxLifetime: 60 * time.Minute,
|
||||||
@ -176,6 +185,7 @@ var configStag = func() Config {
|
|||||||
GoogleAPIPrivateKey: confEnv("SCN_GOOG_PRIVATEKEY"),
|
GoogleAPIPrivateKey: confEnv("SCN_GOOG_PRIVATEKEY"),
|
||||||
GooglePackageName: confEnv("SCN_GOOG_PACKAGENAME"),
|
GooglePackageName: confEnv("SCN_GOOG_PACKAGENAME"),
|
||||||
GoogleProProductID: confEnv("SCN_GOOG_PROPRODUCTID"),
|
GoogleProProductID: confEnv("SCN_GOOG_PROPRODUCTID"),
|
||||||
|
Cors: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +201,7 @@ var configProd = func() Config {
|
|||||||
DBJournal: "WAL",
|
DBJournal: "WAL",
|
||||||
DBTimeout: 5 * time.Second,
|
DBTimeout: 5 * time.Second,
|
||||||
DBCheckForeignKeys: false,
|
DBCheckForeignKeys: false,
|
||||||
|
DBSingleConn: true,
|
||||||
DBMaxOpenConns: 5,
|
DBMaxOpenConns: 5,
|
||||||
DBMaxIdleConns: 5,
|
DBMaxIdleConns: 5,
|
||||||
DBConnMaxLifetime: 60 * time.Minute,
|
DBConnMaxLifetime: 60 * time.Minute,
|
||||||
@ -210,6 +221,7 @@ var configProd = func() Config {
|
|||||||
GoogleAPIPrivateKey: confEnv("SCN_SCN_GOOG_PRIVATEKEY"),
|
GoogleAPIPrivateKey: confEnv("SCN_SCN_GOOG_PRIVATEKEY"),
|
||||||
GooglePackageName: confEnv("SCN_SCN_GOOG_PACKAGENAME"),
|
GooglePackageName: confEnv("SCN_SCN_GOOG_PACKAGENAME"),
|
||||||
GoogleProProductID: confEnv("SCN_SCN_GOOG_PROPRODUCTID"),
|
GoogleProProductID: confEnv("SCN_SCN_GOOG_PROPRODUCTID"),
|
||||||
|
Cors: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,14 @@ func NewDatabase(conf server.Config) (*Database, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.DBSingleConn {
|
||||||
|
xdb.SetMaxOpenConns(1)
|
||||||
|
} else {
|
||||||
xdb.SetMaxOpenConns(5)
|
xdb.SetMaxOpenConns(5)
|
||||||
xdb.SetMaxIdleConns(5)
|
xdb.SetMaxIdleConns(5)
|
||||||
xdb.SetConnMaxLifetime(60 * time.Minute)
|
xdb.SetConnMaxLifetime(60 * time.Minute)
|
||||||
xdb.SetConnMaxIdleTime(60 * time.Minute)
|
xdb.SetConnMaxIdleTime(60 * time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
qqdb := sq.NewDB(xdb)
|
qqdb := sq.NewDB(xdb)
|
||||||
|
|
||||||
|
@ -1429,8 +1429,6 @@ func TestQuotaExceededPro(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSendParallel(t *testing.T) {
|
func TestSendParallel(t *testing.T) {
|
||||||
t.SkipNow()
|
|
||||||
|
|
||||||
_, baseUrl, stop := tt.StartSimpleWebserver(t)
|
_, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
defer stop()
|
defer stop()
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, string, func()) {
|
|||||||
RequestTimeout: 30 * time.Second,
|
RequestTimeout: 30 * time.Second,
|
||||||
ReturnRawErrors: true,
|
ReturnRawErrors: true,
|
||||||
DummyFirebase: true,
|
DummyFirebase: true,
|
||||||
|
DBSingleConn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite, err := db.NewDatabase(conf)
|
sqlite, err := db.NewDatabase(conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user