[MM-48946] Fix read after write issue when uploading data (#21868)
* Fix read after write issue when uploading data * Prefer request.CTX interface
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
68373e992b
Коммит
6fd174a95f
@@ -809,7 +809,7 @@ type AppIface interface {
|
||||
GetTopReactionsForUserSince(userID string, teamID string, opts *model.InsightsOpts) (*model.TopReactionList, *model.AppError)
|
||||
GetTopThreadsForTeamSince(c request.CTX, teamID, userID string, opts *model.InsightsOpts) (*model.TopThreadList, *model.AppError)
|
||||
GetTopThreadsForUserSince(c request.CTX, teamID, userID string, opts *model.InsightsOpts) (*model.TopThreadList, *model.AppError)
|
||||
GetUploadSession(uploadId string) (*model.UploadSession, *model.AppError)
|
||||
GetUploadSession(c request.CTX, uploadId string) (*model.UploadSession, *model.AppError)
|
||||
GetUploadSessionsForUser(userID string) ([]*model.UploadSession, *model.AppError)
|
||||
GetUser(userID string) (*model.User, *model.AppError)
|
||||
GetUserAccessToken(tokenID string, sanitize bool) (*model.UserAccessToken, *model.AppError)
|
||||
@@ -1147,7 +1147,7 @@ type AppIface interface {
|
||||
UpdateUserAuth(userID string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError)
|
||||
UpdateUserRoles(c request.CTX, userID string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError)
|
||||
UpdateUserRolesWithUser(c request.CTX, user *model.User, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError)
|
||||
UploadData(c *request.Context, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError)
|
||||
UploadData(c request.CTX, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError)
|
||||
UploadEmojiImage(c request.CTX, id string, imageData *multipart.FileHeader) *model.AppError
|
||||
UpsertDraft(c *request.Context, draft *model.Draft, connectionID string) (*model.Draft, *model.AppError)
|
||||
UpsertGroupMember(groupID string, userID string) (*model.GroupMember, *model.AppError)
|
||||
|
||||
@@ -10305,7 +10305,7 @@ func (a *OpenTracingAppLayer) GetTotalUsersStats(viewRestrictions *model.ViewUse
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) GetUploadSession(uploadId string) (*model.UploadSession, *model.AppError) {
|
||||
func (a *OpenTracingAppLayer) GetUploadSession(c request.CTX, uploadId string) (*model.UploadSession, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetUploadSession")
|
||||
|
||||
@@ -10317,7 +10317,7 @@ func (a *OpenTracingAppLayer) GetUploadSession(uploadId string) (*model.UploadSe
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0, resultVar1 := a.app.GetUploadSession(uploadId)
|
||||
resultVar0, resultVar1 := a.app.GetUploadSession(c, uploadId)
|
||||
|
||||
if resultVar1 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar1))
|
||||
@@ -18135,7 +18135,7 @@ func (a *OpenTracingAppLayer) UpdateWebConnUserActivity(session model.Session, a
|
||||
a.app.UpdateWebConnUserActivity(session, activityAt)
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) UploadData(c *request.Context, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError) {
|
||||
func (a *OpenTracingAppLayer) UploadData(c request.CTX, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.UploadData")
|
||||
|
||||
|
||||
@@ -1255,7 +1255,9 @@ func (api *PluginAPI) UploadData(us *model.UploadSession, rd io.Reader) (*model.
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetUploadSession(uploadID string) (*model.UploadSession, error) {
|
||||
fi, err := api.app.GetUploadSession(uploadID)
|
||||
// We want to fetch from master DB to avoid a potential read-after-write on the plugin side.
|
||||
api.ctx.SetContext(WithMaster(api.ctx.Context()))
|
||||
fi, err := api.app.GetUploadSession(api.ctx, uploadID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func (a *App) genFileInfoFromReader(name string, file io.ReadSeeker, size int64)
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (a *App) runPluginsHook(c *request.Context, info *model.FileInfo, file io.Reader) *model.AppError {
|
||||
func (a *App) runPluginsHook(c request.CTX, info *model.FileInfo, file io.Reader) *model.AppError {
|
||||
filePath := info.Path
|
||||
// using a pipe to avoid loading the whole file content in memory.
|
||||
r, w := io.Pipe()
|
||||
@@ -154,8 +154,8 @@ func (a *App) CreateUploadSession(c request.CTX, us *model.UploadSession) (*mode
|
||||
return us, nil
|
||||
}
|
||||
|
||||
func (a *App) GetUploadSession(uploadId string) (*model.UploadSession, *model.AppError) {
|
||||
us, err := a.Srv().Store().UploadSession().Get(uploadId)
|
||||
func (a *App) GetUploadSession(c request.CTX, uploadId string) (*model.UploadSession, *model.AppError) {
|
||||
us, err := a.Srv().Store().UploadSession().Get(c.Context(), uploadId)
|
||||
if err != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
@@ -179,7 +179,7 @@ func (a *App) GetUploadSessionsForUser(userID string) ([]*model.UploadSession, *
|
||||
return uss, nil
|
||||
}
|
||||
|
||||
func (a *App) UploadData(c *request.Context, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError) {
|
||||
func (a *App) UploadData(c request.CTX, us *model.UploadSession, rd io.Reader) (*model.FileInfo, *model.AppError) {
|
||||
// prevent more than one caller to upload data at the same time for a given upload session.
|
||||
// This is to avoid possible inconsistencies.
|
||||
a.ch.uploadLockMapMut.Lock()
|
||||
@@ -202,7 +202,8 @@ func (a *App) UploadData(c *request.Context, us *model.UploadSession, rd io.Read
|
||||
}()
|
||||
|
||||
// fetch the session from store to check for inconsistencies.
|
||||
if storedSession, err := a.GetUploadSession(us.Id); err != nil {
|
||||
c.SetContext(WithMaster(c.Context()))
|
||||
if storedSession, err := a.GetUploadSession(c, us.Id); err != nil {
|
||||
return nil, err
|
||||
} else if us.FileOffset != storedSession.FileOffset {
|
||||
return nil, model.NewAppError("UploadData", "app.upload.upload_data.concurrent.app_error",
|
||||
|
||||
Ссылка в новой задаче
Block a user