{"id":15180567,"url":"https://github.com/vertx-howtos/async-loading-cache-caffeine-howto","last_synced_at":"2026-01-31T17:03:03.404Z","repository":{"id":43033739,"uuid":"472377160","full_name":"vertx-howtos/async-loading-cache-caffeine-howto","owner":"vertx-howtos","description":"Using Caffeine's AsyncLoadingCache in a Vert.x application","archived":false,"fork":false,"pushed_at":"2024-12-02T16:19:41.000Z","size":3634,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-13T04:41:39.290Z","etag":null,"topics":["caffeine-cache","howto","vertx"],"latest_commit_sha":null,"homepage":"","language":"Java","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/vertx-howtos.png","metadata":{"files":{"readme":"README.adoc","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-03-21T14:35:33.000Z","updated_at":"2024-12-02T16:19:47.000Z","dependencies_parsed_at":"2025-01-07T03:16:33.463Z","dependency_job_id":null,"html_url":"https://github.com/vertx-howtos/async-loading-cache-caffeine-howto","commit_stats":{"total_commits":8,"total_committers":2,"mean_commits":4.0,"dds":0.125,"last_synced_commit":"1bc7240a641cb6111e7e662303903eca23c2060b"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":"vertx-howtos/howto-template","purl":"pkg:github/vertx-howtos/async-loading-cache-caffeine-howto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vertx-howtos%2Fasync-loading-cache-caffeine-howto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vertx-howtos%2Fasync-loading-cache-caffeine-howto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vertx-howtos%2Fasync-loading-cache-caffeine-howto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vertx-howtos%2Fasync-loading-cache-caffeine-howto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vertx-howtos","download_url":"https://codeload.github.com/vertx-howtos/async-loading-cache-caffeine-howto/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vertx-howtos%2Fasync-loading-cache-caffeine-howto/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28948356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T14:26:55.697Z","status":"ssl_error","status_checked_at":"2026-01-31T14:26:52.545Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["caffeine-cache","howto","vertx"],"created_at":"2024-09-27T16:22:56.303Z","updated_at":"2026-01-31T17:03:03.371Z","avatar_url":"https://github.com/vertx-howtos.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"= Using Caffeine's `AsyncLoadingCache` in a Vert.x application\n:page-permalink: /\n:page-github: vertx-howtos/async-loading-cache-caffeine-howto\n\nThis document will show you how to use Caffeine's `AsyncLoadingCache` in a Vert.x application.\n\n== What you will build\n\nYou will build an application that rotates images in a web page.\n\nThe images will be downloaded by the server from a public API exposed at https://http.cat.\n\nEach image represents an HTTP status code as a 🐱.\n\nReady?\n\nimage::https://http.cat/100[width=600]\n\nNOTE: Images created by Tomomi Imura (https://twitter.com/girlie_mac[@girlie_mac])\n\n== What you need\n\n* A text editor or IDE,\n* Java 11 or higher,\n* Maven or Gradle.\n\n== Create a project\n\nThe code of this project contains Maven and Gradle build files that are functionally equivalent.\n\n=== Using Maven\n\nHere is the content of the `pom.xml` file you should be using:\n\n[source,xml,role=\"collapsed\"]\n.Maven `pom.xml`\n----\ninclude::pom.xml[]\n----\n\n=== Using Gradle\n\nAssuming you use Gradle with the Kotlin DSL, here is what your `build.gradle.kts` file should look like:\n\n[source,kotlin,role=\"collapsed\"]\n.Gradle `build.gradle.kts`\n----\ninclude::build.gradle.kts[]\n----\n\n== Web Page Implementation\n\nThe `index.html` web page consists mainly of:\n\n. an `\u003cimg\u003e` tag in the body, and\n. a script that, after the page is loaded, changes the `src` attribute of the image.\n\n[source,html]\n.index.html\n----\ninclude::src/main/resources/webroot/index.html[]\n----\n\u003c1\u003e `img` tag in the body with `id` set to `cat-img`\n\u003c2\u003e run the script function when the page is loaded\n\u003c3\u003e define some HTTP status codes\n\u003c4\u003e schedule a function to execute periodically at a fixed-delay of 250 milliseconds\n\u003c5\u003e retrieve the `img` element from the DOM using its id\n\u003c6\u003e update the `src` attribute using an HTTP status code chosen randomly\n\n== Server Implementation\n\nWe will need a Vert.x Web Client instance to fetch images:\n\n[source,java]\n.Web Client setup\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=web-client]\n----\n\nWe will also need a cache because we do not want to overload the backend API:\n\n[source,java]\n.Caffeine setup\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=caffeine]\n----\n\u003c1\u003e create a cache builder\n\u003c2\u003e configure the cache to expire items after 1 minute\n\u003c3\u003e enable statistics recording\n\u003c4\u003e define an executor which invokes tasks on the verticle context\n\u003c5\u003e create an asynchronous loader, which much return a `CompletableFuture`, using the cache executor\n\u003c6\u003e fetch the cat image\n\u003c7\u003e convert the Vert.x `Future` to a `CompletionStage`\n\u003c8\u003e log cache statistics periodically\n\n[NOTE]\n====\nThe executor definition and the complex loader implementation are not strictly needed here.\n\nIndeed, we will deploy a single verticle instance, bind the cache to a field and always invoke its methods from the event-loop.\nIf that is your use-case, you may simplify the setup to:\n\n[source,java]\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=caffeine-simple]\n----\n\nIf, however, you plan to deploy several instances of the verticle and to share the cache between them, stick to the previous implementation.\nIt guarantees that the asynchronous loader is always invoked on the right context.\n====\n\nFetching the cat image consists in sending the request to the backend using the corresponding HTTP status code as URI:\n\n[source,java]\n.Fetching the image\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=fetch]\n----\n\nUsing Vert.x Web, creating the HTTP server for our API and static file is pretty straightforward:\n\n[source,java]\n.Server setup\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=server]\n----\n\nHere is how we will implement image request handling:\n\n[source,java]\n.Handling image requests\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=handle-request]\n----\n\u003c1\u003e retrieve the specified code from the request path\n\u003c2\u003e invoke Caffeine (the image will be loaded from the backend transparently, if needed)\n\u003c3\u003e convert the `CompletableFuture` returned by Caffeine to a Vert.x `Future`\n\u003c4\u003e on completion, send the image bytes (or the failure) to the client\n\u003c5\u003e instruct the browser to disable caching of the image (otherwise, it would query our server only once for a given code!)\n\n== Running the application\n\nThe `CatsVerticle` needs a `main` method:\n\n[source,java]\n.Main method\n----\ninclude::src/main/java/io/vertx/howtos/caffeine/CatsVerticle.java[tag=main]\n----\n\u003c1\u003e Create a Vert.x instance\n\u003c2\u003e Deploy `CatsVerticle`\n\nYou can run the application from:\n\n. your IDE, by running the `main` method from the `CatsVerticle` class, or\n. with Maven: `mvn compile exec:java`, or\n. with Gradle: `./gradlew run` (Linux, macOS) or `gradlew run` (Windows).\n\nBrowse to http://localhost:8080.\n\nYou should see the cat images rotating in the web page:\n\nimage::cats.gif[width=600]\n\nAfter some time, inspect the program output.\nYou should read something like:\n\n----\nMar 22, 2022 3:45:17 PM io.vertx.howtos.caffeine.CatsVerticle lambda$start$4\nINFO: Stats: CacheStats{hitCount=52, missCount=28, loadSuccessCount=28, loadFailureCount=0, totalLoadTime=2514949257, evictionCount=0, evictionWeight=0}\nMar 22, 2022 3:45:37 PM io.vertx.howtos.caffeine.CatsVerticle lambda$start$4\nINFO: Stats: CacheStats{hitCount=132, missCount=28, loadSuccessCount=28, loadFailureCount=0, totalLoadTime=2514949257, evictionCount=0, evictionWeight=0}\nMar 22, 2022 3:45:57 PM io.vertx.howtos.caffeine.CatsVerticle lambda$start$4\nINFO: Stats: CacheStats{hitCount=212, missCount=28, loadSuccessCount=28, loadFailureCount=0, totalLoadTime=2514949257, evictionCount=0, evictionWeight=0}\nMar 22, 2022 3:46:17 PM io.vertx.howtos.caffeine.CatsVerticle lambda$start$4\nINFO: Stats: CacheStats{hitCount=267, missCount=53, loadSuccessCount=52, loadFailureCount=0, totalLoadTime=3337599348, evictionCount=28, evictionWeight=28}\nMar 22, 2022 3:46:37 PM io.vertx.howtos.caffeine.CatsVerticle lambda$start$4\nINFO: Stats: CacheStats{hitCount=344, missCount=56, loadSuccessCount=56, loadFailureCount=0, totalLoadTime=3480880213, evictionCount=28, evictionWeight=28}\n----\n\nNotice the changes in `hitCount`, `missCount`, or `evictionCount`.\n\n== Summary\n\nThis document covered:\n\n. the Vert.x web client for making HTTP requests,\n. the Vert.x web server and router,\n. the integration of Caffeine's asynchronous loading cache in a Vert.x application,\n. Vert.x periodic tasks.\n\n== See also\n\n- https://vertx.io/docs/vertx-core/java/[The Vert.x core APIs documentation]\n- https://vertx.io/docs/vertx-web/java/[The Vert.x web documentation]\n- https://vertx.io/docs/vertx-web-client/java/[The Vert.x web client documentation]\n- https://github.com/ben-manes/caffeine/wiki/[The Caffeine project wiki]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvertx-howtos%2Fasync-loading-cache-caffeine-howto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvertx-howtos%2Fasync-loading-cache-caffeine-howto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvertx-howtos%2Fasync-loading-cache-caffeine-howto/lists"}