{"id":13528170,"url":"https://github.com/chiradeep/dyndb-mutex","last_synced_at":"2026-02-04T18:30:27.287Z","repository":{"id":55007574,"uuid":"76488244","full_name":"chiradeep/dyndb-mutex","owner":"chiradeep","description":"A mutex lock implementation leveraging DynamoDB. Useful for AWS Lambda","archived":false,"fork":false,"pushed_at":"2021-01-15T19:32:07.000Z","size":37,"stargazers_count":65,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-09-29T05:02:05.208Z","etag":null,"topics":["aws-lambda","dynamodb","dynamodb-table","mutex"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chiradeep.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}},"created_at":"2016-12-14T18:59:17.000Z","updated_at":"2024-02-26T10:47:12.000Z","dependencies_parsed_at":"2022-08-14T08:50:55.443Z","dependency_job_id":null,"html_url":"https://github.com/chiradeep/dyndb-mutex","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/chiradeep/dyndb-mutex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiradeep%2Fdyndb-mutex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiradeep%2Fdyndb-mutex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiradeep%2Fdyndb-mutex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiradeep%2Fdyndb-mutex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chiradeep","download_url":"https://codeload.github.com/chiradeep/dyndb-mutex/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiradeep%2Fdyndb-mutex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29092965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"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":["aws-lambda","dynamodb","dynamodb-table","mutex"],"created_at":"2024-08-01T06:02:16.073Z","updated_at":"2026-02-04T18:30:27.270Z","avatar_url":"https://github.com/chiradeep.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# dyndb-mutex\nA mutex implementation  leveraging [AWS DynamoDB](https://aws.amazon.com/dynamodb/)\nAlthough this was built for use in  [AWS Lambda](https://aws.amazon.com/lambda), note that you can use this mutex implementation in any context - even outside AWS.\n\n# Install\n```\nsudo pip install dyndbmutex\n```\nor checkout this repository and run `python setup.py`. Or download a release from the releases page and go from there.\n\n# Usage\nLet's say you want to ensure that only 1 python function can access a resource (for example an AWS instance `i-8abd82c31`) at a time\n\n```\n   from dyndbmutex.dyndbmutex import DynamoDbMutex\n   # at the beginning of your function\n   # generate a unique name for this process/thread\n   my_name = str(uuid.uuid4()).split(\"-\")[0]\n   m = DynamoDbMutex('i-8abd832c32', holder=my_name, timeoutms=200 * 1000)\n   locked = m.lock()\n   if locked:\n      # critical section begin\n       ......\n      # critical section end\n      m.release()\n\n\n```\n\nYou can also use the `with` pattern:\n\n```\n   from dyndbmutex.dyndbmutex import DynamoDbMutex, AcquireLockFailedError\n   my_name = str(uuid.uuid4()).split(\"-\")[0]\n   m = DynamoDbMutex('i-8abd832c32', my_name, 200 * 1000)\n   try:\n       with m:\n          # critical section\n   except mutex.AcquireLockFailedError:\n       #m will be released at this point\n\n```\n\n# Theory of operation\nUses [DynamoDb conditional write](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.ConditionalUpdate) as an [atomic compare-and-swap](https://en.wikipedia.org/wiki/Compare-and-swap) operation to implement a mutex.\n\n  * Prune lock: if the acquirer fails to release it within the timeout, release it if it is expired\n  * Acquire lock: prune the lock if required. If the lock is now released, acquire it\n  * Release lock: release it if I am the holder, otherwise fail.\n\nSince the conditional write is atomic (test and set), this works very well. In fact the code doesn't even read the table, only writes to it.\n(We could even make the lock re-entrant since we have the owner/holder information, but leave a note/issue if this is important for your usecase)\n\n# Setup\nThe default name for the Mutex table in DynamoDB is 'Mutex'. You can change this by setting an environment variable:\n\n```\nexport DD_MUTEX_TABLE_NAME=FancyPantsMutex\n```\n\nThe code will auto-create the mutex DynamoDB table, but this could take at least 20 seconds. As an alternative, use the `create-table` script in the scripts directory before using this mutex library.\n\n\n# Notes and Limitations\nAlthough the code is general-purpose and can be used outside of AWS Lambda, note the following limitations:\n\n* Not designed for fine-grained parallelism. Generally, it is expected that you acquire a lock and hold it for a short duration (seconds)\n* Does not detect/prevent deadlocks. There is no spin lock, but the mutex user could create one by spinning until an acquire succeeds. Within a Lambda function, one should avoid taking more than 1 lock.\n* Assumes that client-side delays, pauses and clock drift are all small relative to the expiry time of a lock. Therefore, use a large timeout if there are little-to-no guarantees on how long your lock acquirer can get paused (e.g., due to GC, long lived critical sections). See [this](https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html) for more.\n* Not re-entrant. If a thread (e.g.,a lambda function) tries to re-acquire a lock it already holds, it will block\n* Not designed for speed. The DynamoDb table backing the locks is generally provisioned as low throughput (2 ops/sec)\n* Cleanup - the mutex table is created with the [TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) feature. By default, the TTL is 2 days; after 2 days of disuse, the row created to hold the mutex should get automatically deleted. You can use set the `ttl_minutes` in the constructor to choose a different TTL\n\n\n# TODO\n* No limits on timeout. Perhaps there should be one (300 seconds?)\n* Re-entrancy\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiradeep%2Fdyndb-mutex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchiradeep%2Fdyndb-mutex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiradeep%2Fdyndb-mutex/lists"}