CDN-like, middleware memory cache for Go applications with integrated shielding and Go 1.18 Generics.
package main
import (
	"context"
	"fmt"
	"time"
	"github.com/AlexSSD7/cache"
)
type Person struct {
	Name string
	Age  uint32
}
func fetchPerson(name string) (*Person, error) {
	// Heavy task here, like a DB call.
	// Shielding makes the fetch functions
	// mutually exclusive, to prevent
	// unncecessary duplicate calls
	// if there is no cache in memory.
	// For the purpose of this example though,
	// we will just return sample objects.
	switch name {
	case "John":
		return &Person{Name: "John", Age: 27}, nil
	case "Steve":
		return &Person{Name: "Steve", Age: 32}, nil
	default:
		return nil, fmt.Errorf("unknown person with name '%v'", name)
	}
}
func main() {
	// Create a new ShieldedCache instance with 5-second GC interval.
	cache := cache.NewShieldedCache[*Person](time.Second * 5)
	cacheCtx, cacheCtxCancel := context.WithCancel(context.Background())
	defer cacheCtxCancel()
	// Worker is a separate goroutine running in background.
	// It is responsible for evicting old, expired objects.
	cache.StartWorker(cacheCtx)
	// If there is "person_john" object in cache, return it. Otherwise, execute fetchPerson("John").
	ret, hit, err := cache.Fetch("person_john", time.Minute, func() (*Person, error) {
		return fetchPerson("John")
	})
	fmt.Printf("result: %+v, hit: %v, err: %v\n", ret.Data, hit, err)
	// result: &{Name:John Age:27}, hit: false, err: <nil>
	ret, hit, err = cache.Fetch("person_john", time.Minute, func() (*Person, error) {
		return fetchPerson("John")
	})
	fmt.Printf("result: %+v, hit: %v, err: %v\n", ret.Data, hit, err)
	// result: &{Name:John Age:27}, hit: true, err: <nil>
	ret, hit, err = cache.Fetch("person_steve", time.Minute, func() (*Person, error) {
		return fetchPerson("Steve")
	})
	fmt.Printf("result: %+v, hit: %v, err: %v\n", ret.Data, hit, err)
	// result: &{Name:Steve Age:32}, hit: false, err: <nil>
	ret, hit, err = cache.Fetch("person_alice", time.Minute, func() (*Person, error) {
		return fetchPerson("Alice")
	})
	fmt.Printf("result: %+v, hit: %v, err: %v\n", ret, hit, err)
	// result: <nil>, hit: false, err: unknown person with name 'Alice'
}MIT