79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
package storagex
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
// DriverFactory 驱动工厂接口
|
|
type DriverFactory interface {
|
|
Create(cfg Config) (Uploader, error)
|
|
}
|
|
|
|
// Registry 注册中心,单例模式管理所有上传通道
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
factories map[string]DriverFactory // 存储服务商工厂 (aliyun -> AliyunFactory)
|
|
clients map[string]Uploader // 缓存具体的客户端实例 (key = provider:accountID)
|
|
}
|
|
|
|
// 全局注册中心实例
|
|
var globalRegistry = &Registry{
|
|
factories: make(map[string]DriverFactory),
|
|
clients: make(map[string]Uploader),
|
|
}
|
|
|
|
// Register 注册服务商工厂
|
|
// 例如: Register("aliyun", &AliyunFactory{})
|
|
func Register(provider string, factory DriverFactory) {
|
|
globalRegistry.mu.Lock()
|
|
defer globalRegistry.mu.Unlock()
|
|
globalRegistry.factories[provider] = factory
|
|
}
|
|
|
|
// GetUploader 获取指定服务商和账号的上传器
|
|
// 如果该账号的客户端已存在则复用,不存在则创建
|
|
func GetUploader(provider, accountID string, cfg Config) (Uploader, error) {
|
|
key := fmt.Sprintf("%s:%s", provider, accountID)
|
|
|
|
// 1. 尝试从缓存获取 (读锁)
|
|
globalRegistry.mu.RLock()
|
|
client, ok := globalRegistry.clients[key]
|
|
globalRegistry.mu.RUnlock()
|
|
|
|
if ok {
|
|
return client, nil
|
|
}
|
|
|
|
// 2. 缓存未命中,需要创建 (写锁)
|
|
globalRegistry.mu.Lock()
|
|
defer globalRegistry.mu.Unlock()
|
|
|
|
// 双重检查锁,防止并发下重复创建
|
|
if client, ok := globalRegistry.clients[key]; ok {
|
|
return client, nil
|
|
}
|
|
|
|
factory, ok := globalRegistry.factories[provider]
|
|
if !ok {
|
|
return nil, fmt.Errorf("unknown provider: %s", provider)
|
|
}
|
|
|
|
// 创建新的 Uploader 实例
|
|
client, err := factory.Create(cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create uploader for %s: %w", provider, err)
|
|
}
|
|
|
|
// 存入缓存
|
|
globalRegistry.clients[key] = client
|
|
return client, nil
|
|
}
|
|
|
|
// Clear 主要用于测试,清空缓存
|
|
func Clear() {
|
|
globalRegistry.mu.Lock()
|
|
defer globalRegistry.mu.Unlock()
|
|
globalRegistry.clients = make(map[string]Uploader)
|
|
}
|