Files
coder/coderd/files/closer.go
Steven Masley c1b35bf2f6 chore: use database in current context for file cache (#18490)
Using the db.Store when in a TX causes a deadlock for dbmem.
In production, this can cause a deadlock if at the current conn pool
limit.
2025-06-23 11:58:52 -05:00

60 lines
1.1 KiB
Go

package files
import (
"context"
"sync"
"github.com/google/uuid"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database"
)
// CacheCloser is a cache wrapper used to close all acquired files.
// This is a more simple interface to use if opening multiple files at once.
type CacheCloser struct {
cache FileAcquirer
closers []func()
mu sync.Mutex
}
func NewCacheCloser(cache FileAcquirer) *CacheCloser {
return &CacheCloser{
cache: cache,
closers: make([]func(), 0),
}
}
func (c *CacheCloser) Close() {
c.mu.Lock()
defer c.mu.Unlock()
for _, doClose := range c.closers {
doClose()
}
// Prevent further acquisitions
c.cache = nil
// Remove any references
c.closers = nil
}
func (c *CacheCloser) Acquire(ctx context.Context, db database.Store, fileID uuid.UUID) (*CloseFS, error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.cache == nil {
return nil, xerrors.New("cache is closed, and cannot acquire new files")
}
f, err := c.cache.Acquire(ctx, db, fileID)
if err != nil {
return nil, err
}
c.closers = append(c.closers, f.close)
return f, nil
}