github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/ttlcache/README.md (about)

     1  # TTLCache - an in-memory cache with item expiration
     2  
     3  fork from 40f09cf4bc54b9a74ead0a3843e650a3d387e689 on 24 Mar [github.com/jellydator/ttlcache/v3](https://github.com/jellydator/ttlcache/tree/v3)
     4  
     5  ## Features
     6  - Simple API.
     7  - Type parameters.
     8  - Item expiration and automatic deletion.
     9  - Automatic expiration time extension on each `Get` call.
    10  - `Loader` interface that is used to load/lazily initialize missing cache 
    11  items.
    12  - Subscription to cache events (insertion and eviction).
    13  - Metrics.
    14  - Configurability.
    15  
    16  ## Installation
    17  ```
    18  go get github.com/jellydator/ttlcache/v3
    19  ```
    20  
    21  ## Usage
    22  The main type of `ttlcache` is `Cache`. It represents a single 
    23  in-memory data store.
    24  
    25  To create a new instance of `ttlcache.Cache`, the `ttlcache.New()` function 
    26  should be called:
    27  ```go
    28  func main() {
    29  	cache := ttlcache.New[string, string]()
    30  }
    31  ```
    32  
    33  Note that by default, a new cache instance does not let any of its
    34  items to expire or be automatically deleted. However, this feature
    35  can be activated by passing a few additional options into the 
    36  `ttlcache.New()` function and calling the `cache.Start()` method:
    37  ```go
    38  func main() {
    39  	cache := ttlcache.New[string, string](
    40  		ttlcache.WithTTL[string, string](30 * time.Minute),
    41  	)
    42  
    43  	go cache.Start() // starts automatic expired item deletion
    44  }
    45  ```
    46  
    47  Even though the `cache.Start()` method handles expired item deletion well,
    48  there may be times when the system that uses `ttlcache` needs to determine 
    49  when to delete the expired items itself. For example, it may need to 
    50  delete them only when the resource load is at its lowest (e.g., after 
    51  midnight, when the number of users/HTTP requests drops). So, in situations 
    52  like these, instead of calling `cache.Start()`, the system could 
    53  periodically call `cache.DeleteExpired()`:
    54  ```go
    55  func main() {
    56  	cache := ttlcache.New[string, string](
    57  		ttlcache.WithTTL[string, string](30 * time.Minute),
    58  	)
    59  
    60  	for {
    61  		time.Sleep(4 * time.Hour)
    62  		cache.DeleteExpired()
    63  	}
    64  }
    65  ```
    66  
    67  The data stored in `ttlcache.Cache` can be retrieved and updated with 
    68  `Set`, `Get`, `Delete`, etc. methods:
    69  ```go
    70  func main() {
    71  	cache := ttlcache.New[string, string](
    72  		ttlcache.WithTTL[string, string](30 * time.Minute),
    73  	)
    74  
    75  	// insert data
    76  	cache.Set("first", "value1", ttlcache.DefaultTTL)
    77  	cache.Set("second", "value2", ttlcache.NoTTL)
    78  	cache.Set("third", "value3", ttlcache.DefaultTTL)
    79  
    80  	// retrieve data
    81  	item := cache.Get("first")
    82  	fmt.Println(item.Value(), item.ExpiresAt())
    83  
    84  	// delete data
    85  	cache.Delete("second")
    86  	cache.DeleteExpired()
    87  	cache.DeleteAll()
    88  }
    89  ```
    90  
    91  To subscribe to insertion and eviction events, `cache.OnInsertion()` and 
    92  `cache.OnEviction()` methods should be used:
    93  ```go
    94  func main() {
    95  	cache := ttlcache.New[string, string](
    96  		ttlcache.WithTTL[string, string](30 * time.Minute),
    97  		ttlcache.WithCapacity[string, string](300),
    98  	)
    99  
   100  	cache.OnInsertion(func(item *ttlcache.Item[string, string]) {
   101  		fmt.Println(item.Value(), item.ExpiresAt())
   102  	})
   103  	cache.OnEviction(func(reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {
   104  		if reason == ttlcache.EvictionReasonCapacityReached {
   105  			fmt.Println(item.Key(), item.Value())
   106  		}
   107  	})
   108  
   109  	cache.Set("first", "value1", ttlcache.DefaultTTL)
   110  	cache.DeleteAll()
   111  }
   112  ```
   113  
   114  To load data when the cache does not have it, a custom or
   115  existing implementation of `ttlcache.Loader` can be used:
   116  ```go
   117  func main() {
   118  	loader := ttlcache.LoaderFunc[string, string](
   119  		func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
   120  			// load from file/make an HTTP request
   121  			item := c.Set("key from file", "value from file")
   122  			return item
   123  		},
   124  	)
   125  	cache := ttlcache.New[string, string](
   126  		ttlcache.WithLoader[string, string](loader),
   127  	)
   128  
   129  	item := cache.Get("key from file")
   130  }
   131  ```