{"id":44333581,"url":"https://github.com/unmeshjoshi/replicate","last_synced_at":"2026-02-11T10:36:58.596Z","repository":{"id":61653023,"uuid":"517637942","full_name":"unmeshjoshi/replicate","owner":"unmeshjoshi","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-08T07:44:32.000Z","size":1988,"stargazers_count":127,"open_issues_count":4,"forks_count":50,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-10-08T09:25:55.342Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/unmeshjoshi.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-07-25T11:30:47.000Z","updated_at":"2025-10-08T07:44:36.000Z","dependencies_parsed_at":"2023-01-20T17:16:01.027Z","dependency_job_id":"e1cacab1-0c63-41d8-8d47-31a82b4e406a","html_url":"https://github.com/unmeshjoshi/replicate","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/unmeshjoshi/replicate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unmeshjoshi%2Freplicate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unmeshjoshi%2Freplicate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unmeshjoshi%2Freplicate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unmeshjoshi%2Freplicate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unmeshjoshi","download_url":"https://codeload.github.com/unmeshjoshi/replicate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unmeshjoshi%2Freplicate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29332277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T06:13:03.264Z","status":"ssl_error","status_checked_at":"2026-02-11T06:12:55.843Z","response_time":97,"last_error":"SSL_read: 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":[],"created_at":"2026-02-11T10:36:58.442Z","updated_at":"2026-02-11T10:36:58.589Z","avatar_url":"https://github.com/unmeshjoshi.png","language":"Java","funding_links":[],"categories":["分布式开发"],"sub_categories":["Spring Cloud框架"],"readme":"# Replicate\n\n**Note:** This framework was built while working on the book [Patterns of Distributed Systems](https://www.informit.com/store/patterns-of-distributed-systems-9780138221980).\nI use this to teach replication techniques in the workshops that I conduct.\n\n```java\n/*                                 message1     +--------+\n                                +--------------\u003e+        |\n                                |               | node2  |\n                                |    +-message2-+        |\n                                |    |          |        |\n                             +--+----v+         +--------+\n +------+   request-response |        |\n |      |                    |node1   |\n |client| \u003c---------------\u003e  |        |\n |      |                    |        |\n +------+                    +-+----+-+\n                               |    ^            +---------+\n                               |    |            |         |\n                               |    +--message4--+ node3   |\n                               |                 |         |\n                               +--message3-------\u003e         |\n                                                 +---------+\n*/                              \n```\n## Overview\n\nThis is a basic framework for quickly building and testing replication\nalgorithms. It doesn't require any additional setup (e.g., Docker) for setting\nup a cluster and allows writing simple JUnit tests for testing replication\nmechanisms. The framework was created to learn and teach various distributed\nsystem techniques, enabling the testing of working code while exploring\ndistributed systems concepts. It provides mechanisms for establishing\nmessage-passing communication between replicas and test utilities for quickly\nforming a cluster of replicas, introducing network failures, and asserting the\nstate of the replicas. This repository also contains example code for basic\nreplication algorithms like basic Majority Quorum, Paxos, MultiPaxos and \nViewstamped Replication.\n\n\n## Basic Design\n\nThis framework allows you to implement replication algorithms quickly and write\nJUnit tests. It also offers basic ways to introduce faults like process crashes,\nnetwork disconnections, network delays, and clock skews.\n\n### Replica Class\n\nThe [Replica](src/main/java/replicate/common/Replica.java) class \nimplements essential building blocks for a networked \nservice, including:\n\n- Listening on provided IP addresses and ports.\n- Managing a single-threaded executor for request handling, Implementing the \n  [Singular Update Queue](https://martinfowler.com/articles/patterns-of-distributed-systems/singular-update-queue.html) pattern.\n- Providing a basic implementation of the [Request Waiting List](https://martinfowler.com/articles/patterns-of-distributed-systems/request-waiting-list.html) pattern.\n- Supporting serialization and deserialization of messages (currently using JSON).\n\nThese building blocks are sufficient for implementing and testing any networked service.\n\n### Writing JUnit Tests\n\nUtilities are provided to create multiple `Replica` instances. These instances, being Java objects, are easy to inspect and test. Check out [QuorumKVStoreTest](src/test/java/replicate/quorum/QuorumKVStoreTest.java) for an example of how to write tests.\nThe cluster can be formed by creating multiple instances of the Replica \nimplementations what you create. For example, a three node cluster\nwith replicas named \"athens\", \"byzantium\" and \"cyrene\" is \ncreated as following:\n\n```java\nclass QuorumKVStoreTest {\n  QuorumKVStore athens;\n  QuorumKVStore byzantium;\n  QuorumKVStore cyrene;\n  \n  @Override\n  public void setUp() throws IOException {\n    //no. servers = no. of replicas.\n    this.nodes = TestUtils.startCluster(Arrays.asList(\"athens\",\n                    \"byzantium\", \"cyrene\"),\n            (name, config, clock, clientConnectionAddress, peerConnectionAddress, peerAddresses) -\u003e new QuorumKVStore(name, config, clock, clientConnectionAddress, peerConnectionAddress, peerAddresses));\n\n    athens = nodes.get(\"athens\");\n    byzantium = nodes.get(\"byzantium\");\n    cyrene = nodes.get(\"cyrene\");\n  }\n}\n```\n\n### Introducing Failures\n\nThe `Replica` class allows you to introduce network failures to other nodes, with utility methods for dropping or delaying messages. Examples of testing with introduced network failures can be found in [QuorumKVStoreTest](src/test/java/replicate/quorum/QuorumKVStoreTest.java).\nFor example, to drop messages from the node 'athens' to 'byzantium'\n```java\n athens.dropMessagesTo(byzantium);\n```\nThe connection can be restablished using \n```java\n athens.reconnectTo(cyrene);\n```\n\n## Available Replication Algorithms\n\nThis repository contains example replication mechanisms, including:\n\n1. [Basic Read/Write Quorum](src/main/java/replicate/quorum/QuorumKVStore.java)\n2. [Quorum Consensus](src/main/java/replicate/quorumconsensus/QuorumConsensus.java)\n3. [Single-value Paxos](src/main/java/replicate/paxos/SingleValuePaxos.java)\n4. [Paxos-based Key-Value Store](src/main/java/replicate/paxoskv/PaxosKVStore.java)\n5. [Paxos-based Replicated Log](src/main/java/replicate/paxoslog/PaxosLog.java)\n6. [MultiPaxos](src/main/java/replicate/multipaxos/MultiPaxos.java)\n7. [View Stamped Replication](src/main/java/replicate/vsr/ViewStampedReplication.java)\n\nExplore these algorithms to understand and experiment with different replication techniques.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funmeshjoshi%2Freplicate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funmeshjoshi%2Freplicate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funmeshjoshi%2Freplicate/lists"}