{"id":15132499,"url":"https://github.com/sarakhild/redisson-features","last_synced_at":"2026-02-25T09:37:01.280Z","repository":{"id":257232262,"uuid":"855152844","full_name":"SaraKhild/redisson-features","owner":"SaraKhild","description":"Advanced Redisson Implementation: Caching, Distributed Collections, and More.","archived":false,"fork":false,"pushed_at":"2024-09-11T14:26:15.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T21:43:17.305Z","etag":null,"topics":["redis","redisson","spring-webflux"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SaraKhild.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-09-10T12:01:00.000Z","updated_at":"2024-09-15T09:37:35.000Z","dependencies_parsed_at":"2024-09-15T12:57:00.516Z","dependency_job_id":"22d25df2-5a09-41fb-bef9-48659300dc73","html_url":"https://github.com/SaraKhild/redisson-features","commit_stats":null,"previous_names":["sarakhild/redisson-features"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SaraKhild/redisson-features","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaraKhild%2Fredisson-features","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaraKhild%2Fredisson-features/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaraKhild%2Fredisson-features/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaraKhild%2Fredisson-features/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SaraKhild","download_url":"https://codeload.github.com/SaraKhild/redisson-features/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SaraKhild%2Fredisson-features/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272424506,"owners_count":24932894,"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","status":"online","status_checked_at":"2025-08-28T02:00:10.768Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["redis","redisson","spring-webflux"],"created_at":"2024-09-26T04:20:20.327Z","updated_at":"2025-10-28T23:06:09.738Z","avatar_url":"https://github.com/SaraKhild.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Full-Featured Redis Solution with Redisson: Caching, Message Queue, Pub/Sub, and Distributed Structures\n\n\u003cbr\u003e\n\n## Overview\nThis project demonstrates a complete implementation of \u003cstrong\u003eRedisson’s features, including advanced caching mechanisms, distributed collections, message Queue, and pub/sub messaging.\u003c/strong\u003e\nIdeal for applications requiring \u003cmark\u003erobust Redis functionalities\u003c/mark\u003e and \u003cmark\u003escalable solutions.\u003c/mark\u003e\n  \n## Usages\n-  WebFlux \n- Redisson \"Redis\"\n\n## Architecture of the Project\n\n ### 1-src folder\n   - Configuration\n   - Features\n     \n### 2-Maven pom.xml\n\u003cbr\u003e \n    \n```\n\t\u003cdependencies\u003e\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003espring-boot-starter-webflux\u003c/artifactId\u003e\n\t\t\u003c/dependency\u003e\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.redisson\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003eredisson-spring-boot-starter\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e3.17.7\u003c/version\u003e\n\t\t\u003c/dependency\u003e\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003espring-boot-starter-test\u003c/artifactId\u003e\n\t\t\t\u003cscope\u003etest\u003c/scope\u003e\n\t\t\u003c/dependency\u003e\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eio.projectreactor\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003ereactor-test\u003c/artifactId\u003e\n\t\t\t\u003cscope\u003etest\u003c/scope\u003e\n\t\t\u003c/dependency\u003e\n\t\u003c/dependencies\u003e\n ```\n\n\u003cbr\u003e\n\n###### Output :star_struck:\n\n##### :pencil2: `Initializes RMapReactive with the name \"map\" and a StringCodec for serialization. then performs two asynchronous put operations to add entries \"map1\" and \"map2\" with respective values \"First Map\" and \"Second Map\". Finally, it uses StepVerifier to validate that both put operations complete successfully.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n\t@Test\n\tpublic void testMap() {\n\n\t\tRMapReactive\u003cString, String\u003e map = this.client.getMap(\"map\", StringCodec.INSTANCE);\n\t\tMono\u003cString\u003e map1 = map.put(\"map1\", \"First Map\");\n\t\tMono\u003cString\u003e map2 = map.put(\"map2\", \"Secound Map\");\n\t\tStepVerifier.create(map1.concatWith(map2)).verifyComplete();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"260\" alt=\"map\" src=\"https://github.com/user-attachments/assets/996ceb67-05ea-47df-ae00-f7cc7ececfcb\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Initializes RLocalCachedMap named \"cacheMap\" is created with a JSON codec TypedJsonJacksonCodec for serialization of Integer keys and String values. cachedMapStrategies defines the caching strategies used. testLocalCacheMap1 will adds two entries key 1 with \"cachemap1\" and key 2 with \"cacheMap2\" to the local cached map. testLocalCacheMap2 will update a single entry key1 with \"cacheMap1\" to the local cached map.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n  LocalCachedMapOptions\u003cInteger, String\u003e cachedMapStrategies = LocalCachedMapOptions.\u003cInteger, String\u003edefaults()\n\t\t\t\t.syncStrategy(LocalCachedMapOptions.SyncStrategy.UPDATE) // you can choose None or Invalidate\n\t\t\t\t.reconnectionStrategy(LocalCachedMapOptions.ReconnectionStrategy.NONE); //  you can choose Clean\n\n  private RLocalCachedMap\u003cInteger, String\u003e cachedMap = redissonClient.getLocalCachedMap(\"cacheMap\",\tnew TypedJsonJacksonCodec(Integer.class, String.class),\tcachedMapStrategies);\n\n\t@Test\n\tpublic void testLocalCacheMap1() {\n\n\t\tthis.cachedMap.put(1, \"cachemap1\");\n\t\tthis.cachedMap.put(2, \"cacheMap2\");\n\t\tFlux.interval(Duration.ofSeconds(1))\n\t\t\t\t.doOnNext(item -\u003e System.out.println(item + \"--\u003e\" + cachedMap.get(item))).subscribe();\n\t}\n\n\t@Test\n\tpublic void testLocalCacheMap2() {\n\n\t\tthis.cachedMap.put(1, \"cacheMap1\");\n\t\tFlux.interval(Duration.ofSeconds(1))\n\t\t\t\t.doOnNext(item -\u003e System.out.println(item + \"--\u003e\" + cachedMap.get(item))).subscribe();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck: As you can see cache map reflect the updated\n\n\u003cbr\u003e\n\n\u003cimg width=\"275\" alt=\"cacheMap\" src=\"https://github.com/user-attachments/assets/1eaaecfd-35f6-423b-8b26-9f3b12944d11\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Initializes RListReactive named \"number\" is created with a LongCodec for serialization of long values. list of long numbers from 1 to 10 is created and boxed them as list collect so to send it the same time to be same order. The list.addAll(numbersList).then() operation adds all these numbers to the Redis list. The step verifier is used to ensure this operation completes successfully and verifying size.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n\t@Test\n\tpublic void testList() {\n\n\t\tRListReactive\u003cLong\u003e list = this.client.getList(\"number\", LongCodec.INSTANCE);\n\t\tList\u003cLong\u003e numbersList = LongStream.rangeClosed(1, 10)\n\t\t\t\t.boxed().collect(Collectors.toList());\n\t\t/* Another Way\n\t\t Mono\u003cVoid\u003e numbersList = Flux.range(1, 10)\n\t\t \t\t.flatMap(number -\u003e list.add(number)).then();\n\t\t */\n\n\t\tStepVerifier.create(list.addAll(numbersList).then()).verifyComplete();\n\t\tStepVerifier.create(list.size())\n\t\t\t\t.expectNext(10)\n\t\t\t\t.verifyComplete();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"331\" alt=\"list\" src=\"https://github.com/user-attachments/assets/f737a54a-b41e-47f9-b4ad-f41ad7a2b8d4\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Initializes RQueueReactive named \"number\" is created with a LongCodec for serialization of long values. The method polls items from the queue using queue.poll(), repeating the operation 3 times. Step verifier ensures that the polling operation completes successfully. Additionally, it verifies that the size of the queue is 6 after the polling operations, confirming that the expected number of elements is present.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n\t@Test\n\tpublic void testQueue() {\n\n\t\tRQueueReactive\u003cLong\u003e queue = this.client.getQueue(\"number\", LongCodec.INSTANCE);\n\t\tMono\u003cVoid\u003e poll = queue.poll().repeat(3).doOnNext(System.out::println).then();\n\t\tStepVerifier.create(poll).verifyComplete();\n\t\tStepVerifier.create(queue.size())\n\t\t\t\t.expectNext(6)\n\t\t\t\t.verifyComplete();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"330\" alt=\"queue\" src=\"https://github.com/user-attachments/assets/a6fbde37-b56b-4627-9e0f-c539d1d0f56e\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Initializes RDequeReactive named \"number\" is created with a LongCodec for serialization of long values. The method performs a pollLast() operation to remove  items from the end of the stack, repeating this operation 3 times. Step verifier ensures that the polling operation completes successfully. It also verifies that the size of the stack is 2 after the polling operations, confirming the remaining number of elements in the stack.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n\t@Test\n\tpublic void testStack() {\n\n\t\tRDequeReactive\u003cLong\u003e stack = this.client.getDeque(\"number\", LongCodec.INSTANCE);\n\t\tMono\u003cVoid\u003e poll = stack.pollLast().repeat(3).doOnNext(System.out::println).then();\n\t\tStepVerifier.create(poll).verifyComplete();\n\t\tStepVerifier.create(stack.size())\n\t\t\t\t.expectNext(2)\n\t\t\t\t.verifyComplete();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"295\" alt=\"stack\" src=\"https://github.com/user-attachments/assets/d54aa0ce-7247-4bb2-982f-99e1f6bece45\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Initializes RScoredSortedSetReactive named \"name:score\" is created with a StringCodec for serialization of string values and scores. The method adds three entries to the sorted set with associated scores: \"Sam\" with a score of 1.0, \"Mike\" with a score of 2.5, and \"Jake\" with a score of 0.5. Step verifier is used to ensure the completion of the score addition. Afterward, the sorted set entries are retrieved in a specified range from rank 0 to 1.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n@Test\n\tpublic void testSortedSet() {\n\n\t\tprivate RScoredSortedSetReactive\u003cString\u003e sortedSet = this.client.getScoredSortedSet(\"name:score\", StringCodec.INSTANCE);\n\t\tMono\u003cVoid\u003e sort = this.sortedSet.addScore(\"Sam\", 1.0).then\n\t\t(this.sortedSet.addScore(\"Mike\", 2.5))\n\t\t.then(this.sortedSet.addScore(\"jake\", 0.5)).then();\n\t\tStepVerifier.create(sort).verifyComplete();\n\t\tthis.sortedSet.entryRange(0, 1)\n\t\t\t\t.flatMapIterable(items -\u003e items)\n\t\t\t\t.map(item -\u003e item.getScore() + \":\" + item.getValue())\n\t\t\t\t.doOnNext(System.out::println)\n\t\t\t\t.subscribe();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck: As you can see Jake is priority than Sam, if you restart will be the score of Jake is priority than Sam.\n\n\u003cbr\u003e\n\n\u003cimg width=\"1109\" alt=\"sortedSet-1\" src=\"https://github.com/user-attachments/assets/1e790cff-b60c-4175-a0fe-d30c9081650c\"\u003e\n\u003cimg width=\"1129\" alt=\"sortedSet-2\" src=\"https://github.com/user-attachments/assets/7c9d5abc-6046-470b-a3a3-130cd280689b\"\u003e\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `Producer adds messages to the message queue. It generates a sequence of numbers from 1 to 20, with a delay of 500 milliseconds between each numbe. Consumer1 and consumer2 will listents to a message queue to consume messages then print it.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n  @Test\n\tpublic void testMessageQueueConsumer1() throws InterruptedException {\n\n\t\tthis.messageQueue.takeElements()\n\t\t\t\t.doOnNext(elem -\u003e System.out.println(\"Consumer 1: \" + elem))\n\t\t\t\t.doOnError(System.out::println)\n\t\t\t\t.subscribe();\n\n\t\t\t\tThread.sleep(600_000);\n\t}\n\n\t@Test\n\tpublic void testMessageQueueConsumer2() throws InterruptedException {\n\n\t\tthis.messageQueue.takeElements()\n\t\t\t\t.doOnNext(elem -\u003e System.out.println(\"Consumer 2: \" + elem))\n\t\t\t\t.doOnError(System.out::println)\n\t\t\t\t.subscribe();\n\n\t\t\t\tThread.sleep(600_000);\n\t}\n\n\t@Test\n\tpublic void testMessageQueueProducer() {\n\n\t\tMono\u003cVoid\u003e numbers = Flux.range(1, 20)\n\t\t\t\t.delayElements(Duration.ofMillis(500))\n\t\t\t\t.doOnNext(number -\u003e System.out.println(\"going to add\" + number))\n\t\t\t\t.flatMap(number -\u003e this.messageQueue.add(Long.valueOf(number)))\n\t\t\t\t.then();\n\t\tStepVerifier.create(numbers).verifyComplete();\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"1121\" alt=\"producer\" src=\"https://github.com/user-attachments/assets/42678053-b77d-41a3-8138-38ed3d477149\"\u003e\n\u003cimg width=\"1154\" alt=\"consumer-1\" src=\"https://github.com/user-attachments/assets/ff8b61ae-2c29-4f4f-ac53-b68215c47a0e\"\u003e\n\u003cimg width=\"1152\" alt=\"consumer-2\" src=\"https://github.com/user-attachments/assets/fbf01c32-52be-41ff-86a0-69953f239642\"\u003e\n\n\n---\n\n\u003cbr\u003e\n\n##### :pencil2: `PubSub1 and PubSub2 subscribes to a redis topic to receive messages of type String. It prints each received message to the console.` \n\n###### Code :computer:\n\n\u003cbr\u003e\n\n```\n\t@Test\n\tpublic void testPubSub1() throws InterruptedException {\n\t\tthis.topic.getMessages(String.class)\n\t\t\t\t.doOnNext(System.out::println)\n\t\t\t\t.doOnError(System.out::println)\n\t\t\t\t.subscribe();\n\n\t\t\t\tThread.sleep(600_000);\n\t}\n\n\t@Test\n\tpublic void testPubSub2() throws InterruptedException {\n\t\tthis.topic.getMessages(String.class)\n\t\t\t\t.doOnNext(System.out::println)\n\t\t\t\t.doOnError(System.out::println)\n\t\t\t\t.subscribe();\n\n\t\t\t\tThread.sleep(600_000);\n\t}\n```\n\n\u003cbr\u003e\n\n###### Result :star_struck:\n\n\u003cbr\u003e\n\n\u003cimg width=\"1159\" alt=\"subPub-1\" src=\"https://github.com/user-attachments/assets/723584cd-0038-4d9a-8099-bb7e31635369\"\u003e\n\u003cimg width=\"1137\" alt=\"subPub-2\" src=\"https://github.com/user-attachments/assets/8ed108fe-8c01-49b5-a150-4fd63368fa05\"\u003e\n\n\u003cbr\u003e\n\n---\n\n### Good Luck \u003cimg src=\"https://media.giphy.com/media/hvRJCLFzcasrR4ia7z/giphy.gif\" width=\"30px\"\u003e \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsarakhild%2Fredisson-features","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsarakhild%2Fredisson-features","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsarakhild%2Fredisson-features/lists"}