Implement in-application mutex to reduce DB_LOCKED errors
This commit is contained in:
@@ -23,7 +23,7 @@ type RequestOptions struct {
|
||||
IgnoreWrongContentType bool
|
||||
}
|
||||
|
||||
func (app *Application) DoRequest(gectx *ginext.AppContext, g *gin.Context, fn func(ctx *AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
|
||||
func (app *Application) DoRequest(gectx *ginext.AppContext, g *gin.Context, lockmode models.TransactionLockMode, fn func(ctx *AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
|
||||
|
||||
maxRetry := scn.Conf.RequestMaxRetry
|
||||
retrySleep := scn.Conf.RequestRetrySleep
|
||||
@@ -40,6 +40,29 @@ func (app *Application) DoRequest(gectx *ginext.AppContext, g *gin.Context, fn f
|
||||
|
||||
wrap, stackTrace, panicObj := callPanicSafe(func(ctx *AppContext, finishSuccess func(r ginext.HTTPResponse) ginext.HTTPResponse) ginext.HTTPResponse {
|
||||
|
||||
dl, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
dl = time.Now().Add(time.Second * 5)
|
||||
}
|
||||
|
||||
if lockmode == models.TLockRead {
|
||||
|
||||
islock := app.MainDatabaseLock.RTryLockWithTimeout(dl.Sub(time.Now()))
|
||||
if !islock {
|
||||
return ginresp.APIError(g, 500, apierr.INTERNAL_EXCEPTION, "Failed to lock {MainDatabaseLock} [ro]", nil)
|
||||
}
|
||||
defer app.MainDatabaseLock.RUnlock()
|
||||
|
||||
} else if lockmode == models.TLockReadWrite {
|
||||
|
||||
islock := app.MainDatabaseLock.TryLockWithTimeout(dl.Sub(time.Now()))
|
||||
if !islock {
|
||||
return ginresp.APIError(g, 500, apierr.INTERNAL_EXCEPTION, "Failed to lock {MainDatabaseLock} [rw]", nil)
|
||||
}
|
||||
defer app.MainDatabaseLock.Unlock()
|
||||
|
||||
}
|
||||
|
||||
authheader := g.GetHeader("Authorization")
|
||||
|
||||
perm, err := app.getPermissions(actx, authheader)
|
||||
|
||||
Reference in New Issue
Block a user