Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd736af1

Browse files
authored
fix: handle potential DB conflict due to concurrent upload requests inpostFile (#19005)
This issue manifests when users have multiple templates which rely onthe same files, for example see:#17442---------Signed-off-by: Callum Styan <callumstyan@gmail.com>
1 parentffbfaf2 commitd736af1

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

‎coderd/files.go‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,23 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
118118
Data:data,
119119
})
120120
iferr!=nil {
121-
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
122-
Message:"Internal error saving file.",
123-
Detail:err.Error(),
124-
})
125-
return
121+
ifdatabase.IsUniqueViolation(err,database.UniqueFilesHashCreatedByKey) {
122+
// The file was uploaded by some concurrent process since the last time we checked for it, fetch it again.
123+
file,err=api.Database.GetFileByHashAndCreator(ctx, database.GetFileByHashAndCreatorParams{
124+
Hash:hash,
125+
CreatedBy:apiKey.UserID,
126+
})
127+
api.Logger.Info(ctx,"postFile handler hit UniqueViolation trying to upload file after already checking for the file existence",slog.F("hash",hash),slog.F("created_by_id",apiKey.UserID))
128+
}
129+
// At this point the first error was either not the UniqueViolation OR there's still an error even after we
130+
// attempt to fetch the file again, so we should return here.
131+
iferr!=nil {
132+
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
133+
Message:"Internal error saving file.",
134+
Detail:err.Error(),
135+
})
136+
return
137+
}
126138
}
127139

128140
httpapi.Write(ctx,rw,http.StatusCreated, codersdk.UploadResponse{

‎coderd/files_test.go‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"context"
77
"net/http"
8+
"sync"
89
"testing"
910

1011
"github.com/google/uuid"
@@ -69,6 +70,30 @@ func TestPostFiles(t *testing.T) {
6970
_,err=client.Upload(ctx,codersdk.ContentTypeTar,bytes.NewReader(data))
7071
require.NoError(t,err)
7172
})
73+
t.Run("InsertConcurrent",func(t*testing.T) {
74+
t.Parallel()
75+
client:=coderdtest.New(t,nil)
76+
_=coderdtest.CreateFirstUser(t,client)
77+
78+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
79+
defercancel()
80+
81+
varwg sync.WaitGroup
82+
varend sync.WaitGroup
83+
wg.Add(1)
84+
end.Add(3)
85+
forrange3 {
86+
gofunc() {
87+
wg.Wait()
88+
data:=make([]byte,1024)
89+
_,err:=client.Upload(ctx,codersdk.ContentTypeTar,bytes.NewReader(data))
90+
end.Done()
91+
require.NoError(t,err)
92+
}()
93+
}
94+
wg.Done()
95+
end.Wait()
96+
})
7297
}
7398

7499
funcTestDownload(t*testing.T) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp