{"id":33941621,"url":"https://github.com/atolab/uhlc-rs","last_synced_at":"2026-04-08T14:32:46.671Z","repository":{"id":37905122,"uuid":"281922299","full_name":"atolab/uhlc-rs","owner":"atolab","description":"A Unique Hybrid Logical Clock for Rust","archived":false,"fork":false,"pushed_at":"2025-10-03T08:04:50.000Z","size":4749,"stargazers_count":56,"open_issues_count":2,"forks_count":11,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-14T05:07:14.783Z","etag":null,"topics":["distributed","distributed-systems","hlc","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atolab.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-07-23T10:33:38.000Z","updated_at":"2025-12-04T06:38:10.000Z","dependencies_parsed_at":"2024-06-21T14:12:51.023Z","dependency_job_id":"5b434ecc-fded-432b-81b1-06ac6573b76c","html_url":"https://github.com/atolab/uhlc-rs","commit_stats":{"total_commits":55,"total_committers":9,"mean_commits":6.111111111111111,"dds":0.4727272727272728,"last_synced_commit":"68bf15965061951bb4d11db9c54acf9ba5235b00"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/atolab/uhlc-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atolab%2Fuhlc-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atolab%2Fuhlc-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atolab%2Fuhlc-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atolab%2Fuhlc-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atolab","download_url":"https://codeload.github.com/atolab/uhlc-rs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atolab%2Fuhlc-rs/sbom","scorecard":{"id":214949,"data":{"date":"2025-08-11","repo":{"name":"github.com/atolab/uhlc-rs","commit":"4df3727ba9be742e88d9610b2c93a9ab63ba01b0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.4,"checks":[{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":4,"reason":"Found 9/22 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/atolab/uhlc-rs/release.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:18"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T01:28:46.654Z","repository_id":37905122,"created_at":"2025-08-17T01:28:46.654Z","updated_at":"2025-08-17T01:28:46.654Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31559829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"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":["distributed","distributed-systems","hlc","rust"],"created_at":"2025-12-12T16:36:50.661Z","updated_at":"2026-04-08T14:32:46.652Z","avatar_url":"https://github.com/atolab.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# uhlc-rs\n\n[![build](https://github.com/atolab/uhlc-rs/workflows/build/badge.svg)](https://github.com/atolab/uhlc-rs/actions?query=workflow%3Abuild)\n[![crate](https://img.shields.io/crates/v/uhlc.svg)](https://crates.io/crates/uhlc)\n[![API](https://img.shields.io/badge/api-latest-green.svg)](https://atolab.github.io/uhlc-rs)\n\nA Unique Hybrid Logical Clock for Rust.\n\nThis library is an implementation of an [Hybrid Logical Clock (HLC)](https://cse.buffalo.edu/tech-reports/2014-04.pdf) associated to a unique identifier. Thus, it is able to generate timestamps that are unique across a distributed system, without the need of a centralized time source.\n\n## Usage\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nuhlc = \"0.8\"\n```\n\nThen in your code:\n```rust\nuse uhlc::*;\n\n// create an HLC with a random u128 and relying on SystemTime::now()\nlet hlc = HLC::default();\n\n// generate a timestamp\nlet ts = hlc.new_timestamp();\n\n// update the HLC with a timestamp incoming from another HLC\nif ! hlc.update_with_timestamp(\u0026other_ts).is_ok() {\n    println!(r#\"The incoming timestamp would make this HLC\n             to drift too much. You should refuse it!\"#);\n}\n```\n\n## What is an HLC ?\nA Hybrid Logical Clock combines a Physical Clock with a Logical Clock.\nIt generates monotonic timestamps that are close to the physical time, but with a\ncounter part in the last bits that allow to preserve the _\"happen before\"_ relationship.\n\nYou can find more detailled explanations in:\n - This blog: http://sergeiturukin.com/2017/06/26/hybrid-logical-clocks.html\n - The original paper: https://cse.buffalo.edu/tech-reports/2014-04.pdf\n\n## Why \"Unique\" ?\nIn this implementation, each HLC instance is associated with an identifier that must be\nunique accross the system (by default a random u128). Each generated timestamp, in addition\nof the hybrid time, contains the identifier of the HLC that generated it, and it\ntherefore unique across the system.\n\nSuch property allows the ordering all timestamped events in a distributed system, without\nthe need of a centralized time source or decision.\n\nNote that this ordering preserve the _\"happen before\"_ relationship only when events can\nbe correlated. I.e.:\n\n * if 2 events have the same source, no problem since they will be timestamped by the\n   same HLC that will generate 2 ordered timestamps.\n\n * if an entity receives an event with a timestamp t1, it must update its HLC with t1.\n   Thus, all consecutive generated timestamps will be greater than t1.\n\n * if 2 events have different sources that have not exchanged timestamped events before,\n   as the physical clocks on each source might not be synchronized, it may happen that\n   the HLCs generate timestamps that don't reflect the real physical ordering.\n   But in most cases this doesn't really matter since there is no a real correlation\n   between those events (one is not a consequence of the other).\n\n## Implementation details\nThe `uhlc::HLC::default()` operation generate a random u128 as identifier and uses\n`std::time::SystemTime::now()` as physical clock.  \nBut using the `uhlc::HLCBuilder` allows you to configure the `HLC` differently. Example:  \n```Rust\nlet custom_hlc = HLCBuilder::new()\n    .with_id(ID::try_from([0x01, 0x02, 0x03]).unwrap())     // use a custom identifier\n    .with_clock(my_custom_gps_clock)                        // use a custom physical clock (e.g. using GPS as time source)\n    .with_max_delta(Duration::from_secs(1))                 // use a custom maximum delta (see explanations below)\n    .build();\n\n```\n\nA `uhlc::HLC::NTP64` time is 64-bits unsigned integer as specified in\n[RFC-5909](https://tools.ietf.org/html/rfc5905#section-6).\nThe first 32-bits part is the number of second since the EPOCH of the physical clock,\nand the second 32-bits part is the fraction of second.\nIn case its generated by an HLC, the last few bits of the second part are replaced\nby the HLC logical counter. The size of this counter currently hard-coded to 4 bits\nin `uhlc::CSIZE`.  \nThis gives a theoretical time resolution of (0xF * 10^9 / 2^32) = 3.5 nanoseconds.\n\nTo avoid a \"too fast clock\" to make an HLC drift too much in the future, the\n`uhlc::HLC::update_with_timestamp(timestamp)` operation will return an error if the\nincoming timestamp exceeds the current physical time more than a delta\n(500ms by default, configurable declaring the `UHLC_MAX_DELTA_MS` environment variable).\nIn such case, it could be wise to refuse or drop the incoming event,\nsince it might not be correctly ordered with further events.\n\n## Cargo features\nThis crate provides the following Cargo features:\n\n * `std`: allows this crate to use the full `std`. Even if disabled, notice that the\n   `alloc` crate is still required;\n\n * `defmt`: allows the relevant data structures to implement the `defmt::Format` trait,\n   used instead of `std::fmt::{Debug, Display}` for logging in `no_std` environments.\n\nOnly the `std` feature is enabled by default.\n\n## Usage in `no_std` environments\nIn order to use this crate in a `no_std` environment, the `default-features = false` flag\nshould be added in the dependencies section of the `Cargo.toml` file. The main differences\nwith respect to the `std` implementation include:\n\n * environment variables do not exist in an embedded environment, hence `UHLC_MAX_DELTA_MS`\n   cannot be used to tweak at runtime the delta for the clock \"anti-drift\" mechanism. An\n   appropriate value must always be set at compile time;\n\n * usually, embedded systems do not keep track of \"real world\" time, but re-initialize their\n   hardware timers every time they boot. Hence, the physical clock that is used when calling\n   `uhlc::HLC::default()` is a dummy function that always return a zero-valued timestamp.\n   Since the HLC is responsible for ensuring that timestamps are strictly increasing in order\n   to preserve the _\"happen before\"_ relationship, this means calls to\n   `uhlc::HLC::new_timestamp()` return incremental integers;\n\n * for the same reason, parsing from and formatting to human-readable time formats is not\n   available in `no_std`;\n\n * the `std::sync::Mutex` (internally used to guarantee timestamps monotonicity) is replaced\n   by `spin::Mutex`, which is based on spinlocks instead of relying on some operating system\n   functionality;\n\n * tests (with `cargo test`) can be run only on `std` targets, but different code is compiled\n   (and hence tested) depending on the features specified.\n\n## Usages\n**uhlc** is currently used in [Eclipse zenoh](https://github.com/eclipse-zenoh/zenoh).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatolab%2Fuhlc-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatolab%2Fuhlc-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatolab%2Fuhlc-rs/lists"}