From 2da2000413e0fd4739872e067a462a14f1dc6f8e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 6 Sep 2024 18:12:41 +0800 Subject: Use global lock instead of NewExclusivePool to allow distributed lock between multiple Gitea instances (#31813) Replace #26486 Fix #19620 --------- Co-authored-by: Jason Song --- modules/setting/gloabl_lock.go | 37 +++++++++++++++++++++++++++++++++++++ modules/setting/global_lock_test.go | 35 +++++++++++++++++++++++++++++++++++ modules/setting/setting.go | 1 + 3 files changed, 73 insertions(+) create mode 100644 modules/setting/gloabl_lock.go create mode 100644 modules/setting/global_lock_test.go (limited to 'modules/setting') diff --git a/modules/setting/gloabl_lock.go b/modules/setting/gloabl_lock.go new file mode 100644 index 0000000000..a7802a9df1 --- /dev/null +++ b/modules/setting/gloabl_lock.go @@ -0,0 +1,37 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/nosql" +) + +// GlobalLock represents configuration of global lock +var GlobalLock = struct { + ServiceType string + ServiceConnStr string +}{ + ServiceType: "memory", +} + +func loadGlobalLockFrom(rootCfg ConfigProvider) { + sec := rootCfg.Section("global_lock") + GlobalLock.ServiceType = sec.Key("SERVICE_TYPE").MustString("memory") + switch GlobalLock.ServiceType { + case "memory": + case "redis": + connStr := sec.Key("SERVICE_CONN_STR").String() + if connStr == "" { + log.Fatal("SERVICE_CONN_STR is empty for redis") + } + u := nosql.ToRedisURI(connStr) + if u == nil { + log.Fatal("SERVICE_CONN_STR %s is not a valid redis connection string", connStr) + } + GlobalLock.ServiceConnStr = connStr + default: + log.Fatal("Unknown sync lock service type: %s", GlobalLock.ServiceType) + } +} diff --git a/modules/setting/global_lock_test.go b/modules/setting/global_lock_test.go new file mode 100644 index 0000000000..5eeb275523 --- /dev/null +++ b/modules/setting/global_lock_test.go @@ -0,0 +1,35 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLoadGlobalLockConfig(t *testing.T) { + t.Run("DefaultGlobalLockConfig", func(t *testing.T) { + iniStr := `` + cfg, err := NewConfigProviderFromData(iniStr) + assert.NoError(t, err) + + loadGlobalLockFrom(cfg) + assert.EqualValues(t, "memory", GlobalLock.ServiceType) + }) + + t.Run("RedisGlobalLockConfig", func(t *testing.T) { + iniStr := ` +[global_lock] +SERVICE_TYPE = redis +SERVICE_CONN_STR = addrs=127.0.0.1:6379 db=0 +` + cfg, err := NewConfigProviderFromData(iniStr) + assert.NoError(t, err) + + loadGlobalLockFrom(cfg) + assert.EqualValues(t, "redis", GlobalLock.ServiceType) + assert.EqualValues(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr) + }) +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index b4f913cdae..c93d199b1b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -147,6 +147,7 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error { loadGitFrom(cfg) loadMirrorFrom(cfg) loadMarkupFrom(cfg) + loadGlobalLockFrom(cfg) loadOtherFrom(cfg) return nil } -- cgit v1.2.3