Description
Description
DataValidation is unsafe(validation missing) when used in concurrent condition such as AddDataValidation()
. And I find out that using mutex which already existed in *File object would solve this problem. Here just record some information about the bug, and I will give a pr to fix this soon.
Steps to reproduce the issue:
For example, it will happen when used AddDataValidation in concurrency, many goroutines append data validations to the same worksheet object.
Test Case:
func TestConcurrentAddDataValidation(t *testing.T) {
var (
resultFile = filepath.Join("test", "TestConcurrentAddDataValidation.xlsx")
f = NewFile()
sheet1 = "Sheet1"
dataValidationLen = 1000
)
// prepare dataValidation list
dvs := make([]*DataValidation, dataValidationLen)
for i := 0; i < dataValidationLen; i++ {
dvi := NewDataValidation(true)
dvi.Sqref = fmt.Sprintf("A%d:B%d", i+1, i+1)
dvi.SetRange(10, 20, DataValidationTypeWhole, DataValidationOperatorGreaterThan)
dvi.SetInput(fmt.Sprintf("title:%d", i+1), strconv.Itoa(i+1))
dvs[i] = dvi
}
assert.Len(t, dvs, dataValidationLen)
// simulated concurrency
var wg sync.WaitGroup
wg.Add(dataValidationLen)
for i := 0; i < dataValidationLen; i++ {
// NOTE: this will cause unexpected result because of using slice in concurrency.
go func(i int) {
f.AddDataValidation(sheet1, dvs[i])
wg.Done()
}(i)
}
wg.Wait()
// Test the length of data validation after concurrent
dataValidations, err := f.GetDataValidations(sheet1)
assert.NoError(t, err)
assert.Len(t, dataValidations, dataValidationLen) // here will fail, in fact, the length of dataValidations is less than dataValidationLen.
assert.NoError(t, f.SaveAs(resultFile))
}
Describe the results you received:
unexpected result, the length of dataValidations is less than dataValidationLen
Describe the results you expected:
the length of dataValidations is equal to the dataValidationLen
Output of go version
:
go version go1.20.12 linux/amd64
Excelize version or commit ID:
688808b2b4f7bb1f338991c810cd2ee6a7bb1451
Environment details (OS, Microsoft Excel™ version, physical, etc.):
debian, wps for linux.