{"id":36445927,"url":"https://github.com/gasparian/logical-clocks","last_synced_at":"2026-01-11T22:43:58.258Z","repository":{"id":85460222,"uuid":"415569885","full_name":"gasparian/logical-clocks","owner":"gasparian","description":"Go implementation of several clocks types: Lamport, Vector and Hybrid Logic Clock","archived":false,"fork":false,"pushed_at":"2021-10-13T18:46:10.000Z","size":13,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-21T20:00:18.668Z","etag":null,"topics":["go","go-clock","golang","hybrid-logical-clocks","lamport-clock","logical-clocks","vector-clock"],"latest_commit_sha":null,"homepage":"","language":"Go","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/gasparian.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":"2021-10-10T11:46:15.000Z","updated_at":"2025-03-01T17:34:45.000Z","dependencies_parsed_at":"2023-03-03T08:30:49.179Z","dependency_job_id":null,"html_url":"https://github.com/gasparian/logical-clocks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gasparian/logical-clocks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gasparian%2Flogical-clocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gasparian%2Flogical-clocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gasparian%2Flogical-clocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gasparian%2Flogical-clocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gasparian","download_url":"https://codeload.github.com/gasparian/logical-clocks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gasparian%2Flogical-clocks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["go","go-clock","golang","hybrid-logical-clocks","lamport-clock","logical-clocks","vector-clock"],"created_at":"2026-01-11T22:43:57.576Z","updated_at":"2026-01-11T22:43:58.250Z","avatar_url":"https://github.com/gasparian.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![main tests](https://github.com/gasparian/logical-clocks/actions/workflows/test.yml/badge.svg?branch=main)  \n\n# logical-clocks  \nIn the distributed systems there is a problem of defining causal order of events. Usually you need that to implement MVCC or CRDTs. And you can't always rely only on physical clocks since it is very hard to achieve tight clocks synchronization in real world.  \nBut there is a very \"elegant\" solution to that: use logical clocks, where we can also rely on counting events occuring in the system.  \nSo here you will find my naive go implementation of three basic logical clocks types: [Lamport clock](https://lamport.azurewebsites.net/pubs/time-clocks.pdf), [Vector clock](https://fileadmin.cs.lth.se/cs/Personal/Amr_Ergawy/dist-algos-papers/4.pdf) and [Hybrid logical clock](https://cse.buffalo.edu/tech-reports/2014-04.pdf).  \n\n## Usage  \nRun `make init` to replace pre-commit hook into `.git` folder.  \nTo test the clocks implementations run `make test`.  \nGetting the package:  \n```\ngo get github.com/gasparian/logical-clocks\n```  \n\nThen you can start using clocks:  \n```go\nimport (\n    hlc \"github.com/gasparian/logical-clocks/hlc\"\n)\n\n// Instantiate hybrid clock with the current wall clock timestamp\nhc := hlc.NewNow(0)\n// ...handle request from other service\nreq := ...\n// Apply tick using the hybrid timestamp that came from another service\nhc.Tick(req.Time)\n// Get current time\ncurrentTime := hc.Now()\n// Compare two timestamps if needed\ncmp := hlc.Compare(currentTime, req.Time)\n// ...\n```  \n\n### API  \nAll clocks shares the same API:  \n  - `New() *SomeClock` creates a new clock object;  \n  - `clock.Now() SomeClock` returns a copy of the current state of the clock;  \n  - `clock.AddTicks(ticks int)` adds the specified number to the internal counter (thread-safe);  \n  - `clock.Tick(requestTime *SomeClock)` moves clock forward, comparing to the incoming value;  \n  - `Compare(a, b *SomeClock)` compares the current states of two clocks, returns -1 (\"happens before\"), 0 (\"concurrent\") or 1;  \n\n### References  \n - [Martin Fowler's blog](https://martinfowler.com/articles/patterns-of-distributed-systems/)  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgasparian%2Flogical-clocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgasparian%2Flogical-clocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgasparian%2Flogical-clocks/lists"}