{"id":13507335,"url":"https://github.com/whitfin/sleeplocks","last_synced_at":"2025-04-06T03:09:37.304Z","repository":{"id":49130427,"uuid":"168248751","full_name":"whitfin/sleeplocks","owner":"whitfin","description":"BEAM friendly spinlocks for Elixir/Erlang","archived":false,"fork":false,"pushed_at":"2024-05-27T18:06:55.000Z","size":22,"stargazers_count":60,"open_issues_count":2,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-30T02:05:46.854Z","etag":null,"topics":["concurrency","concurrent-data-structure","parallel-programming"],"latest_commit_sha":null,"homepage":"","language":"Erlang","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/whitfin.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":"2019-01-29T23:57:08.000Z","updated_at":"2025-02-21T05:41:52.000Z","dependencies_parsed_at":"2024-06-19T05:30:22.604Z","dependency_job_id":"def81a7f-3a34-4b2c-af40-56d383afd4b7","html_url":"https://github.com/whitfin/sleeplocks","commit_stats":{"total_commits":23,"total_committers":4,"mean_commits":5.75,"dds":"0.13043478260869568","last_synced_commit":"cb814feb5942493f951dc7ad0a81b433c23598fd"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whitfin%2Fsleeplocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whitfin%2Fsleeplocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whitfin%2Fsleeplocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/whitfin%2Fsleeplocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/whitfin","download_url":"https://codeload.github.com/whitfin/sleeplocks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247427006,"owners_count":20937201,"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":["concurrency","concurrent-data-structure","parallel-programming"],"created_at":"2024-08-01T02:00:31.417Z","updated_at":"2025-04-06T03:09:37.260Z","avatar_url":"https://github.com/whitfin.png","language":"Erlang","funding_links":[],"categories":["Algorithms and Data structures"],"sub_categories":[],"readme":"# sleeplocks\n[![Build Status](https://img.shields.io/github/actions/workflow/status/whitfin/sleeplocks/ci.yml?branch=main)](https://github.com/whitfin/sleeplocks/actions) [![Hex.pm Version](https://img.shields.io/hexpm/v/sleeplocks.svg)](https://hex.pm/packages/sleeplocks) [![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://hexdocs.pm/sleeplocks/)\n\nThis library is designed to provide simple locking mechanisms in Erlang/Elixir, similar to\nhow spinlocks work in other languages - except using messages to communicate locking.\n\nThis is useful for libraries which require lock synchronization, without having to roll your\nown (however simple). Locks can be held by arbitrary numbers of process, making it possible\nto implement various throttling mechanisms.\n\nBest of all, this library is tiny! It builds upon basic OTP principles to implement lock\nbehaviour via simple processes and message passing.\n\n## Installation\n\n### Rebar\n\nFollow the instructons found [here](https://hex.pm/docs/rebar3_usage) to configure your\nRebar setup to use Hex as a dependency source, then you can grab it directly:\n\n```erlang\n{deps,[\n  % pulls the latest version\n  sleeplocks,\n  % to pull the latest version from github\n  {sleeplocks, {git, \"git://github.com/whitfin/sleeplocks.git\"}}\n]}.\n```\n\n### Mix\n\nTo install it for your project, you can pull it directly from Hex. Rather\nthan use the version shown below, you can use the latest version from\nHex (shown at the top of this README).\n\n```elixir\ndef deps do\n  [{:sleeplocks, \"~\u003e 1.0\"}]\nend\n```\n\n## Usage\n\nSnippets below contain sample usage in both Erlang and Elixir, and cover most of the small\nAPI space offered by `sleeplocks`. For a more complete example, scroll down!\n\n### Erlang\n\n```erlang\n% create a new single lock (with a name)\n1\u003e sleeplocks:new(1, [{name, {local, my_lock}}]).\n{ok,\u003c0.179.0\u003e}\n\n% take ownership of the lock\n2\u003e sleeplocks:acquire(my_lock).\nok\n\n% release the current hold on a lock\n3\u003e sleeplocks:release(my_lock).\nok\n\n% attempt to acquire a lock (which will succeed)\n4\u003e sleeplocks:attempt(my_lock).\nok\n\n% now that it's taken, other attempts will fail\n5\u003e sleeplocks:attempt(my_lock).\n{error,unavailable}\n\n% release the lock again\n6\u003e sleeplocks:release(my_lock).\nok\n\n% handle acquisition and locking automatically\n7\u003e sleeplocks:execute(my_lock, fun() -\u003e\n7\u003e   3\n7\u003e end).\n3\n```\n\n### Elixir\n\n```elixir\n# create a new single lock (with a name)\niex(1)\u003e :sleeplocks.new(1, [ name: :my_lock ])\n{:ok, #PID\u003c0.179.0\u003e}\n\n# take ownership of the lock\niex(2)\u003e :sleeplocks.acquire(:my_lock)\n:ok\n\n# release the current hold on a lock\niex(3)\u003e :sleeplocks.release(:my_lock)\n:ok\n\n# attempt to acquire a lock (which will succeed)\niex(4)\u003e :sleeplocks.attempt(:my_lock)\n:ok\n\n# now that it's taken, other attempts will fail\niex(5)\u003e :sleeplocks.attempt(:my_lock)\n{:error, :unavailable}\n\n# release the lock again\niex(6)\u003e :sleeplocks.release(:my_lock)\n:ok\n\n# handle acquisition and locking automatically\niex(7)\u003e :sleeplocks.execute(:my_lock, fn -\u003e\niex(7)\u003e   3\niex(7)\u003e end)\n3\n```\n\n## Examples\n\nThis example is in Elixir, but it should be fairly understandable for those coming from\nboth languages. It simply spawns 6 processes which each attempt to hold a lock for 10\nseconds. As the lock is created with only 2 slots, this runs for 30 seconds and 2 of our\nspawned tasks can hold the lock at any given time.\n\n```elixir\n# First create a new lock, with 2 slots only\n{:ok, ref} = :sleeplocks.new(2)\n\n# Then spawn 6 tasks, which each just sleep for 10 seconds\n# after acquiring the lock. This means that 2 processes will\n# acquire a lock and then release after 10 seconds. This\n# will repeat 3 times (6 / 2) until 30 seconds are up.\nfor idx \u003c- 1..6 do\n  Task.start(fn -\u003e\n    :sleeplocks.execute(ref, fn -\u003e\n      IO.puts(\"Locked #{idx}\")\n      Process.sleep(10_000)\n      IO.puts(\"Releasing #{idx}\")\n    end)\n  end)\nend\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhitfin%2Fsleeplocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhitfin%2Fsleeplocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhitfin%2Fsleeplocks/lists"}