From c9871c80c802aea332ba09a5443c974fcbd338dc Mon Sep 17 00:00:00 2001 From: Egor Matveev Date: Mon, 6 Jan 2025 13:07:17 +0300 Subject: [PATCH] fix --- .deploy/deploy-dev.yaml | 2 ++ .deploy/deploy-prod.yaml | 2 ++ .gitea/workflows/deploy-dev.yaml | 1 + .gitea/workflows/deploy-prod.yaml | 1 + app/routers/take.go | 13 +++++++++++++ app/storage/redis/locks.go | 28 ++++++++++++++++++++++++++++ go.mod | 7 +++++++ go.sum | 13 +++++++++++++ main.go | 2 ++ 9 files changed, 69 insertions(+) create mode 100644 app/storage/redis/locks.go diff --git a/.deploy/deploy-dev.yaml b/.deploy/deploy-dev.yaml index 302ba1d..a0f47e3 100644 --- a/.deploy/deploy-dev.yaml +++ b/.deploy/deploy-dev.yaml @@ -9,6 +9,8 @@ services: environment: MONGO_HOST: "mongo.develop.sprinthub.ru" MONGO_PASSWORD: $MONGO_PASSWORD_DEV + REDIS_HOST: "redis.develop.sprinthub.ru" + REDIS_PASSWORD: $REDIS_PASSWORD_DEV STAGE: "development" deploy: mode: replicated diff --git a/.deploy/deploy-prod.yaml b/.deploy/deploy-prod.yaml index 187e3db..b091579 100644 --- a/.deploy/deploy-prod.yaml +++ b/.deploy/deploy-prod.yaml @@ -9,6 +9,8 @@ services: environment: MONGO_HOST: "mongo.sprinthub.ru" MONGO_PASSWORD: $MONGO_PASSWORD_PROD + REDIS_HOST: "redis.sprinthub.ru" + REDIS_PASSWORD: $REDIS_PASSWORD_PROD STAGE: "production" deploy: mode: replicated diff --git a/.gitea/workflows/deploy-dev.yaml b/.gitea/workflows/deploy-dev.yaml index 3efe3ac..843315a 100644 --- a/.gitea/workflows/deploy-dev.yaml +++ b/.gitea/workflows/deploy-dev.yaml @@ -40,4 +40,5 @@ jobs: - name: deploy env: MONGO_PASSWORD_DEV: ${{ secrets.MONGO_PASSWORD_DEV }} + REDIS_PASSWORD_DEV: ${{ secrets.REDIS_PASSWORD_DEV }} run: docker stack deploy --with-registry-auth -c ./.deploy/deploy-dev.yaml infra-development diff --git a/.gitea/workflows/deploy-prod.yaml b/.gitea/workflows/deploy-prod.yaml index 9a6c82f..4ce27eb 100644 --- a/.gitea/workflows/deploy-prod.yaml +++ b/.gitea/workflows/deploy-prod.yaml @@ -40,4 +40,5 @@ jobs: - name: deploy env: MONGO_PASSWORD_PROD: ${{ secrets.MONGO_PASSWORD_PROD }} + REDIS_PASSWORD_PROD: ${{ secrets.REDIS_PASSWORD_PROD }} run: docker stack deploy --with-registry-auth -c ./.deploy/deploy-prod.yaml infra diff --git a/app/routers/take.go b/app/routers/take.go index 42bc6ff..1f3d05c 100644 --- a/app/routers/take.go +++ b/app/routers/take.go @@ -1,8 +1,11 @@ package routers import ( + "fmt" "net/http" tasks "queues-go/app/storage/mongo/collections" + "queues-go/app/storage/redis" + "time" ) type TaskResponse struct { @@ -17,7 +20,17 @@ type TakeResponse struct { func Take(r *http.Request) (interface{}, int) { queue := r.Header.Get("queue") + mutex := redis.Sync.NewMutex(fmt.Sprintf("lock_queues_%s", queue)) + for { + err := mutex.Lock() + if err != nil { + time.Sleep(time.Millisecond * 5) + } else { + break + } + } task, err := tasks.Take(queue) + mutex.Unlock() if err != nil { return nil, http.StatusInternalServerError } diff --git a/app/storage/redis/locks.go b/app/storage/redis/locks.go new file mode 100644 index 0000000..5ddee39 --- /dev/null +++ b/app/storage/redis/locks.go @@ -0,0 +1,28 @@ +package redis + +import ( + "fmt" + "queues-go/app/utils" + + "github.com/go-redsync/redsync/v4" + "github.com/go-redsync/redsync/v4/redis/goredis/v9" + goredislib "github.com/redis/go-redis/v9" +) + +var Sync redsync.Redsync + +func Connect() { + client := goredislib.NewClient(getOptions()) + pool := goredis.NewPool(client) + Sync = *redsync.New(pool) +} + +func getOptions() *goredislib.Options { + addr := fmt.Sprintf("%s:6379", utils.GetEnv("REDIS_HOST", "localhost")) + password := utils.GetEnv("REDIS_PASSWORD", "password") + + return &goredislib.Options{ + Addr: addr, + Password: password, + } +} diff --git a/go.mod b/go.mod index cdc9282..168ff46 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,17 @@ module queues-go go 1.23.4 +require github.com/go-redsync/redsync/v4 v4.13.0 + require ( + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/montanaflynn/stats v0.7.1 // indirect + github.com/redis/go-redis/v9 v9.5.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect diff --git a/go.sum b/go.sum index 9ea4ff2..37bbb89 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,22 @@ +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkvQ1EkZKA= +github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= +github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= diff --git a/main.go b/main.go index d2562b5..6365a21 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "net/http" "queues-go/app/routers" client "queues-go/app/storage/mongo" + "queues-go/app/storage/redis" "time" ) @@ -30,6 +31,7 @@ func handlerWrapper(f func(*http.Request) (interface{}, int)) func(http.Response func main() { client.Connect() + redis.Connect() http.HandleFunc("/api/v1/take", handlerWrapper(routers.Take)) http.HandleFunc("/api/v1/finish", handlerWrapper(routers.Finish)) http.HandleFunc("/api/v1/put", handlerWrapper(routers.Put))