[MM-21378] Add mutex to model.Post to guard against race conditions on Post.Props (#13884)

* Add mutex to model.Post to guard against race conditions on Post.Props

* Rename mutex

* Add GetProp() method to Post

* Fix more tests

* Fix flaky test

Benchmarks:

BenchmarkPostPropsGet_indirect
BenchmarkPostPropsGet_indirect-2     	85026746	        13.0 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_indirect-4     	90273747	        13.0 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_indirect-8     	88324293	        13.0 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_indirect-16    	91427720	        13.1 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_direct
BenchmarkPostPropsGet_direct-2       	1000000000	         0.242 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_direct-4       	1000000000	         0.241 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_direct-8       	1000000000	         0.240 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsGet_direct-16      	1000000000	         0.241 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsAdd_indirect
BenchmarkPostPropsAdd_indirect-2     	 5602224	       203 ns/op	     336 B/op	       2 allocs/op
BenchmarkPostPropsAdd_indirect-4     	 5959496	       206 ns/op	     336 B/op	       2 allocs/op
BenchmarkPostPropsAdd_indirect-8     	 5833999	       205 ns/op	     336 B/op	       2 allocs/op
BenchmarkPostPropsAdd_indirect-16    	 5802493	       225 ns/op	     336 B/op	       2 allocs/op
BenchmarkPostPropsAdd_direct
BenchmarkPostPropsAdd_direct-2       	100000000	        11.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsAdd_direct-4       	100000000	        11.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsAdd_direct-8       	100000000	        11.6 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsAdd_direct-16      	99840794	        11.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsDel_indirect
BenchmarkPostPropsDel_indirect-2     	18824002	        61.9 ns/op	      48 B/op	       1 allocs/op
BenchmarkPostPropsDel_indirect-4     	19470736	        63.8 ns/op	      48 B/op	       1 allocs/op
BenchmarkPostPropsDel_indirect-8     	17640460	        65.3 ns/op	      48 B/op	       1 allocs/op
BenchmarkPostPropsDel_indirect-16    	18692962	        65.4 ns/op	      48 B/op	       1 allocs/op
BenchmarkPostPropsDel_direct
BenchmarkPostPropsDel_direct-2       	516257440	         2.34 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsDel_direct-4       	514865216	         2.43 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsDel_direct-8       	511330477	         2.37 ns/op	       0 B/op	       0 allocs/op
BenchmarkPostPropsDel_direct-16      	499504010	         2.38 ns/op	       0 B/op	       0 allocs/op
Этот коммит содержится в:
Claudio Costa
2020-03-13 21:12:20 +01:00
коммит произвёл GitHub
родитель 9e580361c2
Коммит 1e53fe85ad
28 изменённых файлов: 430 добавлений и 195 удалений

Просмотреть файл

@@ -73,7 +73,7 @@ func (a *App) CreatePostAsUser(post *model.Post, currentSessionId string) (*mode
}
// Update the LastViewAt only if the post does not have from_webhook prop set (eg. Zapier app)
if _, ok := post.Props["from_webhook"]; !ok {
if _, ok := post.GetProps()["from_webhook"]; !ok {
if _, err := a.MarkChannelsAsViewed([]string{post.ChannelId}, post.UserId, currentSessionId); err != nil {
mlog.Error(
"Encountered error updating last viewed",
@@ -241,12 +241,12 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
}
// Temporary fix so old plugins don't clobber new fields in SlackAttachment struct, see MM-13088
if attachments, ok := post.Props["attachments"].([]*model.SlackAttachment); ok {
if attachments, ok := post.GetProp("attachments").([]*model.SlackAttachment); ok {
jsonAttachments, err := json.Marshal(attachments)
if err == nil {
attachmentsInterface := []interface{}{}
err = json.Unmarshal(jsonAttachments, &attachmentsInterface)
post.Props["attachments"] = attachmentsInterface
post.AddProp("attachments", attachmentsInterface)
}
if err != nil {
mlog.Error("Could not convert post attachments to map interface.", mlog.Err(err))
@@ -384,8 +384,8 @@ func (a *App) FillInPostProps(post *model.Post, channel *model.Channel) *model.A
if len(channelMentionsProp) > 0 {
post.AddProp("channel_mentions", channelMentionsProp)
} else if post.Props != nil {
delete(post.Props, "channel_mentions")
} else if post.GetProps() != nil {
post.DelProp("channel_mentions")
}
return nil
@@ -439,8 +439,8 @@ func (a *App) SendEphemeralPost(userId string, post *model.Post) *model.Post {
if post.CreateAt == 0 {
post.CreateAt = model.GetMillis()
}
if post.Props == nil {
post.Props = model.StringInterface{}
if post.GetProps() == nil {
post.SetProps(make(model.StringInterface))
}
post.GenerateActionIds()
@@ -457,8 +457,8 @@ func (a *App) UpdateEphemeralPost(userId string, post *model.Post) *model.Post {
post.Type = model.POST_EPHEMERAL
post.UpdateAt = model.GetMillis()
if post.Props == nil {
post.Props = model.StringInterface{}
if post.GetProps() == nil {
post.SetProps(make(model.StringInterface))
}
post.GenerateActionIds()
@@ -526,7 +526,7 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
}
newPost := &model.Post{}
*newPost = *oldPost
newPost = oldPost.Clone()
if newPost.Message != post.Message {
newPost.Message = post.Message
@@ -538,7 +538,7 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
newPost.IsPinned = post.IsPinned
newPost.HasReactions = post.HasReactions
newPost.FileIds = post.FileIds
newPost.Props = post.Props
newPost.SetProps(post.GetProps())
}
// Avoid deep-equal checks if EditAt was already modified through message change
@@ -1220,7 +1220,7 @@ func isCommentMention(user *model.User, post *model.Post, otherPosts map[string]
func isPostMention(user *model.User, post *model.Post, keywords map[string][]string, otherPosts map[string]*model.Post, mentionedByThread map[string]bool, checkForCommentMentions bool) bool {
// Prevent the user from mentioning themselves
if post.UserId == user.Id && post.Props["from_webhook"] != "true" {
if post.UserId == user.Id && post.GetProp("from_webhook") != "true" {
return false
}
@@ -1232,7 +1232,7 @@ func isPostMention(user *model.User, post *model.Post, keywords map[string][]str
// Check for mentions caused by being added to the channel
if post.Type == model.POST_ADD_TO_CHANNEL {
if addedUserId, ok := post.Props[model.POST_PROPS_ADDED_USER_ID].(string); ok && addedUserId == user.Id {
if addedUserId, ok := post.GetProp(model.POST_PROPS_ADDED_USER_ID).(string); ok && addedUserId == user.Id {
return true
}
}