[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 удалений

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

@@ -168,20 +168,21 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
splits := make([]*model.Post, 0)
remainingText := post.Message
base := *post
base := post.Clone()
base.Message = ""
base.Props = make(map[string]interface{})
for k, v := range post.Props {
base.SetProps(make(map[string]interface{}))
for k, v := range post.GetProps() {
if k != "attachments" {
base.Props[k] = v
base.AddProp(k, v)
}
}
if utf8.RuneCountInString(model.StringInterfaceToJson(base.Props)) > model.POST_PROPS_MAX_USER_RUNES {
if utf8.RuneCountInString(model.StringInterfaceToJson(base.GetProps())) > model.POST_PROPS_MAX_USER_RUNES {
return nil, model.NewAppError("SplitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]interface{}{"Max": model.POST_PROPS_MAX_USER_RUNES}, "", http.StatusBadRequest)
}
for utf8.RuneCountInString(remainingText) > maxPostSize {
split := base
split := base.Clone()
x := 0
for index := range remainingText {
x++
@@ -191,20 +192,20 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
break
}
}
splits = append(splits, &split)
splits = append(splits, split)
}
split := base
split := base.Clone()
split.Message = remainingText
splits = append(splits, &split)
splits = append(splits, split)
attachments, _ := post.Props["attachments"].([]*model.SlackAttachment)
attachments, _ := post.GetProp("attachments").([]*model.SlackAttachment)
for _, attachment := range attachments {
newAttachment := *attachment
for {
lastSplit := splits[len(splits)-1]
newProps := make(map[string]interface{})
for k, v := range lastSplit.Props {
for k, v := range lastSplit.GetProps() {
newProps[k] = v
}
origAttachments, _ := newProps["attachments"].([]*model.SlackAttachment)
@@ -213,13 +214,13 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
runeCount := utf8.RuneCountInString(newPropsString)
if runeCount <= model.POST_PROPS_MAX_USER_RUNES {
lastSplit.Props = newProps
lastSplit.SetProps(newProps)
break
}
if len(origAttachments) > 0 {
newSplit := base
splits = append(splits, &newSplit)
splits = append(splits, newSplit)
continue
}
@@ -236,7 +237,7 @@ func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.
break
}
}
lastSplit.Props = newProps
lastSplit.SetProps(newProps)
break
}
}