feat(upload): extract upload subsystem + move sweep to scanner ticker (B16)
- internal/upload owns chunked-upload domain logic (fingerprint resume, part tmp+rename, assemble, session sweep) and the shared UniquePath helper used by both single-file and chunked completion paths - handlers/uploads.go is now HTTP-only: bind params, call upload.U, map sentinel errors to the unchanged status/code/message contract - B16: session sweep moved out of the UploadInit request path onto the scanner ticker via a Sweeper hook (upload.U satisfies it) - unit tests for the package without PG/Redis; contract pinned by the existing handler integration tests (all green)
This commit is contained in:
@@ -19,17 +19,23 @@ import (
|
||||
"booklib/internal/store"
|
||||
)
|
||||
|
||||
// Sweeper 是 scanner 每轮顺手调用的清理钩子;upload.U 满足它(B16)。
|
||||
type Sweeper interface {
|
||||
Sweep(ctx context.Context) error
|
||||
}
|
||||
|
||||
type Scanner struct {
|
||||
st *store.Store
|
||||
cfg *config.Config
|
||||
rdb *redispkg.R
|
||||
st *store.Store
|
||||
cfg *config.Config
|
||||
rdb *redispkg.R
|
||||
sweepers []Sweeper
|
||||
// B9-②: per-library single-flight — concurrent scan triggers for the same
|
||||
// library are merged into one execution, even without redis.
|
||||
flights sync.Map // map[int64]*sync.WaitGroup
|
||||
}
|
||||
|
||||
func New(st *store.Store, cfg *config.Config, rdb *redispkg.R) *Scanner {
|
||||
return &Scanner{st: st, cfg: cfg, rdb: rdb}
|
||||
func New(st *store.Store, cfg *config.Config, rdb *redispkg.R, sweepers ...Sweeper) *Scanner {
|
||||
return &Scanner{st: st, cfg: cfg, rdb: rdb, sweepers: sweepers}
|
||||
}
|
||||
|
||||
func (s *Scanner) Run(ctx context.Context) {
|
||||
@@ -40,6 +46,11 @@ func (s *Scanner) Run(ctx context.Context) {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-t.C:
|
||||
for _, sw := range s.sweepers { // B16: 上传会话清扫随扫描周期跑
|
||||
if err := sw.Sweep(ctx); err != nil {
|
||||
log.Printf("scan: sweep: %v", err)
|
||||
}
|
||||
}
|
||||
libs, err := s.st.ListLibraries(ctx)
|
||||
if err != nil {
|
||||
log.Printf("scan: list libraries: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user