{"id":15667409,"url":"https://github.com/silas/ttlcache","last_synced_at":"2025-06-13T19:37:48.673Z","repository":{"id":61626763,"uuid":"544593398","full_name":"silas/ttlcache","owner":"silas","description":null,"archived":false,"fork":false,"pushed_at":"2023-02-10T18:53:11.000Z","size":236,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-30T04:26:41.605Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/silas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-02T21:22:59.000Z","updated_at":"2023-02-10T18:52:06.000Z","dependencies_parsed_at":"2024-06-20T15:34:58.449Z","dependency_job_id":"45b18a0e-de45-497a-9094-c6c671f5eff1","html_url":"https://github.com/silas/ttlcache","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/silas/ttlcache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/silas%2Fttlcache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/silas%2Fttlcache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/silas%2Fttlcache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/silas%2Fttlcache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/silas","download_url":"https://codeload.github.com/silas/ttlcache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/silas%2Fttlcache/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259708287,"owners_count":22899569,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T14:03:19.106Z","updated_at":"2025-06-13T19:37:48.601Z","avatar_url":"https://github.com/silas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TTLCache - an in-memory cache with item expiration\n\nThis is a friendly fork of [jellydator/ttlcache](https://github.com/jellydator/ttlcache),\nwhich adds context support and a context aware singleflight implementation.\n\n## Features\n- Simple API.\n- Type parameters.\n- Item expiration and automatic deletion.\n- Automatic expiration time extension on each `Get` call.\n- `Loader` interface that is used to load/lazily initialize missing cache\nitems.\n- Subscription to cache events (insertion and eviction).\n- Metrics.\n- Configurability.\n\n## Installation\n```\ngo get github.com/silas/ttlcache\n```\n\n## Usage\nThe main type of `ttlcache` is `Cache`. It represents a single\nin-memory data store.\n\nTo create a new instance of `ttlcache.Cache`, the `ttlcache.New()` function\nshould be called:\n```go\nfunc main() {\n\tcache := ttlcache.New[string, string]()\n}\n```\n\nNote that by default, a new cache instance does not let any of its\nitems to expire or be automatically deleted. However, this feature\ncan be activated by passing a few additional options into the\n`ttlcache.New()` function and calling the `cache.Start(ctx)` method:\n```go\nfunc main() {\n\tcache := ttlcache.New[string, string](\n\t\tttlcache.WithTTL[string, string](30 * time.Minute),\n\t)\n\n\tgo cache.Start(context.Background()) // starts automatic expired item deletion\n}\n```\n\nEven though the `cache.Start(ctx)` method handles expired item deletion well,\nthere may be times when the system that uses `ttlcache` needs to determine\nwhen to delete the expired items itself. For example, it may need to\ndelete them only when the resource load is at its lowest (e.g., after\nmidnight, when the number of users/HTTP requests drops). So, in situations\nlike these, instead of calling `cache.Start(ctx)`, the system could\nperiodically call `cache.DeleteExpired(ctx)`:\n```go\nfunc main() {\n\tcache := ttlcache.New[string, string](\n\t\tttlcache.WithTTL[string, string](30 * time.Minute),\n\t)\n\n\tfor {\n\t\ttime.Sleep(4 * time.Hour)\n\t\tcache.DeleteExpired(context.Background())\n\t}\n}\n```\n\nThe data stored in `ttlcache.Cache` can be retrieved and updated with\n`Set`, `Get`, `Delete`, etc. methods:\n```go\nfunc main() {\n\tcache := ttlcache.New[string, string](\n\t\tttlcache.WithTTL[string, string](30 * time.Minute),\n\t)\n\tctx := context.Background()\n\n\t// insert data\n\tcache.Set(ctx, \"first\", \"value1\", ttlcache.DefaultTTL)\n\tcache.Set(ctx, \"second\", \"value2\", ttlcache.NoTTL)\n\tcache.Set(ctx, \"third\", \"value3\", ttlcache.DefaultTTL)\n\n\t// retrieve data\n\titem := cache.Get(ctx, \"first\")\n\tfmt.Println(item.Value(), item.ExpiresAt())\n\n\t// delete data\n\tcache.Delete(ctx, \"second\")\n\tcache.DeleteExpired(ctx)\n\tcache.DeleteAll(ctx)\n}\n```\n\nTo subscribe to insertion and eviction events, `cache.OnInsertion()` and\n`cache.OnEviction()` methods should be used:\n```go\nfunc main() {\n\tcache := ttlcache.New[string, string](\n\t\tttlcache.WithTTL[string, string](30 * time.Minute),\n\t\tttlcache.WithCapacity[string, string](300),\n\t)\n\n\tcache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) {\n\t\tfmt.Println(item.Value(), item.ExpiresAt())\n\t})\n\tcache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {\n\t\tif reason == ttlcache.EvictionReasonCapacityReached {\n\t\t\tfmt.Println(item.Key(), item.Value())\n\t\t}\n\t})\n\n\tctx := context.Background()\n\tcache.Set(ctx, \"first\", \"value1\", ttlcache.DefaultTTL)\n\tcache.DeleteAll(ctx)\n}\n```\n\nTo load data when the cache does not have it, a custom or\nexisting implementation of `ttlcache.Loader` can be used:\n```go\nfunc main() {\n\tvar loader ttlcache.Loader[string, string] = ttlcache.LoaderFunc[string, string](\n\t\tfunc(ctx context.Context, c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {\n\t\t\t// load from file/make an HTTP request\n\t\t\titem := c.Set(ctx, \"key from file\", \"value from file\", time.Minute)\n\t\t\treturn item\n\t\t},\n\t)\n\tloader = ttlcache.SingleFlightLoader(loader)\n\tcache := ttlcache.New[string, string](\n\t\tttlcache.WithLoader[string, string](loader),\n\t)\n\n\titem := cache.Get(context.Background(), \"key from file\")\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsilas%2Fttlcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsilas%2Fttlcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsilas%2Fttlcache/lists"}