{"id":15010689,"url":"https://github.com/maxcountryman/flake","last_synced_at":"2025-04-07T17:12:42.277Z","repository":{"id":19860780,"uuid":"23124075","full_name":"maxcountryman/flake","owner":"maxcountryman","description":"Decentralized, k-ordered unique IDs in Clojure","archived":false,"fork":false,"pushed_at":"2017-08-26T03:44:51.000Z","size":69,"stargazers_count":142,"open_issues_count":1,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T14:13:59.391Z","etag":null,"topics":["clojure","flake","flake-ids","uuid","uuid-generator"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxcountryman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-19T20:06:56.000Z","updated_at":"2025-03-29T11:12:59.000Z","dependencies_parsed_at":"2022-08-02T16:00:10.136Z","dependency_job_id":null,"html_url":"https://github.com/maxcountryman/flake","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxcountryman%2Fflake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxcountryman%2Fflake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxcountryman%2Fflake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxcountryman%2Fflake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxcountryman","download_url":"https://codeload.github.com/maxcountryman/flake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247694877,"owners_count":20980733,"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","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":["clojure","flake","flake-ids","uuid","uuid-generator"],"created_at":"2024-09-24T19:35:23.602Z","updated_at":"2025-04-07T17:12:42.254Z","avatar_url":"https://github.com/maxcountryman.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flake\n[![Clojars Project](https://img.shields.io/clojars/v/flake.svg)](https://clojars.org/flake)\n[![Build Status](https://travis-ci.org/maxcountryman/flake.svg?branch=master)](https://travis-ci.org/maxcountryman/flake)\n[![Dependencies Status](https://jarkeeper.com/maxcountryman/flake/status.svg)](https://jarkeeper.com/maxcountryman/flake)\n\nDecentralized, k-ordered unique ID generator.\n\nThis is a Clojure implementation of Boundary's [Erlang Flake ID service](https://github.com/boundary/flake).\n\n## Usage\n\nNew flake IDs can be generated with the `generate!` fn from flake's core\nnamespace.\n\nNote that in order to prevent generation of duplicate IDs, **`init!` must be\ncalled prior to generating IDs for the first time**.\n\nFor example:\n\n```clojure\n=\u003e (require '[flake.core :as flake])\n=\u003e (flake/init!)\n=\u003e (map flake/flake-\u003ebigint (take 3 (repeatedly flake/generate!)))\n(25978563106299135585558915252224N\n 25978563106299135585558915252225N\n 25978563106299135585558915252226N)\n```\n\nHere we have generated three BigIntegers which are flake IDs. Note how they are\nordered.\n\nIt may be desirable to encode these IDs in a shorter representation, such as\nBase62. The utils namespace provides an encoder:\n\n```clojure\n=\u003e (require '[flake.utils :as utils])\n=\u003e (-\u003e\u003e (repeatedly flake/generate!)\n        first\n        flake/flake-\u003ebigint\n        utils/base62-encode)\n\"8mwFA958SJ2CZVu9nk\"\n```\n\nA flake's middle-most bits are derived from a hardware address, e.g. MAC. If\nthis is not desirable or the caller wishes to have more granular control over\nwhich bits are used here, a custom `worker-id` may be provided:\n\n```clojure\n(import '[java.security SecureRandom])\n\n(defn rand-bytes\n  \"Return `n` random bytes in an array.\"\n  [n]\n  (let [bs (byte-array n)]\n    (.nextBytes (SecureRandom.) bs)\n    bs))\n\n(def worker-id (rand-bytes 6))\n\n(first (repeatedly (partial flake/generate! worker-id)))\n```\n\nThe above specifies a random array of bytes to be used as the worker-id.\n\n# Specification\n\nFlakes are byte sequences composed of 128 bits. These sequences are structured\nsuch that the first 64 bits are a timestamp, i.e. the time since an epoch in\nmilliseconds, the next 48 bits are a unique, machine-specific bitset, normally\nthe MAC, and finally the remaining 16 bits are a monotonically increasing\nshort.\n\nA diagram of the flake byte structure:\n\n    [timestamp:64][MAC:48][sequence:16]\n\n# Exceptions\n\nExceptions may occur if a single machine generates more than 65,535 flakes\nwithin a millisecond. That puts the upper-bound on flake generation per machine\nat ~65 million flakes per second. If this limit is reached a\n`IllegalArgumentException` will be raised.\n\nAdditionally flake makes an effort to detect drift in system time and will\nraise `IllegalStateException` if time appears to be flowing in the wrong\ndirection. Note that `init!` must be used for this to work properly!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxcountryman%2Fflake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxcountryman%2Fflake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxcountryman%2Fflake/lists"}