mirror of
https://github.com/1f349/site-hosting.git
synced 2025-01-21 06:36:33 +00:00
Protect upload calls with a mutex for each site
This commit is contained in:
parent
e0fb935aaf
commit
303e789d82
1
go.mod
1
go.mod
@ -4,6 +4,7 @@ go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/1f349/mjwt v0.4.1
|
||||
github.com/1f349/syncmap v0.0.3
|
||||
github.com/charmbracelet/log v0.4.0
|
||||
github.com/cloudflare/tableflip v1.2.3
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
|
2
go.sum
2
go.sum
@ -2,6 +2,8 @@ github.com/1f349/mjwt v0.4.1 h1:ooCroMMw2kcL5c9L3sLbdtxI0H4/QC8RfTxiloKr+4Y=
|
||||
github.com/1f349/mjwt v0.4.1/go.mod h1:qwnzokkqc7Z9YmKA1m9beI3OZL1GvGYHOQU2rOwoV1M=
|
||||
github.com/1f349/rsa-helper v0.0.2 h1:N/fLQqg5wrjIzG6G4zdwa5Xcv9/jIPutCls9YekZr9U=
|
||||
github.com/1f349/rsa-helper v0.0.2/go.mod h1:VUQ++1tYYhYrXeOmVFkQ82BegR24HQEJHl5lHbjg7yg=
|
||||
github.com/1f349/syncmap v0.0.3 h1:Xc0XJwS+OF8UrbPG/C6eLubNSVFinEZ6SEIx7WmAZ0Y=
|
||||
github.com/1f349/syncmap v0.0.3/go.mod h1:MAfbJgAHKVZgkEqxpbgmMP4yga7Ajmo/KMJLoXVCmZk=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/1f349/bluebell/database"
|
||||
"github.com/1f349/syncmap"
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/spf13/afero"
|
||||
@ -17,6 +18,7 @@ import (
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var indexBranches = []string{
|
||||
@ -82,7 +84,7 @@ type sitesQueries interface {
|
||||
}
|
||||
|
||||
func New(storage afero.Fs, db sitesQueries) *Handler {
|
||||
return &Handler{storage, db}
|
||||
return &Handler{storageFs: storage, db: db}
|
||||
}
|
||||
|
||||
const maxFileSize = 1 * humanize.GiByte
|
||||
@ -90,6 +92,7 @@ const maxFileSize = 1 * humanize.GiByte
|
||||
type Handler struct {
|
||||
storageFs afero.Fs
|
||||
db sitesQueries
|
||||
mu syncmap.Map[string, *sync.Mutex]
|
||||
}
|
||||
|
||||
func (h *Handler) Handle(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
@ -144,6 +147,19 @@ func (h *Handler) extractTarGzUpload(fileData io.Reader, site, branch string) er
|
||||
return fmt.Errorf("invalid site: %w", err)
|
||||
}
|
||||
|
||||
key := site + "@" + branch
|
||||
|
||||
// ensure upload mutex is locked
|
||||
actual, _ := h.mu.LoadOrStore(key, new(sync.Mutex))
|
||||
actual.Lock()
|
||||
defer func() {
|
||||
// The mutex is no longer used so delete it here to safe memory in a "lots of
|
||||
// sites" configuration. Delete should happen first to prevent another upload
|
||||
// reusing the mutex.
|
||||
h.mu.Delete(key)
|
||||
actual.Unlock()
|
||||
}()
|
||||
|
||||
siteBranchPath := filepath.Join(site, "@"+branch)
|
||||
siteBranchOldPath := filepath.Join(site, "old@"+branch)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user