{"id":23545274,"url":"https://github.com/rulyotano/example-sequence-server-zookeeper","last_synced_at":"2025-09-12T03:21:07.840Z","repository":{"id":199568735,"uuid":"703214994","full_name":"rulyotano/example-sequence-server-zookeeper","owner":"rulyotano","description":"Sample repo to create sequenced servers using zookeeper","archived":false,"fork":false,"pushed_at":"2025-02-04T21:19:01.000Z","size":22,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-15T10:44:07.001Z","etag":null,"topics":["docker","dotnet","example","sequencing","test","zookeeper"],"latest_commit_sha":null,"homepage":"","language":"C#","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/rulyotano.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":"2023-10-10T20:15:51.000Z","updated_at":"2025-02-04T21:19:05.000Z","dependencies_parsed_at":"2023-10-11T01:32:21.476Z","dependency_job_id":"d1ed9641-1ecf-4cd0-ace6-c0deb89f1dc8","html_url":"https://github.com/rulyotano/example-sequence-server-zookeeper","commit_stats":null,"previous_names":["rulyotano/sample-sequence-server-zookeeper","rulyotano/example-sequence-server-zookeeper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rulyotano/example-sequence-server-zookeeper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rulyotano%2Fexample-sequence-server-zookeeper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rulyotano%2Fexample-sequence-server-zookeeper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rulyotano%2Fexample-sequence-server-zookeeper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rulyotano%2Fexample-sequence-server-zookeeper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rulyotano","download_url":"https://codeload.github.com/rulyotano/example-sequence-server-zookeeper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rulyotano%2Fexample-sequence-server-zookeeper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274747685,"owners_count":25341936,"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-09-12T02:00:09.324Z","response_time":60,"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":["docker","dotnet","example","sequencing","test","zookeeper"],"created_at":"2024-12-26T08:15:44.502Z","updated_at":"2025-09-12T03:21:07.793Z","avatar_url":"https://github.com/rulyotano.png","language":"C#","readme":"# Example Sequence Server Zookeeper\nSample repo to create sequenced servers by using ZooKeeper\n\n- [Nice Medium post that helped me to understand what ZooKeeper is](https://bikas-katwal.medium.com/zookeeper-introduction-designing-a-distributed-system-using-zookeeper-and-java-7f1b108e236e)\n- [Nice Zookeeper guide](https://www.tutorialspoint.com/zookeeper/zookeeper_quick_guide.htm)\n- [ZooKeeper Docker Image](https://hub.docker.com/_/zookeeper)\n- [ZooKeeper Dotnet Library](https://github.com/shayhatsor/zookeeper)\n\n\n## Goal\n\nThe goal of this sample project is to be able to have many servers with a unique sequence number. This challenge came to my mind after during a coding interview I was asked to design an ID generator. My approach was to use the [Tweeter Snowflake Id Algorithm](https://en.wikipedia.org/wiki/Snowflake_ID). The interviewer asked \"But how are going to assign the id to the servers, those are automatically generated\" I said, \"Well let's use something like ZooKeeper\" (but to be honest I had no idea how it works). And then they asked \"But, for example, what happens if the servers go down and then recover, the id is the same, or it is different?\"... I had no idea, I didn't know exactly how it works. So I decided to try it, after gaining a bit more knowledge about how docker works, it is nice to try it.\n\nWe have a docker-compose with 2 services. One is for ZooKeeper and the other one is for the SequenceNode API app. The code is very basic, without tests (only manual), please don't judge me because of that!\n\nWe can create many instances of SequenceNode and see what happens!!!\n\n\n## Test using Docker\n\n### First run the ZooKeeper container\n\n1. cd `./code`\n2. run `docker compose up -d zookeeper`\n\nNow we have a simple ZooKeeper instance running.\n\n### (optional) Let's test the ZooKeeper instance by doing:\n\n1. `docker container ls` or `docker ps`\n2. find the docker container ID and then connect...\n3. run `docker exec -it \u003ccontainer-id\u003e zkCli.sh` and should be inside the ZooKeeper command line as a client\n4. run `ls /` to try it\n\n### Run the docker instances of the node servers.\n\nThe first step is to build the image.\n\n1. Go to `cd ./code/SequenceNode`\n2. Run the build image command: `docker image build -t sequencenode --target prod . `\n\nThen create the containers like this:\n\n```bash\n  docker run -p 5001:80 --name sequencenode1 --network code_default -d sequencenode\n  docker run -p 5002:80 --name sequencenode2 --network code_default -d sequencenode\n  docker run -p 5003:80 --name sequencenode3 --network code_default -d sequencenode\n  docker run -p 5004:80 --name sequencenode4 --network code_default -d sequencenode\n```\n\nNOTE: this network should be created by default when making the compose up command. If it has a different name change these commands.\n\n### Test it!\n\nFeel free to open a terminal or a browser tab to test it.\n\nTo test in on a terminal just run a `curl` command:\n\n```bash\ncurl http://localhost:500x/sequence\n```\n\nTo test on a browser just go to `http://localhost:500x/swagger` or directly to `http://localhost:500x/sequence`\n\nTest:\n1. Get sequence for 1, 2 and 3\n2. Then stop 2 (`docker container stop sequencenode2`)\n3. Then get the sequence for 4 (Should get the number 2 since it is free now!)\n4. Then start 2 again (`docker container start sequencenode2`)\n5. Get the sequence for 2, it should be 4 now.\n\nIf we test stopping the zookeeper container. All sequence requests are going to fail. But if start it again, are going to work again. Just a strange behavior: in this scenario, transient znodes are not deleted, so the new sequences are going to start after the last inserted (`5` in this case).\n\n### Test it by running docker-compose up\n\n- Change the number of replicas from 1 to 4 in the `docker-compose.yml` file\n- Run `docker compose up -d`. Now all the replicas should be up. This is harder to test because there is no way to access directly from the host because we are not exposing ports.\n- First approach (connect directly to containers):\n- - Make a `docker ps` to the the container IDs and then\n- - Connect to the containers `docker exec -it ecb sh` (`ecb` is the container id)\n- - And then query the sequence id `wget -qO- http://localhost/sequence`\n- Second approach (magic one! Create another container and use the load balancer!):\n- - Just run a new container and attach it to the same network by doing `docker run -it --rm --network code_default alpine sh`\n- - And then just repeat `wget -qO- http://node/sequence` as many times as you want. You could get a different number each time. That is the magic of load balancing.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frulyotano%2Fexample-sequence-server-zookeeper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frulyotano%2Fexample-sequence-server-zookeeper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frulyotano%2Fexample-sequence-server-zookeeper/lists"}