-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🤗 [Question]: Is there a concurrency safety issue in the Set method implementation of Minio Storage? #1142
Comments
Ping @mstgnz |
DetectContentType is not stated to be thread-safe in the Go documentation, so updating ContentType synchronously without proper synchronization can lead to unexpected behavior. In fact, Minio sets the Content Type automatically, but this is not 100% accurate. That's why we set it ourselves. |
@mstgnz Thank you for your reply. I think we should use the copy technique here. What do you think? // If two coroutines arrive here simultaneously, one is a request to upload an image and the other is a request to upload a docx file. Assuming the first Coroutine acquired the lock and changed PutObjectOptions.ContentType to Then the second Coroutine starts acquiring the lock and changes Now, regardless of when the first Coroutine is resumed, it is highly likely that the file := bytes.NewReader(val)
// If two coroutines arrive here simultaneously, one is a request to upload an image and the other is a request to upload a docx file.
// Assuming the first Coroutine acquired the lock and changed PutObjectOptions.ContentType to "image/png", but before it could proceed to the next line of code, the CPU relinquished control.
// Then the second Coroutine starts acquiring the lock and changes PutObjectOptions.ContentType to application/octet, releases the lock, and prepares to execute the next line of code.
// Now, regardless of when the first Coroutine is resumed, it is highly likely that the PutObjectOptions.ContentType used in executing the PutObject function may be incorrect.
s.mu.Lock()
s.cfg.PutObjectOptions.ContentType = http.DetectContentType(val)
s.mu.Unlock()
// put object
_, err := s.minio.PutObject(s.ctx, s.cfg.Bucket, key, file, file.Size(), s.cfg.PutObjectOptions) One approach is to expand the scope of locking, but this can significantly reduce execution efficiency: file := bytes.NewReader(val)
s.mu.Lock()
s.cfg.PutObjectOptions.ContentType = http.DetectContentType(val)
_, err := s.minio.PutObject(s.ctx, s.cfg.Bucket, key, file, file.Size(), s.cfg.PutObjectOptions)
s.mu.Unlock() The above is my limited understanding, and there may be misunderstandings. I look forward to being corrected. |
Although it is not entirely clear, minio PutObject is said to be safe for goroutines. However, a situation like the one you mentioned is theoretically possible, so we need to ensure our security ourselves. Thanks for the information. Related correction made There is a minio issue related to this situation. minio/minio-go#598 |
@gaby No, there's no more. |
Question Description
Please take a look at the code below:
Are there any concurrency safety issues here?
Here is a more complete code snippet below.
Code Snippet (optional)
Checklist:
The text was updated successfully, but these errors were encountered: