{"id":19484469,"url":"https://github.com/flowerinthenight/dlock","last_synced_at":"2025-04-25T16:33:44.502Z","repository":{"id":57531815,"uuid":"277716060","full_name":"flowerinthenight/dlock","owner":"flowerinthenight","description":"Package for distributed locks.","archived":false,"fork":false,"pushed_at":"2021-03-08T22:00:30.000Z","size":215,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-06-21T14:44:03.801Z","etag":null,"topics":["distributed-lock","distributed-locking","distributed-locks","go","golang","kubernetes","leaselock","redis","spindle"],"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/flowerinthenight.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":"2020-07-07T04:26:29.000Z","updated_at":"2023-04-30T10:07:00.000Z","dependencies_parsed_at":"2022-09-06T21:12:13.477Z","dependency_job_id":null,"html_url":"https://github.com/flowerinthenight/dlock","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowerinthenight%2Fdlock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowerinthenight%2Fdlock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowerinthenight%2Fdlock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowerinthenight%2Fdlock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flowerinthenight","download_url":"https://codeload.github.com/flowerinthenight/dlock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224009475,"owners_count":17240568,"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":["distributed-lock","distributed-locking","distributed-locks","go","golang","kubernetes","leaselock","redis","spindle"],"created_at":"2024-11-10T20:21:55.642Z","updated_at":"2024-11-10T20:21:56.904Z","avatar_url":"https://github.com/flowerinthenight.png","language":"Go","readme":"![main](https://github.com/flowerinthenight/dlock/workflows/main/badge.svg)\n\n`dlock` is a package for distributed locks. At the moment, available implementations are [Kubernetes](https://kubernetes.io/) using the [LeaseLock](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#lease-v1-coordination-k8s-io) resource, [spindle](https://github.com/flowerinthenight/spindle), and [Redlock](https://redis.io/topics/distlock) via [redsync](https://github.com/go-redsync/redsync).\n\nA simple [`Locker`](https://github.com/flowerinthenight/dlock/blob/master/dlock.go) interface is also provided. All lock objects in this package implement this interface.\n\n## Usage\n\n**LeaseLock**\n\nThe simplest usage form looks something like:\n```golang\nlock := dlock.NewK8sLock(\"unique-id\", \"lock-name\")\nlock.Lock(context.TODO())\n...\nlock.Unlock\n```\n\nA [sample code](https://github.com/flowerinthenight/dlock/blob/master/examples/k8slock/main.go) is provided for reference. A [deployment file](https://github.com/flowerinthenight/dlock/blob/master/examples/k8slock/k8slock.yaml) is also provided (only tested on GKE). It will deploy two pods that will both try to grab the same lock.\n\n```bash\n# Deploy to k8s:\n$ kubectl create -f k8slock.yaml\n\n# See logs (not the full logs):\n$ stern k8slock\nmain.go:53] [10.28.0.225] attempt to grab lock for a minute...\nmain.go:53] [10.28.4.52] attempt to grab lock for a minute...\nmain.go:47] [10.28.4.52] lock acquired by 10.28.4.52\nmain.go:57] [10.28.4.52] got the lock within that minute!\nmain.go:64] [10.28.4.52] now, let's attempt to grab the lock until termination\nmain.go:47] [10.28.4.52] lock acquired by 10.28.4.52\nmain.go:61] [10.28.0.225] we didn't get the lock within that minute\nmain.go:64] [10.28.0.225] now, let's attempt to grab the lock until termination\nmain.go:73] [10.28.0.225] stopping...\nmain.go:78] [10.28.0.225] we didn't get the lock in the end\nmain.go:73] [10.28.4.52] stopping...\nmain.go:75] [10.28.4.52] got the lock in the end\n\n# Cleanup:\n$ kubectl delete -f k8slock.yaml\n```\n\n**spindle**\n\nThis implementation is a wrapper to the [spindle](https://github.com/flowerinthenight/spindle) distributed locking library by providing a blocking `Lock(...)` / `Unlock()` function pair. This is probably useful if you are already using [Cloud Spanner](https://cloud.google.com/spanner/).\n\nThe basic usage will look something like:\n```golang\nctx := context.Background()\ndb, _ := spanner.NewClient(ctx, \"your/database\")\ndefer db.Close()\n\nlock := dlock.NewSpindleLock(\u0026dlock.SpindleLockOptions{\n  Client:   db,\n  Table:    \"testlease\",\n  Name:     \"dlock\",\n  Duration: 1000,\n})\n\nstart := time.Now()\nlock.Lock(ctx)\nlog.Printf(\"lock acquired after %v, do protected work...\", time.Since(start))\ntime.Sleep(time.Second * 5)\nlock.Unlock()\n```\n\n**Redis**\n\nThe Redis implementation is basically a wrapper to the brilliant [redsync](https://github.com/go-redsync/redsync) package, with additional utility functions for working with Redis connection pools. It's also implemented in a way to follow the [`Locker`](https://github.com/flowerinthenight/dlock/blob/master/dlock.go) interface.\n\nTo use with a single Redis host, no password, use defaults:\n```golang\nlock := dlock.NewRedisLock(\"testredislock\", dlock.WithHost(\"1.2.3.4\"))\nlock.Lock(context.Background())\n...\nlock.Unlock()\n```\n\nTo use with a single Redis host, with password, use defaults:\n```golang\npool := dlock.NewRedisPool(\"1.2.3.4\", dlock.WithPassword(\"secret-pass\"))\nlock := dlock.NewRedisLock(\"testredislock\", dlock.WithPools([]*redis.Pool{pool}))\nlock.Lock(context.Background())\n...\nlock.Unlock()\n```\n\nYou can check out the [test file](https://github.com/flowerinthenight/dlock/blob/master/redislock_test.go) and the [sample code](https://github.com/flowerinthenight/dlock/blob/master/examples/redislock/main.go) for usage reference. You can run the sample code in separate terminals simultaneously and one process should be able to grab the Redis lock.\n\n----\n\n### Todo\nPR's are welcome.\n- [x] LeaseLock (k8s)\n- [x] spindle\n- [ ] etcd\n- [ ] Zookeeper\n- [ ] Consul\n- [x] Redis\n- [x] Add CI\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowerinthenight%2Fdlock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowerinthenight%2Fdlock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowerinthenight%2Fdlock/lists"}