github.com/gofiber/fiber/v2@v2.47.0/middleware/cache/manager.go (about)

     1  package cache
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/gofiber/fiber/v2"
     8  	"github.com/gofiber/fiber/v2/internal/memory"
     9  )
    10  
    11  // go:generate msgp
    12  // msgp -file="manager.go" -o="manager_msgp.go" -tests=false -unexported
    13  type item struct {
    14  	body      []byte
    15  	ctype     []byte
    16  	cencoding []byte
    17  	status    int
    18  	exp       uint64
    19  	headers   map[string][]byte
    20  	// used for finding the item in an indexed heap
    21  	heapidx int
    22  }
    23  
    24  //msgp:ignore manager
    25  type manager struct {
    26  	pool    sync.Pool
    27  	memory  *memory.Storage
    28  	storage fiber.Storage
    29  }
    30  
    31  func newManager(storage fiber.Storage) *manager {
    32  	// Create new storage handler
    33  	manager := &manager{
    34  		pool: sync.Pool{
    35  			New: func() interface{} {
    36  				return new(item)
    37  			},
    38  		},
    39  	}
    40  	if storage != nil {
    41  		// Use provided storage if provided
    42  		manager.storage = storage
    43  	} else {
    44  		// Fallback to memory storage
    45  		manager.memory = memory.New()
    46  	}
    47  	return manager
    48  }
    49  
    50  // acquire returns an *entry from the sync.Pool
    51  func (m *manager) acquire() *item {
    52  	return m.pool.Get().(*item) //nolint:forcetypeassert // We store nothing else in the pool
    53  }
    54  
    55  // release and reset *entry to sync.Pool
    56  func (m *manager) release(e *item) {
    57  	// don't release item if we using memory storage
    58  	if m.storage != nil {
    59  		return
    60  	}
    61  	e.body = nil
    62  	e.ctype = nil
    63  	e.status = 0
    64  	e.exp = 0
    65  	e.headers = nil
    66  	m.pool.Put(e)
    67  }
    68  
    69  // get data from storage or memory
    70  func (m *manager) get(key string) *item {
    71  	var it *item
    72  	if m.storage != nil {
    73  		it = m.acquire()
    74  		raw, err := m.storage.Get(key)
    75  		if err != nil {
    76  			return it
    77  		}
    78  		if raw != nil {
    79  			if _, err := it.UnmarshalMsg(raw); err != nil {
    80  				return it
    81  			}
    82  		}
    83  		return it
    84  	}
    85  	if it, _ = m.memory.Get(key).(*item); it == nil { //nolint:errcheck // We store nothing else in the pool
    86  		it = m.acquire()
    87  		return it
    88  	}
    89  	return it
    90  }
    91  
    92  // get raw data from storage or memory
    93  func (m *manager) getRaw(key string) []byte {
    94  	var raw []byte
    95  	if m.storage != nil {
    96  		raw, _ = m.storage.Get(key) //nolint:errcheck // TODO: Handle error here
    97  	} else {
    98  		raw, _ = m.memory.Get(key).([]byte) //nolint:errcheck // TODO: Handle error here
    99  	}
   100  	return raw
   101  }
   102  
   103  // set data to storage or memory
   104  func (m *manager) set(key string, it *item, exp time.Duration) {
   105  	if m.storage != nil {
   106  		if raw, err := it.MarshalMsg(nil); err == nil {
   107  			_ = m.storage.Set(key, raw, exp) //nolint:errcheck // TODO: Handle error here
   108  		}
   109  		// we can release data because it's serialized to database
   110  		m.release(it)
   111  	} else {
   112  		m.memory.Set(key, it, exp)
   113  	}
   114  }
   115  
   116  // set data to storage or memory
   117  func (m *manager) setRaw(key string, raw []byte, exp time.Duration) {
   118  	if m.storage != nil {
   119  		_ = m.storage.Set(key, raw, exp) //nolint:errcheck // TODO: Handle error here
   120  	} else {
   121  		m.memory.Set(key, raw, exp)
   122  	}
   123  }
   124  
   125  // delete data from storage or memory
   126  func (m *manager) del(key string) {
   127  	if m.storage != nil {
   128  		_ = m.storage.Delete(key) //nolint:errcheck // TODO: Handle error here
   129  	} else {
   130  		m.memory.Delete(key)
   131  	}
   132  }