refacrot: 优化目录结构

This commit is contained in:
tbphp
2025-07-13 20:28:14 +08:00
parent 37bdcf2e72
commit e1478e4b88
7 changed files with 86 additions and 87 deletions

View File

@@ -30,9 +30,9 @@ type App struct {
groupManager *services.GroupManager groupManager *services.GroupManager
logCleanupService *services.LogCleanupService logCleanupService *services.LogCleanupService
requestLogService *services.RequestLogService requestLogService *services.RequestLogService
keyCronService *services.KeyCronService cronChecker *keypool.CronChecker
keyPoolProvider *keypool.KeyProvider keyPoolProvider *keypool.KeyProvider
leaderService *services.LeaderService leaderLock *store.LeaderLock
proxyServer *proxy.ProxyServer proxyServer *proxy.ProxyServer
storage store.Store storage store.Store
db *gorm.DB db *gorm.DB
@@ -48,9 +48,9 @@ type AppParams struct {
GroupManager *services.GroupManager GroupManager *services.GroupManager
LogCleanupService *services.LogCleanupService LogCleanupService *services.LogCleanupService
RequestLogService *services.RequestLogService RequestLogService *services.RequestLogService
KeyCronService *services.KeyCronService CronChecker *keypool.CronChecker
KeyPoolProvider *keypool.KeyProvider KeyPoolProvider *keypool.KeyProvider
LeaderService *services.LeaderService LeaderLock *store.LeaderLock
ProxyServer *proxy.ProxyServer ProxyServer *proxy.ProxyServer
Storage store.Store Storage store.Store
DB *gorm.DB DB *gorm.DB
@@ -65,9 +65,9 @@ func NewApp(params AppParams) *App {
groupManager: params.GroupManager, groupManager: params.GroupManager,
logCleanupService: params.LogCleanupService, logCleanupService: params.LogCleanupService,
requestLogService: params.RequestLogService, requestLogService: params.RequestLogService,
keyCronService: params.KeyCronService, cronChecker: params.CronChecker,
keyPoolProvider: params.KeyPoolProvider, keyPoolProvider: params.KeyPoolProvider,
leaderService: params.LeaderService, leaderLock: params.LeaderLock,
proxyServer: params.ProxyServer, proxyServer: params.ProxyServer,
storage: params.Storage, storage: params.Storage,
db: params.DB, db: params.DB,
@@ -77,25 +77,25 @@ func NewApp(params AppParams) *App {
// Start runs the application, it is a non-blocking call. // Start runs the application, it is a non-blocking call.
func (a *App) Start() error { func (a *App) Start() error {
// 启动 Leader Service 并等待选举结果 // 启动 Leader Lock 服务并等待选举结果
if err := a.leaderService.Start(); err != nil { if err := a.leaderLock.Start(); err != nil {
return fmt.Errorf("leader service failed to start: %w", err) return fmt.Errorf("leader service failed to start: %w", err)
} }
// Leader 节点执行初始化Follower 节点等待 // Leader 节点执行初始化Follower 节点等待
if a.leaderService.IsLeader() { if a.leaderLock.IsLeader() {
logrus.Info("Leader mode. Performing initial one-time tasks...") logrus.Info("Leader mode. Performing initial one-time tasks...")
acquired, err := a.leaderService.AcquireInitializingLock() acquired, err := a.leaderLock.AcquireInitializingLock()
if err != nil { if err != nil {
return fmt.Errorf("failed to acquire initializing lock: %w", err) return fmt.Errorf("failed to acquire initializing lock: %w", err)
} }
if !acquired { if !acquired {
logrus.Warn("Could not acquire initializing lock, another leader might be active. Switching to follower mode for initialization.") logrus.Warn("Could not acquire initializing lock, another leader might be active. Switching to follower mode for initialization.")
if err := a.leaderService.WaitForInitializationToComplete(); err != nil { if err := a.leaderLock.WaitForInitializationToComplete(); err != nil {
return fmt.Errorf("failed to wait for initialization as a fallback follower: %w", err) return fmt.Errorf("failed to wait for initialization as a fallback follower: %w", err)
} }
} else { } else {
defer a.leaderService.ReleaseInitializingLock() defer a.leaderLock.ReleaseInitializingLock()
// 数据库迁移 // 数据库迁移
if err := a.db.AutoMigrate( if err := a.db.AutoMigrate(
@@ -115,7 +115,7 @@ func (a *App) Start() error {
} }
logrus.Info("System settings initialized in DB.") logrus.Info("System settings initialized in DB.")
a.settingsManager.Initialize(a.storage, a.groupManager, a.leaderService) a.settingsManager.Initialize(a.storage, a.groupManager, a.leaderLock)
// 从数据库加载密钥到 Redis // 从数据库加载密钥到 Redis
if err := a.keyPoolProvider.LoadKeysFromDB(); err != nil { if err := a.keyPoolProvider.LoadKeysFromDB(); err != nil {
@@ -125,10 +125,10 @@ func (a *App) Start() error {
} }
} else { } else {
logrus.Info("Follower Mode. Waiting for leader to complete initialization.") logrus.Info("Follower Mode. Waiting for leader to complete initialization.")
if err := a.leaderService.WaitForInitializationToComplete(); err != nil { if err := a.leaderLock.WaitForInitializationToComplete(); err != nil {
return fmt.Errorf("follower failed to start: %w", err) return fmt.Errorf("follower failed to start: %w", err)
} }
a.settingsManager.Initialize(a.storage, a.groupManager, a.leaderService) a.settingsManager.Initialize(a.storage, a.groupManager, a.leaderLock)
} }
// 显示配置并启动所有后台服务 // 显示配置并启动所有后台服务
@@ -138,7 +138,7 @@ func (a *App) Start() error {
a.requestLogService.Start() a.requestLogService.Start()
a.logCleanupService.Start() a.logCleanupService.Start()
a.keyCronService.Start() a.cronChecker.Start()
// Create HTTP server // Create HTTP server
serverConfig := a.configManager.GetEffectiveServerConfig() serverConfig := a.configManager.GetEffectiveServerConfig()
@@ -174,8 +174,8 @@ func (a *App) Stop(ctx context.Context) {
} }
// Stop background services // Stop background services
a.keyCronService.Stop() a.cronChecker.Stop()
a.leaderService.Stop() a.leaderLock.Stop()
a.logCleanupService.Stop() a.logCleanupService.Stop()
a.requestLogService.Stop() a.requestLogService.Stop()
a.groupManager.Stop() a.groupManager.Stop()

View File

@@ -35,12 +35,12 @@ type groupManager interface {
Invalidate() error Invalidate() error
} }
type leaderService interface { type leaderLock interface {
IsLeader() bool IsLeader() bool
} }
// Initialize initializes the SystemSettingsManager with database and store dependencies. // Initialize initializes the SystemSettingsManager with database and store dependencies.
func (sm *SystemSettingsManager) Initialize(store store.Store, gm groupManager, leader leaderService) error { func (sm *SystemSettingsManager) Initialize(store store.Store, gm groupManager, leaderLock leaderLock) error {
settingsLoader := func() (types.SystemSettings, error) { settingsLoader := func() (types.SystemSettings, error) {
var dbSettings []models.SystemSetting var dbSettings []models.SystemSetting
if err := db.DB.Find(&dbSettings).Error; err != nil { if err := db.DB.Find(&dbSettings).Error; err != nil {
@@ -82,7 +82,7 @@ func (sm *SystemSettingsManager) Initialize(store store.Store, gm groupManager,
} }
afterLoader := func(newData types.SystemSettings) { afterLoader := func(newData types.SystemSettings) {
if !leader.IsLeader() { if !leaderLock.IsLeader() {
return return
} }
if err := gm.Invalidate(); err != nil { if err := gm.Invalidate(); err != nil {

View File

@@ -25,9 +25,6 @@ func BuildContainer() (*dig.Container, error) {
if err := container.Provide(config.NewManager); err != nil { if err := container.Provide(config.NewManager); err != nil {
return nil, err return nil, err
} }
if err := container.Provide(services.NewLeaderService); err != nil {
return nil, err
}
if err := container.Provide(db.NewDB); err != nil { if err := container.Provide(db.NewDB); err != nil {
return nil, err return nil, err
} }
@@ -37,6 +34,9 @@ func BuildContainer() (*dig.Container, error) {
if err := container.Provide(store.NewStore); err != nil { if err := container.Provide(store.NewStore); err != nil {
return nil, err return nil, err
} }
if err := container.Provide(store.NewLeaderLock); err != nil {
return nil, err
}
if err := container.Provide(httpclient.NewHTTPClientManager); err != nil { if err := container.Provide(httpclient.NewHTTPClientManager); err != nil {
return nil, err return nil, err
} }
@@ -51,9 +51,6 @@ func BuildContainer() (*dig.Container, error) {
if err := container.Provide(services.NewKeyManualValidationService); err != nil { if err := container.Provide(services.NewKeyManualValidationService); err != nil {
return nil, err return nil, err
} }
if err := container.Provide(services.NewKeyCronService); err != nil {
return nil, err
}
if err := container.Provide(services.NewKeyService); err != nil { if err := container.Provide(services.NewKeyService); err != nil {
return nil, err return nil, err
} }
@@ -72,6 +69,9 @@ func BuildContainer() (*dig.Container, error) {
if err := container.Provide(keypool.NewKeyValidator); err != nil { if err := container.Provide(keypool.NewKeyValidator); err != nil {
return nil, err return nil, err
} }
if err := container.Provide(keypool.NewCronChecker); err != nil {
return nil, err
}
// Handlers // Handlers
if err := container.Provide(handler.NewServer); err != nil { if err := container.Provide(handler.NewServer); err != nil {

View File

@@ -1,9 +1,9 @@
package services package keypool
import ( import (
"gpt-load/internal/config" "gpt-load/internal/config"
"gpt-load/internal/keypool"
"gpt-load/internal/models" "gpt-load/internal/models"
"gpt-load/internal/store"
"sync" "sync"
"time" "time"
@@ -11,51 +11,51 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// KeyCronService is responsible for periodically validating invalid keys. // NewCronChecker is responsible for periodically validating invalid keys.
type KeyCronService struct { type CronChecker struct {
DB *gorm.DB DB *gorm.DB
SettingsManager *config.SystemSettingsManager SettingsManager *config.SystemSettingsManager
Validator *keypool.KeyValidator Validator *KeyValidator
LeaderService *LeaderService LeaderLock *store.LeaderLock
stopChan chan struct{} stopChan chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
} }
// NewKeyCronService creates a new KeyCronService. // NewCronChecker creates a new CronChecker.
func NewKeyCronService( func NewCronChecker(
db *gorm.DB, db *gorm.DB,
settingsManager *config.SystemSettingsManager, settingsManager *config.SystemSettingsManager,
validator *keypool.KeyValidator, validator *KeyValidator,
leaderService *LeaderService, leaderLock *store.LeaderLock,
) *KeyCronService { ) *CronChecker {
return &KeyCronService{ return &CronChecker{
DB: db, DB: db,
SettingsManager: settingsManager, SettingsManager: settingsManager,
Validator: validator, Validator: validator,
LeaderService: leaderService, LeaderLock: leaderLock,
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
} }
} }
// Start begins the cron job execution. // Start begins the cron job execution.
func (s *KeyCronService) Start() { func (s *CronChecker) Start() {
logrus.Debug("Starting KeyCronService...") logrus.Debug("Starting CronChecker...")
s.wg.Add(1) s.wg.Add(1)
go s.runLoop() go s.runLoop()
} }
// Stop stops the cron job. // Stop stops the cron job.
func (s *KeyCronService) Stop() { func (s *CronChecker) Stop() {
logrus.Info("Stopping KeyCronService...") logrus.Info("Stopping CronChecker...")
close(s.stopChan) close(s.stopChan)
s.wg.Wait() s.wg.Wait()
logrus.Info("KeyCronService stopped.") logrus.Info("CronChecker stopped.")
} }
func (s *KeyCronService) runLoop() { func (s *CronChecker) runLoop() {
defer s.wg.Done() defer s.wg.Done()
if s.LeaderService.IsLeader() { if s.LeaderLock.IsLeader() {
s.submitValidationJobs() s.submitValidationJobs()
} }
@@ -65,11 +65,11 @@ func (s *KeyCronService) runLoop() {
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
if s.LeaderService.IsLeader() { if s.LeaderLock.IsLeader() {
logrus.Debug("KeyCronService: Running as leader, submitting validation jobs.") logrus.Debug("CronChecker: Running as leader, submitting validation jobs.")
s.submitValidationJobs() s.submitValidationJobs()
} else { } else {
logrus.Debug("KeyCronService: Not the leader. Standing by.") logrus.Debug("CronChecker: Not the leader. Standing by.")
} }
case <-s.stopChan: case <-s.stopChan:
return return
@@ -78,10 +78,10 @@ func (s *KeyCronService) runLoop() {
} }
// submitValidationJobs finds groups whose keys need validation and validates them. // submitValidationJobs finds groups whose keys need validation and validates them.
func (s *KeyCronService) submitValidationJobs() { func (s *CronChecker) submitValidationJobs() {
var groups []models.Group var groups []models.Group
if err := s.DB.Find(&groups).Error; err != nil { if err := s.DB.Find(&groups).Error; err != nil {
logrus.Errorf("KeyCronService: Failed to get groups: %v", err) logrus.Errorf("CronChecker: Failed to get groups: %v", err)
return return
} }
@@ -97,14 +97,14 @@ func (s *KeyCronService) submitValidationJobs() {
var invalidKeys []models.APIKey var invalidKeys []models.APIKey
err := s.DB.Where("group_id = ? AND status = ?", group.ID, models.KeyStatusInvalid).Find(&invalidKeys).Error err := s.DB.Where("group_id = ? AND status = ?", group.ID, models.KeyStatusInvalid).Find(&invalidKeys).Error
if err != nil { if err != nil {
logrus.Errorf("KeyCronService: Failed to get invalid keys for group %s: %v", group.Name, err) logrus.Errorf("CronChecker: Failed to get invalid keys for group %s: %v", group.Name, err)
continue continue
} }
validatedCount := len(invalidKeys) validatedCount := len(invalidKeys)
becameValidCount := 0 becameValidCount := 0
if validatedCount > 0 { if validatedCount > 0 {
logrus.Debugf("KeyCronService: Found %d invalid keys to validate for group %s.", validatedCount, group.Name) logrus.Debugf("CronChecker: Found %d invalid keys to validate for group %s.", validatedCount, group.Name)
for j := range invalidKeys { for j := range invalidKeys {
key := &invalidKeys[j] key := &invalidKeys[j]
isValid, _ := s.Validator.ValidateSingleKey(key, group) isValid, _ := s.Validator.ValidateSingleKey(key, group)
@@ -116,12 +116,12 @@ func (s *KeyCronService) submitValidationJobs() {
} }
if err := s.DB.Model(group).Update("last_validated_at", time.Now()).Error; err != nil { if err := s.DB.Model(group).Update("last_validated_at", time.Now()).Error; err != nil {
logrus.Errorf("KeyCronService: Failed to update last_validated_at for group %s: %v", group.Name, err) logrus.Errorf("CronChecker: Failed to update last_validated_at for group %s: %v", group.Name, err)
} }
duration := time.Since(groupProcessStart) duration := time.Since(groupProcessStart)
logrus.Infof( logrus.Infof(
"KeyCronService: Group '%s' validation finished. Total checked: %d, became valid: %d. Duration: %s.", "CronChecker: Group '%s' validation finished. Total checked: %d, became valid: %d. Duration: %s.",
group.Name, group.Name,
validatedCount, validatedCount,
becameValidCount, becameValidCount,

View File

@@ -3,6 +3,7 @@ package services
import ( import (
"gpt-load/internal/config" "gpt-load/internal/config"
"gpt-load/internal/models" "gpt-load/internal/models"
"gpt-load/internal/store"
"time" "time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@@ -13,16 +14,16 @@ import (
type LogCleanupService struct { type LogCleanupService struct {
db *gorm.DB db *gorm.DB
settingsManager *config.SystemSettingsManager settingsManager *config.SystemSettingsManager
leaderService *LeaderService leaderLock *store.LeaderLock
stopCh chan struct{} stopCh chan struct{}
} }
// NewLogCleanupService 创建新的日志清理服务 // NewLogCleanupService 创建新的日志清理服务
func NewLogCleanupService(db *gorm.DB, settingsManager *config.SystemSettingsManager, leaderService *LeaderService) *LogCleanupService { func NewLogCleanupService(db *gorm.DB, settingsManager *config.SystemSettingsManager, leaderLock *store.LeaderLock) *LogCleanupService {
return &LogCleanupService{ return &LogCleanupService{
db: db, db: db,
settingsManager: settingsManager, settingsManager: settingsManager,
leaderService: leaderService, leaderLock: leaderLock,
stopCh: make(chan struct{}), stopCh: make(chan struct{}),
} }
} }
@@ -59,7 +60,7 @@ func (s *LogCleanupService) run() {
// cleanupExpiredLogs 清理过期的请求日志 // cleanupExpiredLogs 清理过期的请求日志
func (s *LogCleanupService) cleanupExpiredLogs() { func (s *LogCleanupService) cleanupExpiredLogs() {
if !s.leaderService.IsLeader() { if !s.leaderLock.IsLeader() {
logrus.Debug("Not the leader, skipping log cleanup.") logrus.Debug("Not the leader, skipping log cleanup.")
return return
} }

View File

@@ -27,20 +27,20 @@ type RequestLogService struct {
db *gorm.DB db *gorm.DB
store store.Store store store.Store
settingsManager *config.SystemSettingsManager settingsManager *config.SystemSettingsManager
leaderService *LeaderService leaderLock *store.LeaderLock
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
ticker *time.Ticker ticker *time.Ticker
} }
// NewRequestLogService creates a new RequestLogService instance // NewRequestLogService creates a new RequestLogService instance
func NewRequestLogService(db *gorm.DB, store store.Store, sm *config.SystemSettingsManager, ls *LeaderService) *RequestLogService { func NewRequestLogService(db *gorm.DB, store store.Store, sm *config.SystemSettingsManager, ls *store.LeaderLock) *RequestLogService {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
return &RequestLogService{ return &RequestLogService{
db: db, db: db,
store: store, store: store,
settingsManager: sm, settingsManager: sm,
leaderService: ls, leaderLock: ls,
ctx: ctx, ctx: ctx,
cancel: cancel, cancel: cancel,
} }
@@ -116,7 +116,7 @@ func (s *RequestLogService) flush() {
return return
} }
if !s.leaderService.IsLeader() { if !s.leaderLock.IsLeader() {
logrus.Debug("Not a leader, skipping log flush.") logrus.Debug("Not a leader, skipping log flush.")
return return
} }

View File

@@ -1,4 +1,4 @@
package services package store
import ( import (
"context" "context"
@@ -9,8 +9,6 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"gpt-load/internal/store"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@@ -36,9 +34,9 @@ else
return 0 return 0
end` end`
// LeaderService provides a mechanism for electing a single leader in a cluster. // LeaderLock provides a mechanism for electing a single leader in a cluster.
type LeaderService struct { type LeaderLock struct {
store store.Store store Store
nodeID string nodeID string
isLeader atomic.Bool isLeader atomic.Bool
stopChan chan struct{} stopChan chan struct{}
@@ -46,10 +44,10 @@ type LeaderService struct {
isSingleNode bool isSingleNode bool
} }
// NewLeaderService creates a new LeaderService. // NewLeaderLock creates a new LeaderLock.
func NewLeaderService(s store.Store) *LeaderService { func NewLeaderLock(s Store) *LeaderLock {
_, isDistributed := s.(store.LuaScripter) _, isDistributed := s.(LuaScripter)
service := &LeaderService{ service := &LeaderLock{
store: s, store: s,
nodeID: generateNodeID(), nodeID: generateNodeID(),
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
@@ -65,7 +63,7 @@ func NewLeaderService(s store.Store) *LeaderService {
} }
// Start performs an initial leader election and starts the background leadership maintenance loop. // Start performs an initial leader election and starts the background leadership maintenance loop.
func (s *LeaderService) Start() error { func (s *LeaderLock) Start() error {
if s.isSingleNode { if s.isSingleNode {
return nil return nil
} }
@@ -81,7 +79,7 @@ func (s *LeaderService) Start() error {
} }
// Stop gracefully stops the leadership maintenance process. // Stop gracefully stops the leadership maintenance process.
func (s *LeaderService) Stop() { func (s *LeaderLock) Stop() {
if s.isSingleNode { if s.isSingleNode {
return return
} }
@@ -96,12 +94,12 @@ func (s *LeaderService) Stop() {
} }
// IsLeader returns true if the current node is the leader. // IsLeader returns true if the current node is the leader.
func (s *LeaderService) IsLeader() bool { func (s *LeaderLock) IsLeader() bool {
return s.isLeader.Load() return s.isLeader.Load()
} }
// AcquireInitializingLock sets a temporary lock to indicate that initialization is in progress. // AcquireInitializingLock sets a temporary lock to indicate that initialization is in progress.
func (s *LeaderService) AcquireInitializingLock() (bool, error) { func (s *LeaderLock) AcquireInitializingLock() (bool, error) {
if !s.IsLeader() { if !s.IsLeader() {
return false, nil return false, nil
} }
@@ -110,7 +108,7 @@ func (s *LeaderService) AcquireInitializingLock() (bool, error) {
} }
// ReleaseInitializingLock removes the initialization lock. // ReleaseInitializingLock removes the initialization lock.
func (s *LeaderService) ReleaseInitializingLock() { func (s *LeaderLock) ReleaseInitializingLock() {
if !s.IsLeader() { if !s.IsLeader() {
return return
} }
@@ -121,7 +119,7 @@ func (s *LeaderService) ReleaseInitializingLock() {
} }
// WaitForInitializationToComplete waits until the initialization lock is released. // WaitForInitializationToComplete waits until the initialization lock is released.
func (s *LeaderService) WaitForInitializationToComplete() error { func (s *LeaderLock) WaitForInitializationToComplete() error {
if s.isSingleNode || s.IsLeader() { if s.isSingleNode || s.IsLeader() {
return nil return nil
} }
@@ -165,7 +163,7 @@ func (s *LeaderService) WaitForInitializationToComplete() error {
} }
// maintainLeadershipLoop is the background process that keeps trying to acquire or renew the lock. // maintainLeadershipLoop is the background process that keeps trying to acquire or renew the lock.
func (s *LeaderService) maintainLeadershipLoop() { func (s *LeaderLock) maintainLeadershipLoop() {
defer s.wg.Done() defer s.wg.Done()
ticker := time.NewTicker(leaderRenewalInterval) ticker := time.NewTicker(leaderRenewalInterval)
defer ticker.Stop() defer ticker.Stop()
@@ -185,7 +183,7 @@ func (s *LeaderService) maintainLeadershipLoop() {
} }
// tryToBeLeader is an idempotent function that attempts to acquire or renew the lock. // tryToBeLeader is an idempotent function that attempts to acquire or renew the lock.
func (s *LeaderService) tryToBeLeader() error { func (s *LeaderLock) tryToBeLeader() error {
if s.isLeader.Load() { if s.isLeader.Load() {
err := s.renewLock() err := s.renewLock()
if err != nil { if err != nil {
@@ -206,12 +204,12 @@ func (s *LeaderService) tryToBeLeader() error {
return nil return nil
} }
func (s *LeaderService) acquireLock() (bool, error) { func (s *LeaderLock) acquireLock() (bool, error) {
return s.store.SetNX(leaderLockKey, []byte(s.nodeID), leaderLockTTL) return s.store.SetNX(leaderLockKey, []byte(s.nodeID), leaderLockTTL)
} }
func (s *LeaderService) renewLock() error { func (s *LeaderLock) renewLock() error {
luaStore := s.store.(store.LuaScripter) luaStore := s.store.(LuaScripter)
ttlSeconds := int(leaderLockTTL.Seconds()) ttlSeconds := int(leaderLockTTL.Seconds())
res, err := luaStore.Eval(renewLockScript, []string{leaderLockKey}, s.nodeID, ttlSeconds) res, err := luaStore.Eval(renewLockScript, []string{leaderLockKey}, s.nodeID, ttlSeconds)
if err != nil { if err != nil {
@@ -223,8 +221,8 @@ func (s *LeaderService) renewLock() error {
return nil return nil
} }
func (s *LeaderService) releaseLock() { func (s *LeaderLock) releaseLock() {
luaStore := s.store.(store.LuaScripter) luaStore := s.store.(LuaScripter)
if _, err := luaStore.Eval(releaseLockScript, []string{leaderLockKey}, s.nodeID); err != nil { if _, err := luaStore.Eval(releaseLockScript, []string{leaderLockKey}, s.nodeID); err != nil {
logrus.WithError(err).Error("Failed to release leader lock on shutdown.") logrus.WithError(err).Error("Failed to release leader lock on shutdown.")
} else { } else {