Skip to content

🧹 [Maintenance]: refactor cache handler lock management — replace goto/unlock/relock pattern #4334

Description

@pageton

Problem

The cache middleware handler uses a fragile stateful lock/unlock/relock pattern with goto statements. This makes the code difficult to reason about and easy to introduce bugs when adding new exit paths.

Affected Code

middleware/cache/cache.go:313-326:

mux.Lock()       // line 313
locked := true
unlock := func() { if locked { mux.Unlock(); locked = false } }
relock := func() { if !locked { mux.Lock(); locked = true } }

The handler uses goto continueRequest (lines 370, 412, 536) that jumps over unlock calls. While the idempotent unlock() function mitigates missed unlocks, the pattern is fragile — any future code change that adds a new exit path could easily miss an unlock or create a deadlock.

Suggested Fix

Refactor into smaller functions with clear lock scope boundaries, or use a state machine struct:

type cacheHandler struct {
    mux    sync.Mutex
    locked bool
}

func (h *cacheHandler) withLock(fn func()) {
    h.mux.Lock()
    defer h.mux.Unlock()
    fn()
}

func (h *cacheHandler) withLockDo(fn func() error) error {
    h.mux.Lock()
    defer h.mux.Unlock()
    return fn()
}

Fiber Version

v3 (latest main branch)

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions