{"id":15289158,"url":"https://github.com/zio/zio-cache","last_synced_at":"2025-04-07T06:04:08.579Z","repository":{"id":36962256,"uuid":"285700517","full_name":"zio/zio-cache","owner":"zio","description":"A ZIO native cache with a simple and compositional interface","archived":false,"fork":false,"pushed_at":"2025-02-27T12:03:24.000Z","size":1630,"stargazers_count":85,"open_issues_count":16,"forks_count":38,"subscribers_count":10,"default_branch":"series/2.x","last_synced_at":"2025-03-31T05:02:09.315Z","etag":null,"topics":["asynchronicity","asynchronous-programming","asyncronous","cache","concurrency","concurrent","concurrent-data-structure","concurrent-programming","effects","functional-programming","scala","zio"],"latest_commit_sha":null,"homepage":"https://zio.dev/zio-cache","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zio.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-07T00:36:13.000Z","updated_at":"2025-02-27T07:12:01.000Z","dependencies_parsed_at":"2024-11-04T03:30:41.214Z","dependency_job_id":null,"html_url":"https://github.com/zio/zio-cache","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zio%2Fzio-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zio%2Fzio-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zio%2Fzio-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zio%2Fzio-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zio","download_url":"https://codeload.github.com/zio/zio-cache/tar.gz/refs/heads/series/2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601447,"owners_count":20964864,"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":["asynchronicity","asynchronous-programming","asyncronous","cache","concurrency","concurrent","concurrent-data-structure","concurrent-programming","effects","functional-programming","scala","zio"],"created_at":"2024-09-30T15:59:27.203Z","updated_at":"2025-04-07T06:04:08.559Z","avatar_url":"https://github.com/zio.png","language":"Scala","readme":"[//]: # (This file was autogenerated using `zio-sbt-website` plugin via `sbt generateReadme` command.)\n[//]: # (So please do not edit it manually. Instead, change \"docs/index.md\" file or sbt setting keys)\n[//]: # (e.g. \"readmeDocumentation\" and \"readmeSupport\".)\n\n# ZIO Cache\n\nZIO Cache is a library that makes it easy to optimize the performance of our application by caching values.\n\n[![Development](https://img.shields.io/badge/Project%20Stage-Development-green.svg)](https://github.com/zio/zio/wiki/Project-Stages) ![CI Badge](https://github.com/zio/zio-cache/workflows/CI/badge.svg) [![Sonatype Releases](https://img.shields.io/nexus/r/https/oss.sonatype.org/dev.zio/zio-cache_2.13.svg?label=Sonatype%20Release)](https://oss.sonatype.org/content/repositories/releases/dev/zio/zio-cache_2.13/) [![Sonatype Snapshots](https://img.shields.io/nexus/s/https/oss.sonatype.org/dev.zio/zio-cache_2.13.svg?label=Sonatype%20Snapshot)](https://oss.sonatype.org/content/repositories/snapshots/dev/zio/zio-cache_2.13/) [![javadoc](https://javadoc.io/badge2/dev.zio/zio-cache-docs_2.13/javadoc.svg)](https://javadoc.io/doc/dev.zio/zio-cache-docs_2.13) [![ZIO Cache](https://img.shields.io/github/stars/zio/zio-cache?style=social)](https://github.com/zio/zio-cache)\n\n## Introduction\n\nSometimes we may call or receive requests to do overlapping work. Assume we are writing a service that is going to handle all incoming requests. We don't want to handle duplicate requests. Using ZIO Cache we can make our application to be more **performant** by preventing duplicated works.\n\nSome key features of ZIO Cache:\n\n- **Compositionality** — If we want our applications to be **compositional**, different parts of our application may do overlapping work. ZIO Cache helps us to stay benefit from compositionality while using caching.\n\n- **Unification of Synchronous and Asynchronous Caches** — Compositional definition of cache in terms of _lookup function_ unifies synchronous and asynchronous caches. So the lookup function can compute value either synchronously or asynchronously.\n\n- **Deep ZIO Integration** — ZIO Cache is a ZIO native solution. So without losing the power of ZIO it includes support for _concurrent lookups_, _failure_, and _interruption_.\n\n- **Caching Policy** — Using caching policy, the ZIO Cache can determine when values should/may be removed from the cache. So, if we want to build something more complex and custom we have a lot of flexibility. The caching policy has two parts and together they define a whole caching policy:\n\n    - **Priority (Optional Removal)** — When we are running out of space, it defines the order that the existing values **might** be removed from the cache to make more space.\n\n    - **Evict (Mandatory Removal)** — Regardless of space when we **must** remove existing values because they are no longer valid anymore. They might be invalid because they do not satisfy business requirements (e.g., maybe it's too old). This is a function that determines whether an entry is valid based on the entry and the current time.\n\n- **Composition Caching Policy** — We can define much more complicated caching policies out of much simpler ones.\n\n- **Cache/Entry Statistics** — ZIO Cache maintains some good statistic metrics, such as entries, memory size, hits, misses, loads, evictions, and total load time. So we can look at how our cache is doing and decide where we should change our caching policy to improve caching metrics.\n\n## How to Define a Cache?\n\nA cache is defined in terms of a lookup function that describes how to compute the value associated with a key if a value is not already in the cache.\n\n```scala\nimport zio._\n\ntrait Lookup[-Key, -Environment, +Error, +Value] {\n  def lookup(key: Key): ZIO[Environment, Error, Value]\n}\n```\n\nThe lookup function takes a key of type `Key` and returns a `ZIO` effect that requires an environment of type `Environment` and can fail with an error of type `Error` or succeed with a value of type `Value`. Because the lookup function returns a `ZIO` effect it can describe both synchronous and asynchronous workflows.\n\nWe construct a cache using a lookup function as well as a maximum size and a time to live.\n\n```scala\ntrait Cache[-Key, +Error, +Value] {\n  def get(k: Key): IO[Error, Value]\n}\n\nobject Cache {\n\n  def make[Key, Environment, Error, Value](\n    capacity: Int,\n    timeToLive: Duration,\n    lookup: Lookup[Key, Environment, Error, Value]\n  ): ZIO[Environment, Nothing, Cache[Key, Error, Value]] =\n    ???\n}\n```\n\nOnce we have created a cache the most idiomatic way to work with it is the `get` operator. The `get` operator will return the current value in the cache if it exists or else compute a new value, put it in the cache, and return it.\n\nIf multiple concurrent processes get the value at the same time the value will only be computed once, with all of the other processes receiving the computed value as soon as it is available. All of this will be done using ZIO's fiber based concurrency model without ever blocking any underlying operating system threads.\n\n## Installation\n\nIn order to use this library, we need to add the following line in our `build.sbt` file:\n\n```scala\nlibraryDependencies += \"dev.zio\" %% \"zio-cache\" % \"0.2.3\"\n```\n\n## Example\n\nIn this example, we are calling `timeConsumingEffect` three times in parallel with the same key. The ZIO Cache runs this effect only once. So the concurrent lookups will suspend until the value being computed is available:\n\n```scala\nimport zio._\nimport zio.cache.{Cache, Lookup}\n\nobject ZIOCacheExample extends ZIOAppDefault {\n  def timeConsumingEffect(key: String) =\n    ZIO.sleep(5.seconds).as(key.hashCode)\n\n  def run =\n    for {\n      cache \u003c- Cache.make(\n        capacity = 100,\n        timeToLive = Duration.Infinity,\n        lookup = Lookup(timeConsumingEffect)\n      )\n      result \u003c- cache\n        .get(\"key1\")\n        .zipPar(cache.get(\"key1\"))\n        .zipPar(cache.get(\"key1\"))\n      _ \u003c- ZIO.debug(\n        s\"Result of parallel execution of three effects with the same key: $result\"\n      )\n\n      hits \u003c- cache.cacheStats.map(_.hits)\n      misses \u003c- cache.cacheStats.map(_.misses)\n      _ \u003c- ZIO.debug(s\"Number of cache hits: $hits\")\n      _ \u003c- ZIO.debug(s\"Number of cache misses: $misses\")\n    } yield ()\n\n}\n```\n\nThe output of this program should be as follows:\n\n```\nResult of parallel execution three effects with the same key: ((3288498,3288498),3288498)\nNumber of cache hits: 2\nNumber of cache misses: 1\n```\n\n## Resources\n\n- [Compositional Caching](https://www.youtube.com/watch?v=iFeTUhYpPLs) by Adam Fraser (December 2020) — In this talk, Adam will introduce ZIO Cache, a new library in the ZIO ecosystem that provides a drop-in caching solution for ZIO applications. We will see how ZIO’s support for asynchrony and concurrent lets us implement a cache in terms of a single lookup function and how we get many other things such as typed errors and compositional caching policies for free. See how easy it can be to add caching to your ZIO application!\n\n## Documentation\n\nLearn more on the [ZIO Cache homepage](https://zio.dev/zio-cache)!\n\n## Contributing\n\nFor the general guidelines, see ZIO [contributor's guide](https://zio.dev/contributor-guidelines).\n\n## Code of Conduct\n\nSee the [Code of Conduct](https://zio.dev/code-of-conduct)\n\n## Support\n\nCome chat with us on [![Badge-Discord]][Link-Discord].\n\n[Badge-Discord]: https://img.shields.io/discord/629491597070827530?logo=discord \"chat on discord\"\n[Link-Discord]: https://discord.gg/2ccFBr4 \"Discord\"\n\n## License\n\n[License](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzio%2Fzio-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzio%2Fzio-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzio%2Fzio-cache/lists"}