{"id":40811287,"url":"https://github.com/hunterhug/gorlock","last_synced_at":"2026-01-21T21:17:52.473Z","repository":{"id":57612919,"uuid":"271206556","full_name":"hunterhug/gorlock","owner":"hunterhug","description":"💐 Redis Distributed Lock By Golang","archived":false,"fork":false,"pushed_at":"2023-06-26T06:26:44.000Z","size":36,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-13T19:53:05.260Z","etag":null,"topics":["distributed-lock","distributed-locks","golang-redis-lock","lock-go","redis-lock"],"latest_commit_sha":null,"homepage":"","language":"Go","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/hunterhug.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":"2020-06-10T07:17:25.000Z","updated_at":"2023-01-29T09:22:01.000Z","dependencies_parsed_at":"2024-06-20T13:01:46.388Z","dependency_job_id":"24544eff-b1d1-4025-a626-9d7ed0f36c67","html_url":"https://github.com/hunterhug/gorlock","commit_stats":null,"previous_names":["hunterhug/rlock"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/hunterhug/gorlock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunterhug%2Fgorlock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunterhug%2Fgorlock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunterhug%2Fgorlock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunterhug%2Fgorlock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hunterhug","download_url":"https://codeload.github.com/hunterhug/gorlock/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hunterhug%2Fgorlock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28643315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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-lock","distributed-locks","golang-redis-lock","lock-go","redis-lock"],"created_at":"2026-01-21T21:17:52.384Z","updated_at":"2026-01-21T21:17:52.467Z","avatar_url":"https://github.com/hunterhug.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Redis Distributed Lock By Golang\n\n[![GitHub forks](https://img.shields.io/github/forks/hunterhug/gorlock.svg?style=social\u0026label=Forks)](https://github.com/hunterhug/gorlock/network)\n[![GitHub stars](https://img.shields.io/github/stars/hunterhug/gorlock.svg?style=social\u0026label=Stars)](https://github.com/hunterhug/gorlock/stargazers)\n[![GitHub last commit](https://img.shields.io/github/last-commit/hunterhug/gorlock.svg)](https://github.com/hunterhug/gorlock)\n[![GitHub issues](https://img.shields.io/github/issues/hunterhug/gorlock.svg)](https://github.com/hunterhug/gorlock/issues)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\n[中文说明](README_ZH.md)\n\nWhy use distributed lock?\n\n1. Some program processes/services may compete for resources, they distributed deployed in different position at many machines, ensure free from side effects such dirty read/write, we should lock those resources before make logic action.\n2. Some crontab task may distribute deployed, we know they will run at the same time when time reach, ensure crontab task can execute one by one, we make a task lock! \n3. Other Parallel security.\n\nSome cases: 1.avoid repeated order pay in E-commerce business, we lock the order. 2.multi copy of crontab statistical task run at night, we lock task.\n\nWe are support:\n\n1. Single Mode Redis: Stand-alone Redis.\n2. Sentinel Mode Redis: Pseudo Cluster Redis.\n\n## How to use\n\nSimple：\n\n```\ngo get -v github.com/hunterhug/gorlock\n```\n\nSupport auto keepAlive:\n\n```go\n// LockFactory is main interface\ntype LockFactory interface {\n\tSetRetryCount(c int64) LockFactory\n\tGetRetryCount() int64\n\tSetUnLockRetryCount(c int64) LockFactory\n\tGetUnLockRetryCount() int64\n\tSetKeepAlive(isKeepAlive bool) LockFactory\n\tIsKeepAlive() bool\n\tSetRetryMillSecondDelay(c int64) LockFactory\n\tGetRetryMillSecondDelay() int64\n\tSetUnLockRetryMillSecondDelay(c int64) LockFactory\n\tGetUnLockRetryMillSecondDelay() int64\n\tLockFactoryCore\n}\n\n// LockFactoryCore is core interface\ntype LockFactoryCore interface {\n\t// Lock ,lock resource default keepAlive depend on LockFactory\n\tLock(ctx context.Context, resourceName string, lockMillSecond int) (lock *Lock, err error)\n\t// LockForceKeepAlive lock resource force keepAlive\n\tLockForceKeepAlive(ctx context.Context, resourceName string, lockMillSecond int) (lock *Lock, err error)\n\t// LockForceNotKeepAlive lock resource force not keepAlive\n\tLockForceNotKeepAlive(ctx context.Context, resourceName string, lockMillSecond int) (lock *Lock, err error)\n\t// UnLock ,unlock resource\n\tUnLock(ctx context.Context, lock *Lock) (isUnLock bool, err error)\n\t// Done asynchronous see lock whether is release\n\tDone(lock *Lock) chan error\n}\n```\n\nIf you keepAlive the lock, you must call `defer UnLock()` every time you make a Lock.\n\n## Example\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/hunterhug/gorlock\"\n\t\"time\"\n)\n\nfunc main() {\n\tgorlock.SetDebug()\n\n\t// 1. config redis\n\tredisHost := \"127.0.0.1:6379\"\n\tredisDb := 0\n\tredisPass := \"hunterhug\" // may redis has password\n\tconfig := gorlock.NewRedisSingleModeConfig(redisHost, redisDb, redisPass)\n\tpool, err := gorlock.NewRedisPool(config)\n\tif err != nil {\n\t\tfmt.Println(\"redis init err:\", err.Error())\n\t\treturn\n\t}\n\n\t// 2. new a lock factory\n\tlockFactory := gorlock.New(pool)\n\n\t// set retry time and delay mill second\n\tlockFactory.SetRetryCount(3).SetRetryMillSecondDelay(200)\n\n\t// keep alive will auto extend the expire time of lock\n\tlockFactory.SetKeepAlive(true)\n\n\t// 3. lock a resource\n\tresourceName := \"myLock\"\n\n\t// 10s\n\texpireMillSecond := 10 * 1000\n\tlock, err := lockFactory.Lock(context.Background(), resourceName, expireMillSecond)\n\tif err != nil {\n\t\tfmt.Println(\"lock err:\", err.Error())\n\t\treturn\n\t}\n\n\t// lock empty point not lock\n\tif lock == nil {\n\t\tfmt.Println(\"lock err:\", \"can not lock\")\n\t\treturn\n\t}\n\n\t// add lock success\n\tfmt.Printf(\"add lock success:%#v\\n\", lock)\n\n\t// wait lock release\n\t//\u003c-lockFactory.Done(lock)\n\n\ttime.Sleep(3 * time.Second)\n\n\t// 4. unlock a resource\n\tisUnlock, err := lockFactory.UnLock(context.Background(), lock)\n\tif err != nil {\n\t\tfmt.Println(\"lock err:\", err.Error())\n\t\treturn\n\t}\n\n\tfmt.Printf(\"lock unlock: %v, %#v\\n\", isUnlock, lock)\n\n\t// unlock a resource again no effect side\n\tisUnlock, err = lockFactory.UnLock(context.Background(), lock)\n\tif err != nil {\n\t\tfmt.Println(\"lock err:\", err.Error())\n\t\treturn\n\t}\n\n\tfmt.Println(\"lock unlock:\", isUnlock)\n}\n```\n\nResult：\n\n```\nadd lock success:\u0026gorlock.Lock{CreateMillSecondTime:1627543007573, LiveMillSecondTime:10001, LastKeepAliveMillSecondTime:0, UnlockMillSecondTime:0, ResourceName:\"myLock\", RandomKey:\"a6f438bd9b1f4d759e818dbc78e890f4\", IsUnlock:false, isUnlockChan:(chan struct {})(0xc00007a1e0), IsClose:false, OpenKeepAlive:true, closeChan:(chan struct {})(0xc00007a240), keepAliveDealCloseChan:(chan bool)(0xc00007a2a0), mutex:sync.Mutex{state:0, sema:0x0}}\n2021-07-29 15:16:48.083 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:48.079402 +0800 CST m=+0.518137615 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 doing\n2021-07-29 15:16:48.586 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:48.583449 +0800 CST m=+1.022178426 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 doing\n2021-07-29 15:16:49.090 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:49.087154 +0800 CST m=+1.525877218 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 doing\n2021-07-29 15:16:49.594 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:49.590883 +0800 CST m=+2.029599435 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 doing\n2021-07-29 15:16:50.097 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:50.094998 +0800 CST m=+2.533708261 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 doing\n2021-07-29 15:16:50.575 github.com/hunterhug/gorlock:(*redisLockFactory).UnLock [DEBUG]: UnLock send signal to keepAlive ask game over\n2021-07-29 15:16:50.575 github.com/hunterhug/gorlock:(*redisLockFactory).keepAlive [DEBUG]: start in 2021-07-29 15:16:50.575115 +0800 CST m=+3.013818937 keepAlive myLock with random key:a6f438bd9b1f4d759e818dbc78e890f4 close\n2021-07-29 15:16:50.575 github.com/hunterhug/gorlock:(*redisLockFactory).UnLock [DEBUG]: UnLock receive signal to keepAlive response keepAliveHasBeenClose=false\nlock unlock: true, \u0026gorlock.Lock{CreateMillSecondTime:1627543007573, LiveMillSecondTime:10001, LastKeepAliveMillSecondTime:1627543010097, UnlockMillSecondTime:1627543010575, ResourceName:\"myLock\", RandomKey:\"a6f438bd9b1f4d759e818dbc78e890f4\", IsUnlock:true, isUnlockChan:(chan struct {})(0xc00007a1e0), IsClose:true, OpenKeepAlive:true, closeChan:(chan struct {})(0xc00007a240), keepAliveDealCloseChan:(chan bool)(0xc00007a2a0), mutex:sync.Mutex{state:0, sema:0x0}}\nlock unlock: true\n```\n\n# License\n\n```\nCopyright [2019-2021] [github.com/hunterhug]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhunterhug%2Fgorlock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhunterhug%2Fgorlock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhunterhug%2Fgorlock/lists"}