Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d2dec86b4 | |||
| 78969f5e6a | |||
| 2e4a0a89f1 | |||
| 3798b90447 | |||
| bcbe6eba78 | |||
| f85314f119 | |||
| ac6beab363 | |||
| 0a38df71c9 |
110
consul/consul.go
110
consul/consul.go
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/contrib/registry/consul/v2"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
@@ -14,30 +15,96 @@ import (
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
var initOnce sync.Once
|
||||
var (
|
||||
registry gsvc.Registry
|
||||
consulAddr string
|
||||
reconnectMutex sync.RWMutex
|
||||
reconnectDone chan struct{}
|
||||
)
|
||||
|
||||
// Init 初始化 Consul 注册中心(延迟初始化,首次调用时执行)
|
||||
func Init() {
|
||||
initOnce.Do(func() {
|
||||
consulAddr := g.Cfg().MustGet(context.Background(), "consul.address").String()
|
||||
if consulAddr == "" {
|
||||
g.Log().Warning(context.Background(), "⚠️ Consul 配置未找到,跳过初始化")
|
||||
// connectConsul 连接 Consul
|
||||
func connectConsul(ctx context.Context) error {
|
||||
reconnectMutex.Lock()
|
||||
defer reconnectMutex.Unlock()
|
||||
|
||||
var err error
|
||||
registry, err = consul.New(consul.WithAddress(consulAddr))
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "❌ Consul 连接失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
gsvc.SetRegistry(registry)
|
||||
gsel.SetBuilder(gsel.NewBuilderRoundRobin())
|
||||
g.Log().Infof(ctx, "✅ Consul 初始化成功: %s", consulAddr)
|
||||
|
||||
// 启动健康检查和自动重连
|
||||
go startHealthCheckAndReconnect()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// startHealthCheckAndReconnect 启动健康检查和自动重连
|
||||
func startHealthCheckAndReconnect() {
|
||||
if reconnectDone != nil {
|
||||
close(reconnectDone)
|
||||
}
|
||||
|
||||
reconnectDone = make(chan struct{})
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
// 检查服务发现是否正常工作
|
||||
if checkConsulHealth(ctx) {
|
||||
continue
|
||||
}
|
||||
|
||||
g.Log().Warning(ctx, "⚠️ Consul 连接异常,尝试重新连接...")
|
||||
if err := connectConsul(ctx); err != nil {
|
||||
g.Log().Errorf(ctx, "❌ Consul 重连失败: %v,5秒后重试...", err)
|
||||
}
|
||||
|
||||
case <-reconnectDone:
|
||||
g.Log().Info(ctx, "🛑 Consul 健康检查已停止")
|
||||
return
|
||||
}
|
||||
registry, err := consul.New(consul.WithAddress(consulAddr))
|
||||
if err != nil {
|
||||
g.Log().Errorf(context.Background(), "Consul 初始化失败: %v", err)
|
||||
return
|
||||
}
|
||||
gsvc.SetRegistry(registry)
|
||||
gsel.SetBuilder(gsel.NewBuilderRoundRobin())
|
||||
g.Log().Infof(context.Background(), "✅ Consul 初始化成功: %s", consulAddr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// checkConsulHealth 检查 Consul 健康状态
|
||||
func checkConsulHealth(ctx context.Context) bool {
|
||||
reconnectMutex.RLock()
|
||||
defer reconnectMutex.RUnlock()
|
||||
|
||||
if registry == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 尝试获取服务列表来检测连接是否正常
|
||||
services, err := registry.Search(ctx, gsvc.SearchInput{})
|
||||
if err != nil {
|
||||
g.Log().Debugf(ctx, "Consul 健康检查失败: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
g.Log().Debugf(ctx, "✅ Consul 健康检查通过,发现 %d 个服务", len(services))
|
||||
return true
|
||||
}
|
||||
|
||||
func init() {
|
||||
// 默认自动初始化(保持向后兼容)
|
||||
Init()
|
||||
consulAddr = g.Cfg().MustGet(context.Background(), "consul.address").String()
|
||||
if consulAddr == "" {
|
||||
g.Log().Warning(context.Background(), "⚠️ Consul 配置未找到,跳过初始化")
|
||||
return
|
||||
}
|
||||
if err := connectConsul(context.Background()); err != nil {
|
||||
g.Log().Errorf(context.Background(), "❌ Consul 初始化失败: %v", err)
|
||||
}
|
||||
}
|
||||
func getLocalIP() (string, error) {
|
||||
// 获取本机所有网络接口
|
||||
@@ -69,9 +136,14 @@ func getInstanceAddrByIp(ctx context.Context, ip string, services []gsvc.Service
|
||||
}
|
||||
func GetInstanceAddr(ctx context.Context, name string) (addr string, err error) {
|
||||
watch, err := gsvc.GetRegistry().Watch(ctx, name)
|
||||
if err != nil {
|
||||
err = errors.New("获取服务监听器失败")
|
||||
return
|
||||
}
|
||||
|
||||
service, err := watch.Proceed()
|
||||
if err != nil || service == nil {
|
||||
err = errors.New("获取customerService服务实例失败!")
|
||||
err = errors.New("获取服务实例失败")
|
||||
return
|
||||
}
|
||||
//优先使用客户端IP获取实例(前后端在同一台机器调试)
|
||||
|
||||
@@ -373,6 +373,7 @@ var (
|
||||
)
|
||||
|
||||
type Gfdb interface {
|
||||
Exec(ctx context.Context, sql string, args ...any) (sql.Result, error)
|
||||
Model(ctx context.Context, tableNameOrStruct ...any) *model
|
||||
Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) error
|
||||
}
|
||||
@@ -389,17 +390,45 @@ type dataBase struct {
|
||||
gdb.DB
|
||||
}
|
||||
|
||||
func DB(ctx context.Context) Gfdb {
|
||||
var dbName []string
|
||||
func GetTablePrefix(ctx context.Context) (prefix string, err error) {
|
||||
tenantId, config, err := checkSchemaConfig(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "[DB] checkSchemaConfig error: %v", err)
|
||||
return
|
||||
}
|
||||
if config {
|
||||
sprintf := fmt.Sprintf("database.%s%v.0.prefix", schemaPrefix, tenantId)
|
||||
prefix = g.Cfg().MustGet(ctx, sprintf).String()
|
||||
return
|
||||
}
|
||||
prefix = g.Cfg().MustGet(ctx, "database.default.0.prefix").String()
|
||||
return
|
||||
}
|
||||
|
||||
func checkSchemaConfig(ctx context.Context) (uint64, bool, error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "[DB] GetUserInfo error: %v", err)
|
||||
return nil
|
||||
return 0, false, err
|
||||
}
|
||||
|
||||
var schema = fmt.Sprintf("%s%v", schemaPrefix, user.TenantId)
|
||||
sprintf := fmt.Sprintf("database.%s", schema)
|
||||
if !g.Cfg().MustGet(ctx, sprintf).IsEmpty() {
|
||||
return user.TenantId, true, nil
|
||||
}
|
||||
return user.TenantId, false, nil
|
||||
}
|
||||
|
||||
func DB(ctx context.Context) Gfdb {
|
||||
tenantId, config, err := checkSchemaConfig(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "[DB] checkSchemaConfig error: %v", err)
|
||||
return nil
|
||||
}
|
||||
var schema = fmt.Sprintf("%s%v", schemaPrefix, tenantId)
|
||||
|
||||
var dbName []string
|
||||
if config {
|
||||
dbName = append(dbName, schema)
|
||||
} else {
|
||||
dbName = append(dbName, "default")
|
||||
@@ -418,29 +447,27 @@ func DB(ctx context.Context) Gfdb {
|
||||
}
|
||||
|
||||
func (d *dataBase) Model(ctx context.Context, tableNameOrStruct ...any) *model {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "[DB] GetUserInfo error: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
m := d.DB.Model(tableNameOrStruct...).Ctx(ctx)
|
||||
|
||||
var schema = fmt.Sprintf("%s%v", schemaPrefix, user.TenantId)
|
||||
sprintf := fmt.Sprintf("database.%s", schema)
|
||||
if !g.Cfg().MustGet(ctx, sprintf).IsEmpty() {
|
||||
tenantId, config, err := checkSchemaConfig(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "[DB] checkSchemaConfig error: %v", err)
|
||||
return nil
|
||||
}
|
||||
if config {
|
||||
// 创建按地区分库的配置
|
||||
shardingConfig := gdb.ShardingConfig{
|
||||
Schema: gdb.ShardingSchemaConfig{
|
||||
Enable: true, // 启用分库
|
||||
Prefix: schemaPrefix, // 分库前缀
|
||||
Rule: &RegionShardingRule{RegionMapping: user.TenantId}, // 自定义分库规则
|
||||
Enable: true, // 启用分库
|
||||
Prefix: schemaPrefix, // 分库前缀
|
||||
Rule: &RegionShardingRule{RegionMapping: tenantId}, // 自定义分库规则
|
||||
},
|
||||
}
|
||||
m.Sharding(shardingConfig).ShardingValue(user.TenantId)
|
||||
m.Sharding(shardingConfig).ShardingValue(tenantId)
|
||||
}
|
||||
|
||||
m.OmitNilData().OmitNilWhere().Hook(catchSQLHook())
|
||||
m.OmitNil().Hook(catchSQLHook())
|
||||
return &model{
|
||||
Model: m,
|
||||
}
|
||||
|
||||
@@ -86,7 +86,11 @@ func (d *BaseDataSource) Connect(ctx context.Context) error {
|
||||
defer d.mu.Unlock()
|
||||
|
||||
// 构建客户端
|
||||
d.client = ms.New(d.config.Host, ms.WithAPIKey(d.config.APIKey))
|
||||
host := d.config.Host
|
||||
if d.config.Port > 0 {
|
||||
host = fmt.Sprintf("%s:%d", d.config.Host, d.config.Port)
|
||||
}
|
||||
d.client = ms.New(host, ms.WithAPIKey(d.config.APIKey))
|
||||
|
||||
// 测试连接
|
||||
if err := d.healthCheck(ctx); err != nil {
|
||||
|
||||
@@ -71,22 +71,97 @@ func (m *meilisearchDB) getDataSource() (DataSource, error) {
|
||||
}
|
||||
|
||||
// getClient 获取 Meilisearch 客户端
|
||||
func (m *meilisearchDB) getClient() (interface{ Index(string) interface{} }, error) {
|
||||
func (m *meilisearchDB) getClient() (ms.ServiceManager, error) {
|
||||
source, err := m.getDataSource()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c, ok := source.Client().(interface{ Index(string) interface{} }); ok {
|
||||
if c, ok := source.Client().(ms.ServiceManager); ok {
|
||||
return c, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid client type")
|
||||
}
|
||||
|
||||
// indexInterface 辅助函数,获取index
|
||||
func indexInterface(indexName string, client interface{ Index(string) interface{} }) interface{} {
|
||||
func indexInterface(indexName string, client ms.ServiceManager) ms.IndexManager {
|
||||
return client.Index(indexName)
|
||||
}
|
||||
|
||||
// ensureIndexExists 确保索引存在,不存在则自动创建
|
||||
// 同时会检查并更新 filterable attributes 设置
|
||||
func (m *meilisearchDB) ensureIndexExists(client ms.ServiceManager, indexName string) error {
|
||||
// 使用 Index 方法获取索引(不存在时不会报错)
|
||||
idx := client.Index(indexName)
|
||||
|
||||
// 先获取索引信息,检查是否存在
|
||||
_, err := idx.FetchInfo()
|
||||
if err != nil {
|
||||
// 索引不存在,创建索引并等待完成
|
||||
task, err := client.CreateIndex(&ms.IndexConfig{
|
||||
Uid: indexName,
|
||||
PrimaryKey: "id",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 等待索引创建完成(最多等待10秒)
|
||||
if _, err = client.WaitForTask(task.TaskUID, 10*time.Second); err != nil {
|
||||
return fmt.Errorf("等待索引创建失败: %w", err)
|
||||
}
|
||||
// 重新获取索引
|
||||
idx = client.Index(indexName)
|
||||
}
|
||||
|
||||
// 检查并更新 filterable attributes
|
||||
settings, err := idx.GetSettings()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
requiredFilterable := []string{"tenantId", "isDeleted", "datasetId", "creator", "updater"}
|
||||
needUpdate := false
|
||||
|
||||
// 检查是否缺少必要的 filterable attributes
|
||||
existingFilterable := make(map[string]bool)
|
||||
for _, attr := range settings.FilterableAttributes {
|
||||
existingFilterable[attr] = true
|
||||
}
|
||||
|
||||
for _, attr := range requiredFilterable {
|
||||
if !existingFilterable[attr] {
|
||||
needUpdate = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if needUpdate {
|
||||
// 合并现有的 filterable attributes 和新增的
|
||||
allFilterable := append(settings.FilterableAttributes, requiredFilterable...)
|
||||
uniqueFilterable := make(map[string]bool)
|
||||
var finalFilterable []string
|
||||
for _, attr := range allFilterable {
|
||||
if !uniqueFilterable[attr] {
|
||||
uniqueFilterable[attr] = true
|
||||
finalFilterable = append(finalFilterable, attr)
|
||||
}
|
||||
}
|
||||
|
||||
updateSettings := &ms.Settings{
|
||||
FilterableAttributes: finalFilterable,
|
||||
}
|
||||
task, err := idx.UpdateSettings(updateSettings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 等待设置更新完成(最多等待10秒)
|
||||
if _, err = client.WaitForTask(task.TaskUID, 10*time.Second); err != nil {
|
||||
return fmt.Errorf("等待设置更新失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildSearchRequest 构建搜索请求
|
||||
func (m *meilisearchDB) buildSearchRequest(ctx context.Context, searchParams *SearchParams) (*ms.SearchRequest, error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
@@ -154,13 +229,18 @@ func (m *meilisearchDB) buildSearchRequest(ctx context.Context, searchParams *Se
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Search 搜索文档
|
||||
// Search 搜索文档(索引不存在时返回空结果)
|
||||
func (m *meilisearchDB) Search(ctx context.Context, searchParams *SearchParams, indexName string, result interface{}) (total int64, err error) {
|
||||
client, err := m.getClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 检查索引是否存在,不存在则返回空结果
|
||||
if _, err = client.GetIndex(indexName); err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// 构建搜索请求
|
||||
req, err := m.buildSearchRequest(ctx, searchParams)
|
||||
if err != nil {
|
||||
@@ -201,14 +281,7 @@ func (m *meilisearchDB) Search(ctx context.Context, searchParams *SearchParams,
|
||||
|
||||
// 执行搜索
|
||||
idx := indexInterface(indexName, client)
|
||||
var searchResp *ms.SearchResponse
|
||||
if i, ok := idx.(interface {
|
||||
Search(string, *ms.SearchRequest) (*ms.SearchResponse, error)
|
||||
}); ok {
|
||||
searchResp, err = i.Search(searchParams.Query, req)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support Search method")
|
||||
}
|
||||
searchResp, err := idx.Search(searchParams.Query, req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -261,13 +334,18 @@ func (m *meilisearchDB) Search(ctx context.Context, searchParams *SearchParams,
|
||||
return
|
||||
}
|
||||
|
||||
// Insert 插入文档
|
||||
// Insert 插入文档(自动创建索引)
|
||||
func (m *meilisearchDB) Insert(ctx context.Context, document interface{}, indexName string) (taskUID int64, err error) {
|
||||
c, err := m.getClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 确保索引存在
|
||||
if err = m.ensureIndexExists(c, indexName); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -308,14 +386,7 @@ func (m *meilisearchDB) Insert(ctx context.Context, document interface{}, indexN
|
||||
// 执行插入
|
||||
documents := []map[string]interface{}{docMap}
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
AddDocuments([]map[string]interface{}, interface{}) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.AddDocuments(documents, nil)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support AddDocuments method")
|
||||
}
|
||||
task, err := idx.AddDocuments(documents, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -329,13 +400,18 @@ func (m *meilisearchDB) Insert(ctx context.Context, document interface{}, indexN
|
||||
return task.TaskUID, nil
|
||||
}
|
||||
|
||||
// InsertMany 批量插入文档
|
||||
// InsertMany 批量插入文档(自动创建索引)
|
||||
func (m *meilisearchDB) InsertMany(ctx context.Context, documents []interface{}, indexName string) (taskUID int64, err error) {
|
||||
c, err := m.getClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 确保索引存在
|
||||
if err = m.ensureIndexExists(c, indexName); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -379,14 +455,7 @@ func (m *meilisearchDB) InsertMany(ctx context.Context, documents []interface{},
|
||||
|
||||
// 执行批量插入
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
AddDocuments([]map[string]interface{}, interface{}) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.AddDocuments(docs, nil)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support AddDocuments method")
|
||||
}
|
||||
task, err := idx.AddDocuments(docs, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -426,14 +495,7 @@ func (m *meilisearchDB) Update(ctx context.Context, document interface{}, indexN
|
||||
// 执行更新
|
||||
documents := []map[string]interface{}{docMap}
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
UpdateDocuments([]map[string]interface{}, interface{}) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.UpdateDocuments(documents, nil)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support UpdateDocuments method")
|
||||
}
|
||||
task, err := idx.UpdateDocuments(documents, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -456,14 +518,7 @@ func (m *meilisearchDB) Delete(ctx context.Context, id string, indexName string)
|
||||
|
||||
// 执行删除
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
DeleteDocument(string) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.DeleteDocument(id)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support DeleteDocument method")
|
||||
}
|
||||
task, err := idx.DeleteDocument(id, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -504,14 +559,7 @@ func (m *meilisearchDB) DeleteSoft(ctx context.Context, id string, indexName str
|
||||
// 执行更新
|
||||
documents := []map[string]interface{}{updateMap}
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
UpdateDocuments([]map[string]interface{}, interface{}) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.UpdateDocuments(documents, nil)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support UpdateDocuments method")
|
||||
}
|
||||
task, err := idx.UpdateDocuments(documents, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -552,13 +600,7 @@ func (m *meilisearchDB) Get(ctx context.Context, id string, indexName string, re
|
||||
// 执行查询
|
||||
var doc map[string]interface{}
|
||||
idx := indexInterface(indexName, c)
|
||||
if i, ok := idx.(interface {
|
||||
GetDocument(string, interface{}) error
|
||||
}); ok {
|
||||
err = i.GetDocument(id, &doc)
|
||||
} else {
|
||||
return fmt.Errorf("index does not support GetDocument method")
|
||||
}
|
||||
err = idx.GetDocument(id, nil, &doc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -600,122 +642,7 @@ func (m *meilisearchDB) cleanCache(ctx context.Context, indexName string, tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateIndex 创建索引
|
||||
func (m *meilisearchDB) CreateIndex(ctx context.Context, indexConfig *IndexConfig) (taskUID int64, err error) {
|
||||
client, err := m.getClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
indexSettings := &ms.IndexConfig{
|
||||
Uid: indexConfig.UID,
|
||||
PrimaryKey: indexConfig.PrimaryKey,
|
||||
}
|
||||
|
||||
if c, ok := client.(interface {
|
||||
CreateIndex(*ms.IndexConfig) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err := c.CreateIndex(indexSettings)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return task.TaskUID, nil
|
||||
}
|
||||
return 0, fmt.Errorf("client does not support CreateIndex")
|
||||
}
|
||||
|
||||
// DeleteIndex 删除索引
|
||||
func (m *meilisearchDB) DeleteIndex(ctx context.Context, indexName string) (err error) {
|
||||
client, err := m.getClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c, ok := client.(interface{ DeleteIndex(string) error }); ok {
|
||||
return c.DeleteIndex(indexName)
|
||||
}
|
||||
return fmt.Errorf("client does not support DeleteIndex")
|
||||
}
|
||||
|
||||
// GetIndex 获取索引信息
|
||||
func (m *meilisearchDB) GetIndex(ctx context.Context, indexName string) (interface{}, error) {
|
||||
client, err := m.getClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c, ok := client.(interface {
|
||||
GetIndex(string) (interface{}, error)
|
||||
}); ok {
|
||||
return c.GetIndex(indexName)
|
||||
}
|
||||
return nil, fmt.Errorf("client does not support GetIndex")
|
||||
}
|
||||
|
||||
// GetIndexes 获取所有索引
|
||||
func (m *meilisearchDB) GetIndexes(ctx context.Context) (interface{}, error) {
|
||||
client, err := m.getClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c, ok := client.(interface {
|
||||
GetIndexes(interface{}) (interface{}, error)
|
||||
}); ok {
|
||||
return c.GetIndexes(nil)
|
||||
}
|
||||
return nil, fmt.Errorf("client does not support GetIndexes")
|
||||
}
|
||||
|
||||
// UpdateSettings 更新索引设置
|
||||
func (m *meilisearchDB) UpdateSettings(ctx context.Context, indexName string, settings *ms.Settings) (taskUID int64, err error) {
|
||||
c, err := m.getClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
idx := indexInterface(indexName, c)
|
||||
var task *ms.TaskInfo
|
||||
if i, ok := idx.(interface {
|
||||
UpdateSettings(*ms.Settings) (*ms.TaskInfo, error)
|
||||
}); ok {
|
||||
task, err = i.UpdateSettings(settings)
|
||||
} else {
|
||||
return 0, fmt.Errorf("index does not support UpdateSettings method")
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return task.TaskUID, nil
|
||||
}
|
||||
|
||||
// GetSettings 获取索引设置
|
||||
func (m *meilisearchDB) GetSettings(ctx context.Context, indexName string) (*ms.Settings, error) {
|
||||
c, err := m.getClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idx := indexInterface(indexName, c)
|
||||
var settings *ms.Settings
|
||||
if i, ok := idx.(interface{ GetSettings() (*ms.Settings, error) }); ok {
|
||||
settings, err = i.GetSettings()
|
||||
} else {
|
||||
return nil, fmt.Errorf("index does not support GetSettings method")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
// GetClient 获取原始客户端(用于高级操作)
|
||||
func (m *meilisearchDB) GetClient() (interface{ Index(string) interface{} }, error) {
|
||||
func (m *meilisearchDB) GetClient() (ms.ServiceManager, error) {
|
||||
return m.getClient()
|
||||
}
|
||||
|
||||
// BuildUpdateData 构建更新数据
|
||||
func BuildUpdateData(ctx context.Context, req interface{}) (map[string]interface{}, error) {
|
||||
return gconv.Map(req), nil
|
||||
}
|
||||
|
||||
51
go.mod
51
go.mod
@@ -6,15 +6,27 @@ require (
|
||||
github.com/alibaba/sentinel-golang v1.0.4
|
||||
github.com/bwmarrin/snowflake v0.3.0
|
||||
github.com/cloudwego/eino v0.7.26
|
||||
github.com/cloudwego/eino-ext/components/document/loader/url v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/document/parser/docx v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/document/parser/xlsx v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/semantic v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/embedding/ark v0.1.1
|
||||
github.com/cloudwego/eino-ext/components/embedding/dashscope v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260323112355-f061db7e8419
|
||||
github.com/go-ego/gse v1.0.2
|
||||
github.com/gogf/gf/contrib/registry/consul/v2 v2.9.5
|
||||
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.9.5
|
||||
github.com/gogf/gf/v2 v2.9.5
|
||||
github.com/golang/glog v1.2.5
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/meilisearch/meilisearch-go v0.36.1
|
||||
github.com/minio/minio-go/v7 v7.0.97
|
||||
github.com/nats-io/nats.go v1.48.0
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
github.com/rabbitmq/amqp091-go v1.10.0
|
||||
github.com/rpcxio/rpcx-consul v0.1.1
|
||||
github.com/smallnest/rpcx v1.9.1
|
||||
github.com/tiger1103/gfast-token v1.0.10
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.0
|
||||
@@ -24,11 +36,15 @@ require (
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.8.1 // indirect
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
|
||||
github.com/akutz/memconn v0.1.0 // indirect
|
||||
github.com/alitto/pond v1.9.2 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/apache/thrift v0.21.0 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
@@ -41,14 +57,19 @@ require (
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20241224063832-9fbcc0e56c28 // indirect
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.14 // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.2.0 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/dgryski/go-jump v0.0.0-20211018200510-ba001c3ffce0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dslipak/pdf v0.0.2 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edwingeng/doublejump v1.0.1 // indirect
|
||||
github.com/eino-contrib/docx2md v0.0.1 // indirect
|
||||
github.com/eino-contrib/jsonschema v1.0.3 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/evanphx/json-patch v0.5.2 // indirect
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
@@ -58,16 +79,17 @@ require (
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/go-ping/ping v1.2.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/godzie44/go-uring v0.0.0-20220926161041-69611e8b13d5 // indirect
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
|
||||
github.com/golang/glog v1.2.5 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/flatbuffers v1.12.1 // indirect
|
||||
github.com/google/pprof v0.0.0-20250128161936-077ca0a936bf // indirect
|
||||
github.com/goph/emperror v0.17.2 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grandcat/zeroconf v1.0.0 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
@@ -81,18 +103,24 @@ require (
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/juju/ratelimit v1.0.2 // indirect
|
||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||
github.com/kavu/go_reuseport v1.5.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/klauspost/crc32 v1.3.0 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.4 // indirect
|
||||
github.com/libp2p/go-sockaddr v0.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/meguminnnnnnnnn/go-openai v0.1.1 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 // indirect
|
||||
github.com/miekg/dns v1.1.63 // indirect
|
||||
github.com/minio/crc64nvme v1.1.0 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
@@ -100,6 +128,7 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/nats-io/nkeys v0.4.11 // indirect
|
||||
github.com/nats-io/nuid v1.0.1 // indirect
|
||||
github.com/nikolalohinski/gonja v1.5.3 // indirect
|
||||
@@ -107,7 +136,7 @@ require (
|
||||
github.com/olekukonko/ll v0.0.9 // indirect
|
||||
github.com/olekukonko/tablewriter v1.1.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
@@ -115,8 +144,13 @@ require (
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/quic-go/quic-go v0.49.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/redis/go-redis/v9 v9.12.1 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rpcxio/libkv v0.5.1 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/rubyist/circuitbreaker v2.2.1+incompatible // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.21.6 // indirect
|
||||
@@ -124,6 +158,7 @@ require (
|
||||
github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect
|
||||
github.com/smallnest/quick v0.2.0 // indirect
|
||||
github.com/smallnest/rsocket v0.0.0-20241130031020-4a72eb6ff62a // indirect
|
||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
@@ -132,13 +167,19 @@ require (
|
||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/valyala/fastrand v1.1.0 // indirect
|
||||
github.com/vcaesar/cedar v0.30.0 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 // indirect
|
||||
github.com/volcengine/volcengine-go-sdk v1.0.181 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // 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
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
||||
github.com/xuri/excelize/v2 v2.9.0 // indirect
|
||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
||||
github.com/yargevad/filepathx v1.0.0 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
@@ -149,9 +190,9 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
golang.org/x/arch v0.11.0 // indirect
|
||||
golang.org/x/arch v0.15.0 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
|
||||
155
go.sum
155
go.sum
@@ -5,6 +5,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
@@ -25,20 +27,26 @@ github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
|
||||
github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE=
|
||||
github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.3.6/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
@@ -60,6 +68,8 @@ github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgIS
|
||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/mockey v1.3.0 h1:ONLRdvhqmCfr9rTasUB8ZKCfvbdD2tohOg4u+4Q/ed0=
|
||||
github.com/bytedance/mockey v1.3.0/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY=
|
||||
github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w=
|
||||
github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
@@ -86,6 +96,28 @@ github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/cloudwego/eino v0.7.26 h1:FD8xnhd8WyV495eJs0Rka8aHnknqj/ljq3ZbwGH/SiQ=
|
||||
github.com/cloudwego/eino v0.7.26/go.mod h1:nA8Vacmuqv3pqKBQbTWENBLQ8MmGmPt/WqiyLeB8ohQ=
|
||||
github.com/cloudwego/eino-ext/components/document/loader/url v0.0.0-20260323112355-f061db7e8419 h1:dMr31rw5pjZMKMPEvNvpy+1RI3HnqVUWmk2abNkb+yM=
|
||||
github.com/cloudwego/eino-ext/components/document/loader/url v0.0.0-20260323112355-f061db7e8419/go.mod h1:/IeSk52Hhym5AUjCs3ESTF5Nb0RLYFWW8llSpWuc/JA=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/docx v0.0.0-20260323112355-f061db7e8419 h1:NkEyzkMvYj1imCNclbL0OeesosinmbU10uW+ZlC0vtA=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/docx v0.0.0-20260323112355-f061db7e8419/go.mod h1:7Nfu+tf9OkdI8Fy5VRi9Xap13OGVV8SXlpj+GHbaWQ8=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20241224063832-9fbcc0e56c28 h1:Z1cWrlqxdc5IuPV1UcqoW2BGlFr7IQJHGwn7I3Tax0A=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20241224063832-9fbcc0e56c28/go.mod h1:e+Hf9OyKXFxAoCTF3thTm2Sz8KDfJ/iiEOHOmADpxRI=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20260323112355-f061db7e8419 h1:kw67tDHJ8vBI4eaB2Gb11kcLFrnQuCX8yFF9onU7CEQ=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20260323112355-f061db7e8419/go.mod h1:kHC3xkGM/gv3IHpOk33p75BfBaEIYATOs2XmYFKffcs=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/xlsx v0.0.0-20260323112355-f061db7e8419 h1:iCibCaUZNr7BFuqSI2U+fH1MUZCYS5lFjIb/Fytj3V8=
|
||||
github.com/cloudwego/eino-ext/components/document/parser/xlsx v0.0.0-20260323112355-f061db7e8419/go.mod h1:7aF6WcOvowbYaXUnDY+awRZJ29LHP+4oWhS5ogH36bE=
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260323112355-f061db7e8419 h1:y8XB6u0Z/AyNww1BHFZqBCzLmxnBUFtQmqaWT/YH4q8=
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive v0.0.0-20260323112355-f061db7e8419/go.mod h1:9R0RQrQSpg1JaNnRtw7+RfRAAv0HgdE348YnrlZ6coo=
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/semantic v0.0.0-20260323112355-f061db7e8419 h1:XsvQmwMKMD/w/YIPK0Y9pfBv0UH6rJ5ZiedUuZiA9Vo=
|
||||
github.com/cloudwego/eino-ext/components/document/transformer/splitter/semantic v0.0.0-20260323112355-f061db7e8419/go.mod h1:Ov33JMUewdOoUgJbYNJt3qL7KQDVHYpoVBCjJXsz8sw=
|
||||
github.com/cloudwego/eino-ext/components/embedding/ark v0.1.1 h1:PM/+XAvJtrBqFlBY15ws0pb0+92XKHQv0ei3M7PIJcQ=
|
||||
github.com/cloudwego/eino-ext/components/embedding/ark v0.1.1/go.mod h1:6O6x0fHfM3uCLr3lX1DnB/my7fC3WRUA5hpkCkrkZrg=
|
||||
github.com/cloudwego/eino-ext/components/embedding/dashscope v0.0.0-20260323112355-f061db7e8419 h1:gGnohcgEaHqp5V826Ay0H3fi4TpK8ReWlUPePAnzvA4=
|
||||
github.com/cloudwego/eino-ext/components/embedding/dashscope v0.0.0-20260323112355-f061db7e8419/go.mod h1:ekJmA+GLD9vJyZNeODZDBFMiJ92Suy6nF0OY42X3sao=
|
||||
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260323112355-f061db7e8419 h1:eM29lyMShtFZNoAhE5g96+zHg9PBLckRyd2HtVeeY4E=
|
||||
github.com/cloudwego/eino-ext/components/embedding/openai v0.0.0-20260323112355-f061db7e8419/go.mod h1:SajSFFRIXJXIbxadAAlSUIS5KTY8R/jzJg9RNSOXCCI=
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.14 h1:yOZII6VYaL00CVZYba+HUixFygsW0Xz/1QjQ5htj1Ls=
|
||||
github.com/cloudwego/eino-ext/libs/acl/openai v0.1.14/go.mod h1:1xMQZ8eE11pkEoTAEy8UlaAY817qGVMvjpDPGSIO3Ns=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
@@ -110,6 +142,8 @@ github.com/dgryski/go-jump v0.0.0-20211018200510-ba001c3ffce0 h1:0wH6nO9QEa02Qx8
|
||||
github.com/dgryski/go-jump v0.0.0-20211018200510-ba001c3ffce0/go.mod h1:4hKCXuwrJoYvHZxJ86+bRVTOMyJ0Ej+RqfSm8mHi6KA=
|
||||
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/dslipak/pdf v0.0.2 h1:djAvcM5neg9Ush+zR6QXB+VMJzR6TdnX766HPIg1JmI=
|
||||
github.com/dslipak/pdf v0.0.2/go.mod h1:2L3SnkI9cQwnAS9gfPz2iUoLC0rUZwbucpbKi5R1mUo=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@@ -120,6 +154,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/edwingeng/doublejump v1.0.1 h1:wJ6QgNyyF23Of9vw+ThbwJ/obe9KdxaWEg/Brpv5S1o=
|
||||
github.com/edwingeng/doublejump v1.0.1/go.mod h1:ykMWX8JWePtMtk2OGjNE9kwtgpI+SF2FNIyXV4gS36k=
|
||||
github.com/eino-contrib/docx2md v0.0.1 h1:Clz0sF8jiQRYAIZAUTuTAjh0vF/1KqHQqsMha1ZX4q4=
|
||||
github.com/eino-contrib/docx2md v0.0.1/go.mod h1:b1dupA9cF5yExHjVMCcP6feyE6mwZjsY7Cc9ESO5Y14=
|
||||
github.com/eino-contrib/jsonschema v1.0.3 h1:2Kfsm1xlMV0ssY2nuxshS4AwbLFuqmPmzIjLVJ1Fsp0=
|
||||
github.com/eino-contrib/jsonschema v1.0.3/go.mod h1:cpnX4SyKjWjGC7iN2EbhxaTdLqGjCi0e9DxpLYxddD4=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
@@ -129,10 +165,13 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
@@ -141,12 +180,15 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
github.com/go-ego/gse v1.0.2 h1:+27lYFPhQEhA9igtdOsJPRKYL/k3TwYsxBF5jr6KFv4=
|
||||
github.com/go-ego/gse v1.0.2/go.mod h1:Fy35G+q7VV7Et1zIKO8o/sW1kkugV3znXap/lF/11zc=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
@@ -164,6 +206,7 @@ github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ping/ping v1.2.0 h1:vsJ8slZBZAXNCK4dPcI2PEE9eM9n9RbXbGouVQ/Y4yQ=
|
||||
github.com/go-ping/ping v1.2.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
||||
github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
@@ -225,6 +268,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -235,6 +279,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18=
|
||||
@@ -243,6 +288,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
@@ -258,9 +305,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/api v1.8.1/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk=
|
||||
github.com/hashicorp/consul/api v1.26.1 h1:5oSXOO5fboPZeW5SN+TdGFP/BILDgBm19OrPZ/pICIM=
|
||||
github.com/hashicorp/consul/api v1.26.1/go.mod h1:B4sQTeaSO16NtynqrAdwOlahJ7IUDZM9cj2420xYL8A=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.7.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
|
||||
github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU=
|
||||
github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -270,9 +319,12 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
@@ -300,22 +352,31 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM=
|
||||
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
@@ -353,6 +414,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
@@ -366,11 +428,12 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
@@ -378,6 +441,7 @@ github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stg
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
@@ -387,10 +451,14 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/meguminnnnnnnnn/go-openai v0.1.1 h1:u/IMMgrj/d617Dh/8BKAwlcstD74ynOJzCtVl+y8xAs=
|
||||
github.com/meguminnnnnnnnn/go-openai v0.1.1/go.mod h1:qs96ysDmxhE4BZoU45I43zcyfnaYxU3X+aRzLko/htY=
|
||||
github.com/meilisearch/meilisearch-go v0.36.1 h1:mJTCJE5g7tRvaqKco6DfqOuJEjX+rRltDEnkEC02Y0M=
|
||||
github.com/meilisearch/meilisearch-go v0.36.1/go.mod h1:hWcR0MuWLSzHfbz9GGzIr3s9rnXLm1jqkmHkJPbUSvM=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
@@ -413,6 +481,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -422,6 +491,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
@@ -438,6 +509,7 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c=
|
||||
github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
||||
@@ -452,10 +524,15 @@ github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCz
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
@@ -472,8 +549,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
|
||||
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/peterbourgon/g2s v0.0.0-20140925154142-ec76db4c1ac1 h1:5Dl+ADmsGerAqHwWzyLqkNaUBQ+48DQwfDCaW1gHAQM=
|
||||
github.com/peterbourgon/g2s v0.0.0-20140925154142-ec76db4c1ac1/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg=
|
||||
@@ -529,16 +606,27 @@ github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULM
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg=
|
||||
github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
|
||||
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ=
|
||||
github.com/rpcxio/libkv v0.5.1 h1:M0/QqwTcdXz7us0NB+2i8Kq5+wikTm7zZ4Hyb/jNgME=
|
||||
github.com/rpcxio/libkv v0.5.1/go.mod h1:zHGgtLr3cFhGtbalum0BrMPOjhFZFJXCKiws/25ewls=
|
||||
github.com/rpcxio/rpcx-consul v0.1.1 h1:z/IHpIytgChEuHndWlpo4BY0V0mVBSg/XsKsc54f0iU=
|
||||
github.com/rpcxio/rpcx-consul v0.1.1/go.mod h1:N4SjBS0M9HpVdq3CIIXm/MwWv6euXQ39ybhfH2iTh1c=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
@@ -548,6 +636,7 @@ github.com/rubyist/circuitbreaker v2.2.1+incompatible/go.mod h1:Ycs3JgJADPuzJDwf
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20201211165307-7117e9ea2414/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shirou/gopsutil/v3 v3.21.6 h1:vU7jrp1Ic/2sHB7w6UNs7MIkn7ebVtTb5D9j45o9VYE=
|
||||
@@ -566,8 +655,8 @@ github.com/smallnest/rpcx v1.9.1 h1:fGw+qMcDRPm7Ei9fdEfqteYY6qQqgVsoyxoUw6hEXy0=
|
||||
github.com/smallnest/rpcx v1.9.1/go.mod h1:owr4mDCReTn+dy9m5ilof0mBivFBeK0XrkYfZYdDGb4=
|
||||
github.com/smallnest/rsocket v0.0.0-20241130031020-4a72eb6ff62a h1:GI6kCNC5AVFbKA6ZKbVd4r+fk+Z7XZCRQm9LURZY4t4=
|
||||
github.com/smallnest/rsocket v0.0.0-20241130031020-4a72eb6ff62a/go.mod h1:VJeIKKrDEzT4ZNVe87JN9uRLw1XLp/ZnnE9PfsyJ1jY=
|
||||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||
github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
|
||||
github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||
@@ -583,6 +672,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
@@ -590,13 +680,13 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
|
||||
@@ -621,10 +711,18 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8=
|
||||
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
|
||||
github.com/vcaesar/cedar v0.30.0 h1:9fSDpM7FTjjUdPiBUUa0MWYMRGSEcqgFXvppZcZ4d7Y=
|
||||
github.com/vcaesar/cedar v0.30.0/go.mod h1:lyuGvALuZZDPNXwpzv/9LyxW+8Y6faN7zauFezNsnik=
|
||||
github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
|
||||
github.com/vcaesar/tt v0.20.1/go.mod h1:cH2+AwGAJm19Wa6xvEa+0r+sXDJBT0QgNQey6mwqLeU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 h1:anOslb2Qp6ywnsbyq9jqR0ljuO63kg9PY+4OehIk5R8=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
|
||||
github.com/volcengine/volcengine-go-sdk v1.0.181 h1:/3PB4M1N4fjMqiSKTJwX43EZ5Nn1HUOtQrSCk+22+wI=
|
||||
github.com/volcengine/volcengine-go-sdk v1.0.181/go.mod h1:gfEDc1s7SYaGoY+WH2dRrS3qiuDJMkwqyfXWCa7+7oA=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
|
||||
@@ -640,6 +738,12 @@ github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZ
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||
github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE=
|
||||
github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE=
|
||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
|
||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc=
|
||||
@@ -660,18 +764,22 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
|
||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
|
||||
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
|
||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
|
||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
@@ -689,8 +797,8 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
|
||||
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
|
||||
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -704,8 +812,10 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae h1:COZdc9Ut6wLq7MO9GIYxfZl4n4ScmgqQLoHocKXrxco=
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -737,14 +847,18 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -770,18 +884,24 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -789,10 +909,13 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -802,11 +925,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -815,6 +940,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -838,6 +964,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
@@ -906,10 +1033,12 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/redis"
|
||||
"gitea.com/red-future/common/utils"
|
||||
"github.com/alibaba/sentinel-golang/api"
|
||||
"github.com/alibaba/sentinel-golang/core/circuitbreaker"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
@@ -1081,7 +1081,7 @@ func syncCircuitBreakerStateToDistributed(ctx context.Context, resourceName, sta
|
||||
}
|
||||
|
||||
// 使用common/redis中的Lock方法获取分布式锁
|
||||
success, err := redis.Lock(ctx, lockKey, lockTimeout, func(ctx context.Context) error {
|
||||
success, err := utils.Lock(ctx, lockKey, lockTimeout, func(ctx context.Context) error {
|
||||
// 设置熔断器状态
|
||||
_, err := redisClient.Do(ctx, "SETEX", stateKey, ttl, state)
|
||||
if err != nil {
|
||||
@@ -1335,7 +1335,7 @@ func resetSingleResource(r *ghttp.Request, resourceName string) error {
|
||||
if redisClient != nil {
|
||||
lockKey := "circuit_breaker:" + resourceName + ":lock"
|
||||
// 使用较短的锁超时时间
|
||||
success, err := redis.Lock(r.GetCtx(), lockKey, int64(3), func(ctx context.Context) error {
|
||||
success, err := utils.Lock(r.GetCtx(), lockKey, int64(3), func(ctx context.Context) error {
|
||||
_, err := redisClient.Del(ctx, "circuit_breaker:"+resourceName+":state")
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "清除分布式熔断状态失败: %s, error: %v", resourceName, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/utils"
|
||||
@@ -53,11 +54,11 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func UploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl string, err error) {
|
||||
func UploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl string, fileName string, fileFormat string, err error) {
|
||||
return uploadFile(ctx, fileHeader)
|
||||
}
|
||||
|
||||
func uploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl string, err error) {
|
||||
func uploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl string, fileName string, fileFormat string, err error) {
|
||||
bucketName, err := utils.GetBucketName(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取桶名称失败: %v", err)
|
||||
@@ -124,5 +125,5 @@ func uploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl st
|
||||
glog.Errorf(ctx, "上传图片失败: %v", err)
|
||||
return
|
||||
}
|
||||
return objectName, err
|
||||
return objectName, fileHeader.Filename, strings.ReplaceAll(fileExt, ".", ""), err
|
||||
}
|
||||
|
||||
8
rag/eino/consts.go
Normal file
8
rag/eino/consts.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package eino
|
||||
|
||||
const (
|
||||
providerArk = "ark"
|
||||
providerOpenai = "openai"
|
||||
providerQianfan = "qianfan"
|
||||
providerDashscope = "dashscope"
|
||||
)
|
||||
51
rag/eino/document_loader.go
Normal file
51
rag/eino/document_loader.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package eino
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.com/red-future/common/utils"
|
||||
"github.com/cloudwego/eino-ext/components/document/loader/url"
|
||||
"github.com/cloudwego/eino-ext/components/document/parser/docx"
|
||||
"github.com/cloudwego/eino-ext/components/document/parser/pdf"
|
||||
"github.com/cloudwego/eino-ext/components/document/parser/xlsx"
|
||||
"github.com/cloudwego/eino/components/document"
|
||||
"github.com/cloudwego/eino/components/document/parser"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
)
|
||||
|
||||
// LoadDocument 业务函数:加载文件
|
||||
func LoadDocument(ctx context.Context, filePath, fileFormat string) (docs []*schema.Document, err error) {
|
||||
p, err := docsParser(ctx, fileFormat)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
loader, err := url.NewLoader(ctx, &url.LoaderConfig{
|
||||
Parser: p,
|
||||
})
|
||||
imageUrl, err := utils.GetFileAddressPrefix(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
docs, err = loader.Load(context.Background(), document.Source{
|
||||
URI: fmt.Sprintf("%s%s", imageUrl, filePath),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func docsParser(ctx context.Context, fileFormat string) (p parser.Parser, err error) {
|
||||
switch fileFormat {
|
||||
case "docx":
|
||||
p, err = docx.NewDocxParser(ctx, &docx.Config{
|
||||
ToSections: true,
|
||||
IncludeHeaders: true,
|
||||
IncludeFooters: true,
|
||||
IncludeTables: true,
|
||||
})
|
||||
case "pdf":
|
||||
p, err = pdf.NewPDFParser(ctx, &pdf.Config{})
|
||||
case "xlsx":
|
||||
p, err = xlsx.NewXlsxParser(ctx, &xlsx.Config{})
|
||||
}
|
||||
return
|
||||
}
|
||||
64
rag/eino/document_semantic.go
Normal file
64
rag/eino/document_semantic.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package eino
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cloudwego/eino-ext/components/document/transformer/splitter/recursive"
|
||||
"github.com/cloudwego/eino-ext/components/document/transformer/splitter/semantic"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// SemanticSplitDocument 语义分割文档
|
||||
func SemanticSplitDocument(ctx context.Context, docs []*schema.Document) (res []*schema.Document, err error) {
|
||||
// 默认分隔符(支持中英文)
|
||||
separators := []string{"\n\n", "\n", "。", "!", "?", ";", ".", "!", "?", ";"}
|
||||
// 读取配置,使用合理的默认值
|
||||
bufferSize := g.Cfg().MustGet(ctx, "eino.splitter.bufferSize").Int()
|
||||
minChunkSize := g.Cfg().MustGet(ctx, "eino.splitter.minChunkSize").Int()
|
||||
percentile := g.Cfg().MustGet(ctx, "eino.splitter.percentile").Float64()
|
||||
batchSize := g.Cfg().MustGet(ctx, "eino.splitter.batchSize").Int()
|
||||
if batchSize <= 0 {
|
||||
batchSize = 10 // doubao-embedding-vision 限制每批最多 10 个
|
||||
}
|
||||
|
||||
// 使用批量包装器
|
||||
var batchEmbedder *BatchEmbedder
|
||||
provider := g.Cfg().MustGet(ctx, "eino.embedding.provider").String()
|
||||
switch provider {
|
||||
case providerArk:
|
||||
batchEmbedder = NewBatchEmbedder(EmbedderArk, batchSize)
|
||||
case providerOpenai:
|
||||
batchEmbedder = NewBatchEmbedder(EmbedderOpenAI, batchSize)
|
||||
case providerDashscope:
|
||||
batchEmbedder = NewBatchEmbedder(EmbedderDashscope, batchSize)
|
||||
}
|
||||
|
||||
splitter, err := semantic.NewSplitter(ctx, &semantic.Config{
|
||||
Embedding: batchEmbedder,
|
||||
BufferSize: bufferSize,
|
||||
MinChunkSize: minChunkSize,
|
||||
Percentile: percentile,
|
||||
Separators: separators,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return splitter.Transform(ctx, docs)
|
||||
}
|
||||
|
||||
// RecursiveSplitDocument 递归分割文档
|
||||
func RecursiveSplitDocument(ctx context.Context, docs []*schema.Document) (res []*schema.Document, err error) {
|
||||
// 默认分隔符(支持中英文)
|
||||
separators := []string{"\n\n", "\n", "。", "!", "?", ";", ".", "!", "?", ";"}
|
||||
splitter, err := recursive.NewSplitter(ctx, &recursive.Config{
|
||||
ChunkSize: 512,
|
||||
OverlapSize: 100,
|
||||
KeepType: recursive.KeepTypeNone,
|
||||
Separators: separators,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return splitter.Transform(ctx, docs)
|
||||
}
|
||||
69
rag/eino/embedding.go
Normal file
69
rag/eino/embedding.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package eino
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudwego/eino-ext/components/embedding/ark"
|
||||
"github.com/cloudwego/eino-ext/components/embedding/dashscope"
|
||||
"github.com/cloudwego/eino-ext/components/embedding/openai"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// 全局只初始化一次
|
||||
var (
|
||||
EmbedderArk *ark.Embedder
|
||||
EmbedderDashscope *dashscope.Embedder
|
||||
EmbedderOpenAI *openai.Embedder
|
||||
)
|
||||
|
||||
func init() {
|
||||
ctx := context.Background()
|
||||
if !g.Cfg().MustGet(ctx, "eino.embedding").IsEmpty() {
|
||||
var err error
|
||||
provider := g.Cfg().MustGet(ctx, "eino.embedding.provider").String()
|
||||
switch provider {
|
||||
case providerArk:
|
||||
cfg := &ark.EmbeddingConfig{
|
||||
APIKey: g.Cfg().MustGet(ctx, "eino.embedding.apiKey").String(),
|
||||
Model: g.Cfg().MustGet(ctx, "eino.embedding.model").String(),
|
||||
}
|
||||
if apiType := g.Cfg().MustGet(ctx, "eino.embedding.apiType").String(); apiType != "" {
|
||||
apiTypeVal := ark.APIType(apiType)
|
||||
cfg.APIType = &apiTypeVal
|
||||
}
|
||||
EmbedderArk, err = ark.NewEmbedder(ctx, cfg)
|
||||
case providerOpenai:
|
||||
chatModelConfig := &openai.EmbeddingConfig{
|
||||
APIKey: g.Cfg().MustGet(ctx, "eino.embedding.apiKey").String(),
|
||||
Model: g.Cfg().MustGet(ctx, "eino.embedding.model").String(),
|
||||
}
|
||||
EmbedderOpenAI, err = openai.NewEmbedder(ctx, chatModelConfig)
|
||||
case providerDashscope:
|
||||
cfg := &dashscope.EmbeddingConfig{
|
||||
APIKey: g.Cfg().MustGet(ctx, "eino.embedding.apiKey").String(),
|
||||
Model: g.Cfg().MustGet(ctx, "eino.embedding.model").String(),
|
||||
}
|
||||
EmbedderDashscope, err = dashscope.NewEmbedder(ctx, cfg)
|
||||
}
|
||||
if err != nil {
|
||||
glog.Fatalf("NewEmbedder of %v error: %v", provider, err)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func EmbedStrings(ctx context.Context, texts []string) (embeddings [][]float64, err error) {
|
||||
provider := g.Cfg().MustGet(ctx, "eino.embedding.provider").String()
|
||||
switch provider {
|
||||
case providerArk:
|
||||
return EmbedderArk.EmbedStrings(ctx, texts)
|
||||
case providerOpenai:
|
||||
return EmbedderOpenAI.EmbedStrings(ctx, texts)
|
||||
case providerDashscope:
|
||||
return EmbedderDashscope.EmbedStrings(ctx, texts)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported provider: %v", provider)
|
||||
}
|
||||
47
rag/eino/embedding_batch.go
Normal file
47
rag/eino/embedding_batch.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package eino
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cloudwego/eino/components/embedding"
|
||||
)
|
||||
|
||||
// BatchEmbedder 包装器,支持批量限制
|
||||
type BatchEmbedder struct {
|
||||
embedder embedding.Embedder
|
||||
batchSize int
|
||||
}
|
||||
|
||||
// NewBatchEmbedder 创建支持批量限制的 embedding 包装器
|
||||
func NewBatchEmbedder(embedder embedding.Embedder, batchSize int) *BatchEmbedder {
|
||||
if batchSize <= 0 {
|
||||
batchSize = 10 // 默认每批 10 个
|
||||
}
|
||||
return &BatchEmbedder{
|
||||
embedder: embedder,
|
||||
batchSize: batchSize,
|
||||
}
|
||||
}
|
||||
|
||||
// EmbedStrings 分批调用 embedding
|
||||
func (b *BatchEmbedder) EmbedStrings(ctx context.Context, texts []string, opts ...embedding.Option) ([][]float64, error) {
|
||||
if len(texts) <= b.batchSize {
|
||||
return b.embedder.EmbedStrings(ctx, texts, opts...)
|
||||
}
|
||||
|
||||
var allEmbeddings [][]float64
|
||||
for i := 0; i < len(texts); i += b.batchSize {
|
||||
end := i + b.batchSize
|
||||
if end > len(texts) {
|
||||
end = len(texts)
|
||||
}
|
||||
|
||||
batch := texts[i:end]
|
||||
embeddings, err := b.embedder.EmbedStrings(ctx, batch, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allEmbeddings = append(allEmbeddings, embeddings...)
|
||||
}
|
||||
return allEmbeddings, nil
|
||||
}
|
||||
114
rag/gse/utils.go
Normal file
114
rag/gse/utils.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package gse
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/go-ego/gse"
|
||||
"github.com/go-ego/gse/hmm/extracker"
|
||||
"github.com/go-ego/gse/hmm/segment"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
)
|
||||
|
||||
var GseTool *gseTool
|
||||
|
||||
// 初始化函数:程序启动时执行一次
|
||||
func init() {
|
||||
var err error
|
||||
GseTool, err = newGseTool()
|
||||
if err != nil {
|
||||
glog.Error(context.Background(), err)
|
||||
}
|
||||
}
|
||||
|
||||
// gseTool 关键词提取工具(gse v1.0.2 标准)
|
||||
type gseTool struct {
|
||||
seg gse.Segmenter
|
||||
tfidf *extracker.TagExtracter
|
||||
tr *extracker.TextRanker
|
||||
}
|
||||
|
||||
// newGseTool 初始化工具(内置词典 + 停用词)
|
||||
func newGseTool() (tool *gseTool, err error) {
|
||||
// 1. 初始化分词器
|
||||
var seg gse.Segmenter
|
||||
// 内置词典(无外部文件)
|
||||
err = seg.LoadDictEmbed()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 内置停用词(v1.0.2 标准)
|
||||
err = seg.LoadStopEmbed()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 初始化 TF-IDF 提取器
|
||||
tfidf := &extracker.TagExtracter{}
|
||||
tfidf.WithGse(seg)
|
||||
err = tfidf.LoadIdf()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 初始化 TextRank 提取器
|
||||
tr := &extracker.TextRanker{}
|
||||
tr.WithGse(seg)
|
||||
|
||||
tool = &gseTool{
|
||||
seg: seg,
|
||||
tfidf: tfidf,
|
||||
tr: tr,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Cut 分词(关键词提取唯一正确模式:精确模式 + HMM)
|
||||
func (k *gseTool) Cut(text string) []string {
|
||||
return k.seg.Cut(text, true)
|
||||
}
|
||||
|
||||
// Keyword 最终输出:关键词 + 权重
|
||||
type Keyword struct {
|
||||
Word string `json:"word"`
|
||||
Score float64 `json:"score"`
|
||||
}
|
||||
|
||||
func (k *gseTool) Extract(text string, topN int) []Keyword {
|
||||
// 1. 提取 TF-IDF
|
||||
tfTags := k.extractTFIDF(text, topN)
|
||||
|
||||
// 2. 提取 TextRank
|
||||
trTags := k.extractTextRank(text, topN)
|
||||
|
||||
// 3. 合并成最终关键词(业务最常用)
|
||||
scoreMap := make(map[string]float64)
|
||||
for _, tag := range tfTags {
|
||||
scoreMap[tag.Text] = tag.Weight
|
||||
}
|
||||
for _, tag := range trTags {
|
||||
scoreMap[tag.Text] = tag.Weight
|
||||
}
|
||||
|
||||
// 转成切片并排序(高分在前)
|
||||
res := make([]Keyword, 0, len(scoreMap))
|
||||
for word, score := range scoreMap {
|
||||
res = append(res, Keyword{Word: word, Score: score})
|
||||
}
|
||||
|
||||
sort.Slice(res, func(i, j int) bool {
|
||||
return res[i].Score > res[j].Score
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// ExtractTFIDF TF-IDF 关键词(带权重)90% 业务:文章标签、搜索、关键词
|
||||
func (k *gseTool) extractTFIDF(text string, topN int) segment.Segments {
|
||||
return k.tfidf.ExtractTags(text, topN)
|
||||
}
|
||||
|
||||
// ExtractTextRank TextRank 关键词(带权重)长文本、摘要、语义理解
|
||||
func (k *gseTool) extractTextRank(text string, topN int) segment.Segments {
|
||||
return k.tr.TextRank(text, topN)
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -38,40 +37,6 @@ func RedisClient() *gredis.Redis {
|
||||
return getClient()
|
||||
}
|
||||
|
||||
// Lock 分布式锁
|
||||
func Lock(ctx context.Context, key string, expireSeconds int64, fn func(ctx context.Context) error) (success bool, err error) {
|
||||
limit := 3
|
||||
LOOP:
|
||||
if limit < 0 {
|
||||
return false, errors.New("锁重试次数耗尽")
|
||||
}
|
||||
limit--
|
||||
client := getClient()
|
||||
if val, err := client.Set(ctx, key, true, gredis.SetOption{
|
||||
TTLOption: gredis.TTLOption{
|
||||
EX: &expireSeconds,
|
||||
},
|
||||
NX: true,
|
||||
}); err != nil {
|
||||
return false, err
|
||||
} else {
|
||||
if val.Bool() {
|
||||
defer func(client *gredis.Redis, ctx context.Context, key string) {
|
||||
if _, err = client.Del(ctx, key); err != nil {
|
||||
glog.Errorf(ctx, "redis client Del error: %v", err)
|
||||
}
|
||||
}(client, ctx, key)
|
||||
if err = fn(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
} else {
|
||||
time.Sleep(time.Second)
|
||||
goto LOOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetReadStream(ctx context.Context, msg ...QueueMessage) error {
|
||||
for _, t := range msg {
|
||||
err := GetReadFromStream(ctx, t.StreamKey, t.GroupName, t.ConsumerName, t.BatchSize, t.BlockMs, t.AutoAck, t.HandleFunc)
|
||||
|
||||
69
rpc/client.go
Normal file
69
rpc/client.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
consulClient "github.com/rpcxio/rpcx-consul/client"
|
||||
"github.com/smallnest/rpcx/client"
|
||||
)
|
||||
|
||||
var (
|
||||
xclientMap = make(map[string]client.XClient)
|
||||
xclientMu sync.RWMutex
|
||||
)
|
||||
|
||||
// CallWithConsul 基于Consul服务发现调用RPC
|
||||
func CallWithConsul(ctx context.Context, serviceName string, args, reply interface{}) error {
|
||||
xclient, err := getOrCreatXClient(serviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = xclient.Call(ctx, "Mul", args, reply)
|
||||
if err != nil {
|
||||
// 调用失败,清理失效客户端
|
||||
removeXClient(serviceName)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func removeXClient(serviceName string) {
|
||||
xclientMu.Lock()
|
||||
defer xclientMu.Unlock()
|
||||
if c, ok := xclientMap[serviceName]; ok {
|
||||
c.Close()
|
||||
delete(xclientMap, serviceName)
|
||||
}
|
||||
}
|
||||
|
||||
func getOrCreatXClient(serviceName string) (client.XClient, error) {
|
||||
// 第一次:读锁,快速判断是否存在
|
||||
xclientMu.RLock()
|
||||
if c, ok := xclientMap[serviceName]; ok {
|
||||
xclientMu.RUnlock()
|
||||
return c, nil
|
||||
}
|
||||
xclientMu.RUnlock()
|
||||
|
||||
// 没找到,加写锁准备创建
|
||||
xclientMu.Lock()
|
||||
defer xclientMu.Unlock()
|
||||
|
||||
// 第二次:双重检查,防止刚被别人创建完
|
||||
if c, ok := xclientMap[serviceName]; ok {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
consulAddr := g.Cfg().MustGet(nil, "consul.address").String()
|
||||
|
||||
d, err := consulClient.NewConsulDiscovery("rpcx", serviceName, []string{consulAddr}, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := client.NewXClient(serviceName, client.Failtry, client.RandomSelect, d, client.DefaultOption)
|
||||
xclientMap[serviceName] = c
|
||||
return c, nil
|
||||
}
|
||||
707
rpc/rpcx.go
707
rpc/rpcx.go
@@ -1,364 +1,347 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/consul"
|
||||
"gitea.com/red-future/common/jaeger"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
rpcxClient "github.com/smallnest/rpcx/client"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
// pluginsContainer rpcx插件容器(全局统一设置)
|
||||
// init()中添加链路追踪插件,所有client共用此容器
|
||||
pluginsContainer = rpcxClient.NewPluginContainer()
|
||||
|
||||
// clientPool 连接池缓存,key为服务名,value为客户端实例
|
||||
clientPool = make(map[string]*rpcxClient.OneClient)
|
||||
|
||||
// poolMutex 连接池锁
|
||||
poolMutex sync.RWMutex
|
||||
|
||||
// healthCheckInterval 健康检查间隔(秒)
|
||||
healthCheckInterval = 30
|
||||
|
||||
// lastHealthCheckTime 上次健康检查时间,key为服务名
|
||||
lastHealthCheckTime = make(map[string]time.Time)
|
||||
|
||||
// serviceAddrCache 服务地址缓存,key为服务名,value为地址
|
||||
serviceAddrCache = make(map[string]string)
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 全局设置链路追踪插件,所有client共用
|
||||
pluginsContainer.Add(&TracingPlugin{})
|
||||
|
||||
// 启动后台健康检查协程
|
||||
go healthCheckLoop()
|
||||
}
|
||||
|
||||
// healthCheckLoop 后台健康检查循环
|
||||
func healthCheckLoop() {
|
||||
ticker := time.NewTicker(time.Duration(healthCheckInterval) * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
checkAllConnections()
|
||||
}
|
||||
}
|
||||
|
||||
// checkAllConnections 检查所有缓存连接的健康状态
|
||||
func checkAllConnections() {
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
for serviceName, client := range clientPool {
|
||||
// 检查连接是否需要健康检查
|
||||
if lastCheck, ok := lastHealthCheckTime[serviceName]; ok {
|
||||
if now.Sub(lastCheck) < time.Duration(healthCheckInterval)*time.Second {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// 检查连接健康状态(心跳检测)
|
||||
if !isClientHealthy(ctx, client, serviceName) {
|
||||
g.Log().Warningf(ctx, "检测到服务[%s]连接不健康,将从连接池移除", serviceName)
|
||||
client.Close()
|
||||
delete(clientPool, serviceName)
|
||||
delete(lastHealthCheckTime, serviceName)
|
||||
delete(serviceAddrCache, serviceName)
|
||||
continue
|
||||
}
|
||||
|
||||
// 连接健康,检查服务地址是否发生变化
|
||||
currentAddr, err := consul.GetInstanceAddr(ctx, serviceName)
|
||||
if err != nil {
|
||||
g.Log().Warningf(ctx, "健康检查时从consul获取服务[%s]地址失败: %v,保持现有连接", serviceName, err)
|
||||
lastHealthCheckTime[serviceName] = now
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查地址是否发生变化
|
||||
if oldAddr, ok := serviceAddrCache[serviceName]; ok && oldAddr != currentAddr {
|
||||
g.Log().Infof(ctx, "检测到服务[%s]地址变化: %s -> %s,重建连接", serviceName, oldAddr, currentAddr)
|
||||
// 关闭旧连接并从连接池移除,下次请求时会创建新连接
|
||||
client.Close()
|
||||
delete(clientPool, serviceName)
|
||||
delete(lastHealthCheckTime, serviceName)
|
||||
// 更新缓存的新地址
|
||||
serviceAddrCache[serviceName] = currentAddr
|
||||
} else {
|
||||
// 地址未变化,更新检查时间
|
||||
if !ok {
|
||||
serviceAddrCache[serviceName] = currentAddr
|
||||
}
|
||||
g.Log().Debugf(ctx, "服务[%s]地址未变化,连接健康", serviceName)
|
||||
}
|
||||
|
||||
lastHealthCheckTime[serviceName] = now
|
||||
}
|
||||
}
|
||||
|
||||
// isClientHealthy 检查client是否健康
|
||||
// 使用心跳检测方式:尝试调用服务的心跳方法
|
||||
func isClientHealthy(ctx context.Context, client *rpcxClient.OneClient, serviceName string) bool {
|
||||
if client == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 设置较短的超时时间,避免阻塞
|
||||
pingCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// 尝试调用健康检查方法
|
||||
// 大多数服务都会提供 Ping 或 Health 方法
|
||||
// 如果服务没有提供这些方法,会返回错误,我们认为是健康的
|
||||
// 因为连接本身是正常的,只是方法不存在
|
||||
var reply interface{}
|
||||
err := client.Call(pingCtx, serviceName, "Ping", nil, &reply)
|
||||
|
||||
// 如果调用成功,连接肯定健康
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// 如果是方法不存在的错误,说明连接是健康的,只是服务没有Ping方法
|
||||
// 这种情况下我们认为是健康的
|
||||
if isMethodNotFoundError(err) || isServiceNotFoundError(err) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 其他错误(网络错误、超时等)说明连接不健康
|
||||
g.Log().Warningf(ctx, "健康检查失败,服务[%s]连接可能不健康: %v", serviceName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// isMethodNotFoundError 判断是否是方法未找到错误
|
||||
func isMethodNotFoundError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
errStr := err.Error()
|
||||
// rpcx 方法不存在的常见错误信息
|
||||
return strings.Contains(errStr, "not found") ||
|
||||
strings.Contains(errStr, "no such") ||
|
||||
strings.Contains(errStr, "service not found") ||
|
||||
strings.Contains(errStr, "method not found")
|
||||
}
|
||||
|
||||
// isServiceNotFoundError 判断是否是服务未找到错误
|
||||
func isServiceNotFoundError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
errStr := err.Error()
|
||||
return strings.Contains(errStr, "no service") ||
|
||||
strings.Contains(errStr, "service not registered")
|
||||
}
|
||||
|
||||
// getOrCreateClient 从连接池获取或创建客户端(带连接池)
|
||||
func getOrCreateClient(ctx context.Context, serviceName string) (*rpcxClient.OneClient, error) {
|
||||
if g.IsEmpty(serviceName) {
|
||||
return nil, errors.New("服务名称不能为空")
|
||||
}
|
||||
|
||||
// 先尝试从连接池获取
|
||||
poolMutex.RLock()
|
||||
client, exists := clientPool[serviceName]
|
||||
poolMutex.RUnlock()
|
||||
|
||||
// 如果存在且健康,直接返回
|
||||
if exists && isClientHealthy(ctx, client, serviceName) {
|
||||
g.Log().Debugf(ctx, "从连接池获取rpcx客户端[%s]", serviceName)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// 不存在或不健康,重新创建
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
// 双重检查,防止并发时重复创建
|
||||
if client, exists := clientPool[serviceName]; exists && isClientHealthy(ctx, client, serviceName) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// 获取服务实例地址
|
||||
addr, err := consul.GetInstanceAddr(ctx, serviceName)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "从consul获取服务[%s]地址失败: %v", serviceName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
g.Log().Debugf(ctx, "服务[%s]地址: %s", serviceName, addr)
|
||||
|
||||
// 缓存服务地址,用于健康检查时对比
|
||||
serviceAddrCache[serviceName] = addr
|
||||
|
||||
// 创建服务发现
|
||||
discovery, err := rpcxClient.NewPeer2PeerDiscovery("tcp@"+addr, "")
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "创建服务发现失败: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建新客户端
|
||||
newClient := rpcxClient.NewOneClient(
|
||||
rpcxClient.Failtry,
|
||||
rpcxClient.RandomSelect,
|
||||
discovery,
|
||||
rpcxClient.DefaultOption,
|
||||
)
|
||||
newClient.SetPlugins(pluginsContainer)
|
||||
|
||||
// 更新连接池
|
||||
if oldClient, ok := clientPool[serviceName]; ok && oldClient != nil {
|
||||
oldClient.Close()
|
||||
}
|
||||
clientPool[serviceName] = newClient
|
||||
lastHealthCheckTime[serviceName] = time.Now()
|
||||
|
||||
g.Log().Infof(ctx, "rpcx客户端[%s]创建并加入连接池", serviceName)
|
||||
|
||||
return newClient, nil
|
||||
}
|
||||
|
||||
// Call 调用rpcx服务方法
|
||||
// serviceName: 服务名称
|
||||
// serviceMethod: 服务方法
|
||||
// args: 请求参数
|
||||
// reply: 响应结果
|
||||
func Call(ctx context.Context, serviceName, serviceMethod string, args interface{}, reply interface{}) error {
|
||||
// 从连接池获取客户端(不再关闭连接)
|
||||
client, err := getOrCreateClient(ctx, serviceName)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "获取rpcx客户端失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置超时
|
||||
callCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// 调用服务方法
|
||||
err = client.Call(callCtx, serviceName, serviceMethod, args, reply)
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "调用服务[%s]方法[%s]失败: %v", serviceName, serviceMethod, err)
|
||||
|
||||
// 如果调用失败,检查连接是否需要重新创建
|
||||
poolMutex.Lock()
|
||||
if pooledClient, ok := clientPool[serviceName]; ok && pooledClient == client {
|
||||
// 标记为不健康,下次请求时会重新创建
|
||||
delete(lastHealthCheckTime, serviceName)
|
||||
}
|
||||
poolMutex.Unlock()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close 关闭指定服务的连接(用于清理连接池)
|
||||
func Close(serviceName string) {
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
if client, ok := clientPool[serviceName]; ok {
|
||||
client.Close()
|
||||
delete(clientPool, serviceName)
|
||||
delete(lastHealthCheckTime, serviceName)
|
||||
delete(serviceAddrCache, serviceName)
|
||||
g.Log().Infof(context.Background(), "rpcx客户端[%s]已从连接池移除", serviceName)
|
||||
}
|
||||
}
|
||||
|
||||
// CloseAll 关闭所有连接(用于优雅停机)
|
||||
func CloseAll() {
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
for serviceName, client := range clientPool {
|
||||
client.Close()
|
||||
g.Log().Infof(context.Background(), "rpcx客户端[%s]已关闭", serviceName)
|
||||
}
|
||||
clientPool = make(map[string]*rpcxClient.OneClient)
|
||||
lastHealthCheckTime = make(map[string]time.Time)
|
||||
serviceAddrCache = make(map[string]string)
|
||||
}
|
||||
|
||||
// TracingPlugin rpcx链路追踪插件
|
||||
// 实现 rpcx 的 PreCallPlugin 和 PostCallPlugin 接口
|
||||
type TracingPlugin struct{}
|
||||
|
||||
// PreCall 调用前拦截 - 创建jaeger span
|
||||
func (p *TracingPlugin) PreCall(ctx context.Context, serviceName, serviceMethod string, args interface{}) (err error) {
|
||||
// 创建span,名称格式: ServiceName.Method
|
||||
spanName := serviceName + "." + serviceMethod
|
||||
ctx, span := jaeger.NewSpan(ctx, spanName)
|
||||
|
||||
// 记录服务和方法信息
|
||||
span.SetAttributes(
|
||||
attribute.String("rpc.service", serviceName),
|
||||
attribute.String("rpc.method", serviceMethod),
|
||||
attribute.String("rpc.system", "rpcx"),
|
||||
)
|
||||
var data []byte
|
||||
// 记录请求参数(序列化为JSON)
|
||||
if args != nil {
|
||||
if data, err = json.Marshal(args); err == nil {
|
||||
argsStr := string(data)
|
||||
// 限制长度,避免过大
|
||||
if len(argsStr) > 2000 {
|
||||
argsStr = argsStr[:2000] + "... (truncated)"
|
||||
}
|
||||
span.SetAttributes(attribute.String("rpc.request", argsStr))
|
||||
}
|
||||
}
|
||||
|
||||
g.Log().Debugf(ctx, "[rpcx] 调用开始: %s.%s", serviceName, serviceMethod)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// PostCall 调用后拦截 - 记录结果和错误
|
||||
func (p *TracingPlugin) PostCall(ctx context.Context, serviceName, serviceMethod string, args interface{}, reply interface{}, err error) error {
|
||||
span := trace.SpanFromContext(ctx)
|
||||
if span != nil && span.IsRecording() {
|
||||
defer span.End()
|
||||
|
||||
// 记录响应结果
|
||||
if reply != nil {
|
||||
if data, err := json.Marshal(reply); err == nil {
|
||||
replyStr := string(data)
|
||||
// 限制长度,避免过大
|
||||
if len(replyStr) > 2000 {
|
||||
replyStr = replyStr[:2000] + "... (truncated)"
|
||||
}
|
||||
span.SetAttributes(attribute.String("rpc.response", replyStr))
|
||||
}
|
||||
}
|
||||
|
||||
// 处理错误
|
||||
if err != nil {
|
||||
jaeger.RecordError(ctx, err, "rpcx调用失败")
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
g.Log().Errorf(ctx, "[rpcx] 调用失败: %s.%s, 错误: %v", serviceName, serviceMethod, err)
|
||||
} else {
|
||||
g.Log().Debugf(ctx, "[rpcx] 调用成功: %s.%s", serviceName, serviceMethod)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
//var (
|
||||
// // pluginsContainer rpcx插件容器(全局统一设置)
|
||||
// // init()中添加链路追踪插件,所有client共用此容器
|
||||
// pluginsContainer = rpcxClient.NewPluginContainer()
|
||||
//
|
||||
// // clientPool 连接池缓存,key为服务名,value为客户端实例
|
||||
// clientPool = make(map[string]*rpcxClient.OneClient)
|
||||
//
|
||||
// // poolMutex 连接池锁
|
||||
// poolMutex sync.RWMutex
|
||||
//
|
||||
// // healthCheckInterval 健康检查间隔(秒)
|
||||
// healthCheckInterval = 30
|
||||
//
|
||||
// // lastHealthCheckTime 上次健康检查时间,key为服务名
|
||||
// lastHealthCheckTime = make(map[string]time.Time)
|
||||
//
|
||||
// // serviceAddrCache 服务地址缓存,key为服务名,value为地址
|
||||
// serviceAddrCache = make(map[string]string)
|
||||
//)
|
||||
//
|
||||
//func init() {
|
||||
// // 全局设置链路追踪插件,所有client共用
|
||||
// pluginsContainer.Add(&TracingPlugin{})
|
||||
//
|
||||
// // 启动后台健康检查协程
|
||||
// go healthCheckLoop()
|
||||
//}
|
||||
//
|
||||
//// healthCheckLoop 后台健康检查循环
|
||||
//func healthCheckLoop() {
|
||||
// ticker := time.NewTicker(time.Duration(healthCheckInterval) * time.Second)
|
||||
// defer ticker.Stop()
|
||||
//
|
||||
// for range ticker.C {
|
||||
// checkAllConnections()
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// checkAllConnections 检查所有缓存连接的健康状态
|
||||
//func checkAllConnections() {
|
||||
// poolMutex.Lock()
|
||||
// defer poolMutex.Unlock()
|
||||
//
|
||||
// now := time.Now()
|
||||
// for serviceName, client := range clientPool {
|
||||
// // 检查连接是否需要健康检查
|
||||
// if lastCheck, ok := lastHealthCheckTime[serviceName]; ok {
|
||||
// if now.Sub(lastCheck) < time.Duration(healthCheckInterval)*time.Second {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// // 检查连接健康状态(心跳检测)
|
||||
// if !isClientHealthy(ctx, client, serviceName) {
|
||||
// g.Log().Warningf(ctx, "检测到服务[%s]连接不健康,将从连接池移除", serviceName)
|
||||
// client.Close()
|
||||
// delete(clientPool, serviceName)
|
||||
// delete(lastHealthCheckTime, serviceName)
|
||||
// delete(serviceAddrCache, serviceName)
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // 连接健康,检查服务地址是否发生变化
|
||||
// currentAddr, err := consul.GetInstanceAddr(ctx, serviceName)
|
||||
// if err != nil {
|
||||
// g.Log().Warningf(ctx, "健康检查时从consul获取服务[%s]地址失败: %v,保持现有连接", serviceName, err)
|
||||
// lastHealthCheckTime[serviceName] = now
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // 检查地址是否发生变化
|
||||
// if oldAddr, ok := serviceAddrCache[serviceName]; ok && oldAddr != currentAddr {
|
||||
// g.Log().Infof(ctx, "检测到服务[%s]地址变化: %s -> %s,重建连接", serviceName, oldAddr, currentAddr)
|
||||
// // 关闭旧连接并从连接池移除,下次请求时会创建新连接
|
||||
// client.Close()
|
||||
// delete(clientPool, serviceName)
|
||||
// delete(lastHealthCheckTime, serviceName)
|
||||
// // 更新缓存的新地址
|
||||
// serviceAddrCache[serviceName] = currentAddr
|
||||
// } else {
|
||||
// // 地址未变化,更新检查时间
|
||||
// if !ok {
|
||||
// serviceAddrCache[serviceName] = currentAddr
|
||||
// }
|
||||
// g.Log().Debugf(ctx, "服务[%s]地址未变化,连接健康", serviceName)
|
||||
// }
|
||||
//
|
||||
// lastHealthCheckTime[serviceName] = now
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// isClientHealthy 检查client是否健康
|
||||
//// 使用心跳检测方式:尝试调用服务的心跳方法
|
||||
//func isClientHealthy(ctx context.Context, client *rpcxClient.OneClient, serviceName string) bool {
|
||||
// if client == nil {
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// // 设置较短的超时时间,避免阻塞
|
||||
// pingCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
||||
// defer cancel()
|
||||
//
|
||||
// // 尝试调用健康检查方法
|
||||
// // 大多数服务都会提供 Ping 或 Health 方法
|
||||
// // 如果服务没有提供这些方法,会返回错误,我们认为是健康的
|
||||
// // 因为连接本身是正常的,只是方法不存在
|
||||
// var reply interface{}
|
||||
// err := client.Call(pingCtx, serviceName, "Ping", nil, &reply)
|
||||
//
|
||||
// // 如果调用成功,连接肯定健康
|
||||
// if err == nil {
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// // 如果是方法不存在的错误,说明连接是健康的,只是服务没有Ping方法
|
||||
// // 这种情况下我们认为是健康的
|
||||
// if isMethodNotFoundError(err) || isServiceNotFoundError(err) {
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// // 其他错误(网络错误、超时等)说明连接不健康
|
||||
// g.Log().Warningf(ctx, "健康检查失败,服务[%s]连接可能不健康: %v", serviceName, err)
|
||||
// return false
|
||||
//}
|
||||
//
|
||||
//// isMethodNotFoundError 判断是否是方法未找到错误
|
||||
//func isMethodNotFoundError(err error) bool {
|
||||
// if err == nil {
|
||||
// return false
|
||||
// }
|
||||
// errStr := err.Error()
|
||||
// // rpcx 方法不存在的常见错误信息
|
||||
// return strings.Contains(errStr, "not found") ||
|
||||
// strings.Contains(errStr, "no such") ||
|
||||
// strings.Contains(errStr, "service not found") ||
|
||||
// strings.Contains(errStr, "method not found")
|
||||
//}
|
||||
//
|
||||
//// isServiceNotFoundError 判断是否是服务未找到错误
|
||||
//func isServiceNotFoundError(err error) bool {
|
||||
// if err == nil {
|
||||
// return false
|
||||
// }
|
||||
// errStr := err.Error()
|
||||
// return strings.Contains(errStr, "no service") ||
|
||||
// strings.Contains(errStr, "service not registered")
|
||||
//}
|
||||
//
|
||||
//// getOrCreateClient 从连接池获取或创建客户端(带连接池)
|
||||
//func getOrCreateClient(ctx context.Context, serviceName string) (*rpcxClient.OneClient, error) {
|
||||
// if g.IsEmpty(serviceName) {
|
||||
// return nil, errors.New("服务名称不能为空")
|
||||
// }
|
||||
//
|
||||
// // 先尝试从连接池获取
|
||||
// poolMutex.RLock()
|
||||
// client, exists := clientPool[serviceName]
|
||||
// poolMutex.RUnlock()
|
||||
//
|
||||
// // 如果存在且健康,直接返回
|
||||
// if exists && isClientHealthy(ctx, client, serviceName) {
|
||||
// g.Log().Debugf(ctx, "从连接池获取rpcx客户端[%s]", serviceName)
|
||||
// return client, nil
|
||||
// }
|
||||
//
|
||||
// // 不存在或不健康,重新创建
|
||||
// poolMutex.Lock()
|
||||
// defer poolMutex.Unlock()
|
||||
//
|
||||
// // 双重检查,防止并发时重复创建
|
||||
// if client, exists := clientPool[serviceName]; exists && isClientHealthy(ctx, client, serviceName) {
|
||||
// return client, nil
|
||||
// }
|
||||
//
|
||||
// // 获取服务实例地址
|
||||
// addr, err := consul.GetInstanceAddr(ctx, serviceName)
|
||||
// if err != nil {
|
||||
// g.Log().Errorf(ctx, "从consul获取服务[%s]地址失败: %v", serviceName, err)
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// g.Log().Debugf(ctx, "服务[%s]地址: %s", serviceName, addr)
|
||||
//
|
||||
// // 缓存服务地址,用于健康检查时对比
|
||||
// serviceAddrCache[serviceName] = addr
|
||||
//
|
||||
// // 创建服务发现
|
||||
// discovery, err := rpcxClient.NewPeer2PeerDiscovery("tcp@"+addr, "")
|
||||
// if err != nil {
|
||||
// g.Log().Errorf(ctx, "创建服务发现失败: %v", err)
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// // 创建新客户端
|
||||
// newClient := rpcxClient.NewOneClient(
|
||||
// rpcxClient.Failtry,
|
||||
// rpcxClient.RandomSelect,
|
||||
// discovery,
|
||||
// rpcxClient.DefaultOption,
|
||||
// )
|
||||
// newClient.SetPlugins(pluginsContainer)
|
||||
//
|
||||
// // 更新连接池
|
||||
// if oldClient, ok := clientPool[serviceName]; ok && oldClient != nil {
|
||||
// oldClient.Close()
|
||||
// }
|
||||
// clientPool[serviceName] = newClient
|
||||
// lastHealthCheckTime[serviceName] = time.Now()
|
||||
//
|
||||
// g.Log().Infof(ctx, "rpcx客户端[%s]创建并加入连接池", serviceName)
|
||||
//
|
||||
// return newClient, nil
|
||||
//}
|
||||
//
|
||||
//// Call 调用rpcx服务方法
|
||||
//// serviceName: 服务名称
|
||||
//// serviceMethod: 服务方法
|
||||
//// args: 请求参数
|
||||
//// reply: 响应结果
|
||||
//func Call(ctx context.Context, serviceName, serviceMethod string, args interface{}, reply interface{}) error {
|
||||
// // 从连接池获取客户端(不再关闭连接)
|
||||
// client, err := getOrCreateClient(ctx, serviceName)
|
||||
// if err != nil {
|
||||
// g.Log().Errorf(ctx, "获取rpcx客户端失败: %v", err)
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// // 设置超时
|
||||
// callCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
// defer cancel()
|
||||
//
|
||||
// // 调用服务方法
|
||||
// err = client.Call(callCtx, serviceName, serviceMethod, args, reply)
|
||||
// if err != nil {
|
||||
// g.Log().Errorf(ctx, "调用服务[%s]方法[%s]失败: %v", serviceName, serviceMethod, err)
|
||||
//
|
||||
// // 如果调用失败,检查连接是否需要重新创建
|
||||
// poolMutex.Lock()
|
||||
// if pooledClient, ok := clientPool[serviceName]; ok && pooledClient == client {
|
||||
// // 标记为不健康,下次请求时会重新创建
|
||||
// delete(lastHealthCheckTime, serviceName)
|
||||
// }
|
||||
// poolMutex.Unlock()
|
||||
//
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//// Close 关闭指定服务的连接(用于清理连接池)
|
||||
//func Close(serviceName string) {
|
||||
// poolMutex.Lock()
|
||||
// defer poolMutex.Unlock()
|
||||
//
|
||||
// if client, ok := clientPool[serviceName]; ok {
|
||||
// client.Close()
|
||||
// delete(clientPool, serviceName)
|
||||
// delete(lastHealthCheckTime, serviceName)
|
||||
// delete(serviceAddrCache, serviceName)
|
||||
// g.Log().Infof(context.Background(), "rpcx客户端[%s]已从连接池移除", serviceName)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// CloseAll 关闭所有连接(用于优雅停机)
|
||||
//func CloseAll() {
|
||||
// poolMutex.Lock()
|
||||
// defer poolMutex.Unlock()
|
||||
//
|
||||
// for serviceName, client := range clientPool {
|
||||
// client.Close()
|
||||
// g.Log().Infof(context.Background(), "rpcx客户端[%s]已关闭", serviceName)
|
||||
// }
|
||||
// clientPool = make(map[string]*rpcxClient.OneClient)
|
||||
// lastHealthCheckTime = make(map[string]time.Time)
|
||||
// serviceAddrCache = make(map[string]string)
|
||||
//}
|
||||
//
|
||||
//// TracingPlugin rpcx链路追踪插件
|
||||
//// 实现 rpcx 的 PreCallPlugin 和 PostCallPlugin 接口
|
||||
//type TracingPlugin struct{}
|
||||
//
|
||||
//// PreCall 调用前拦截 - 创建jaeger span
|
||||
//func (p *TracingPlugin) PreCall(ctx context.Context, serviceName, serviceMethod string, args interface{}) (err error) {
|
||||
// // 创建span,名称格式: ServiceName.Method
|
||||
// spanName := serviceName + "." + serviceMethod
|
||||
// ctx, span := jaeger.NewSpan(ctx, spanName)
|
||||
//
|
||||
// // 记录服务和方法信息
|
||||
// span.SetAttributes(
|
||||
// attribute.String("rpc.service", serviceName),
|
||||
// attribute.String("rpc.method", serviceMethod),
|
||||
// attribute.String("rpc.system", "rpcx"),
|
||||
// )
|
||||
// var data []byte
|
||||
// // 记录请求参数(序列化为JSON)
|
||||
// if args != nil {
|
||||
// if data, err = json.Marshal(args); err == nil {
|
||||
// argsStr := string(data)
|
||||
// // 限制长度,避免过大
|
||||
// if len(argsStr) > 2000 {
|
||||
// argsStr = argsStr[:2000] + "... (truncated)"
|
||||
// }
|
||||
// span.SetAttributes(attribute.String("rpc.request", argsStr))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// g.Log().Debugf(ctx, "[rpcx] 调用开始: %s.%s", serviceName, serviceMethod)
|
||||
//
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//// PostCall 调用后拦截 - 记录结果和错误
|
||||
//func (p *TracingPlugin) PostCall(ctx context.Context, serviceName, serviceMethod string, args interface{}, reply interface{}, err error) error {
|
||||
// span := trace.SpanFromContext(ctx)
|
||||
// if span != nil && span.IsRecording() {
|
||||
// defer span.End()
|
||||
//
|
||||
// // 记录响应结果
|
||||
// if reply != nil {
|
||||
// if data, err := json.Marshal(reply); err == nil {
|
||||
// replyStr := string(data)
|
||||
// // 限制长度,避免过大
|
||||
// if len(replyStr) > 2000 {
|
||||
// replyStr = replyStr[:2000] + "... (truncated)"
|
||||
// }
|
||||
// span.SetAttributes(attribute.String("rpc.response", replyStr))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 处理错误
|
||||
// if err != nil {
|
||||
// jaeger.RecordError(ctx, err, "rpcx调用失败")
|
||||
// span.SetStatus(codes.Error, err.Error())
|
||||
// g.Log().Errorf(ctx, "[rpcx] 调用失败: %s.%s, 错误: %v", serviceName, serviceMethod, err)
|
||||
// } else {
|
||||
// g.Log().Debugf(ctx, "[rpcx] 调用成功: %s.%s", serviceName, serviceMethod)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
||||
93
rpc/server.go
Normal file
93
rpc/server.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/rpcxio/rpcx-consul/serverplugin"
|
||||
"github.com/smallnest/rpcx/server"
|
||||
)
|
||||
|
||||
var rpcServer *server.Server
|
||||
|
||||
// Serve 启动RPC服务
|
||||
func Serve(ctx context.Context, service interface{}) error {
|
||||
// 获取本机IP
|
||||
ip, err := getLocalIP()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取IP失败: %w", err)
|
||||
}
|
||||
|
||||
// 解析端口
|
||||
addrConfig := g.Cfg().MustGet(ctx, "server.address").String()
|
||||
portStr := strings.TrimPrefix(addrConfig, ":")
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return errors.New("端口解析失败")
|
||||
}
|
||||
serviceAddr := fmt.Sprintf("%s:%d", ip, port)
|
||||
|
||||
// 创建服务端
|
||||
rpcServer = server.NewServer()
|
||||
|
||||
// 添加 Consul 注册插件
|
||||
consulAddr := g.Cfg().MustGet(ctx, "consul.address").String()
|
||||
if consulAddr != "" {
|
||||
plugin := &serverplugin.ConsulRegisterPlugin{
|
||||
ServiceAddress: "tcp@" + serviceAddr,
|
||||
ConsulServers: []string{consulAddr},
|
||||
BasePath: "rpcx",
|
||||
UpdateInterval: time.Minute,
|
||||
}
|
||||
if err := plugin.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
rpcServer.Plugins.Add(plugin)
|
||||
g.Log().Infof(ctx, "Consul注册成功: %s", serviceAddr)
|
||||
}
|
||||
|
||||
// 注册服务
|
||||
err = rpcServer.Register(service, "")
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, "注册服务失败: %v", err)
|
||||
return nil
|
||||
}
|
||||
// 优雅关闭
|
||||
//gproc.AddShutdownFunc(func(ctx context.Context) {
|
||||
// if rpcServer != nil {
|
||||
// _ = rpcServer.Shutdown(ctx)
|
||||
// }
|
||||
//})
|
||||
|
||||
// 异步启动
|
||||
go func() {
|
||||
g.Log().Infof(ctx, "RPC服务启动: %s", serviceAddr)
|
||||
if err := rpcServer.Serve("tcp", serviceAddr); err != nil {
|
||||
g.Log().Fatalf(ctx, "RPC服务启动失败: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLocalIP() (string, error) {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
|
||||
if ipNet.IP.To4() != nil {
|
||||
return ipNet.IP.String(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("未找到本机IP")
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package utils
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
@@ -13,10 +14,12 @@ import (
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/beans"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/database/gredis"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/tiger1103/gfast-token/gftoken"
|
||||
@@ -397,6 +400,7 @@ func GetFileAddressPrefix(ctx context.Context) (imageUrl string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketName 获取bucket名称
|
||||
func GetBucketName(ctx context.Context) (bucketName string, err error) {
|
||||
user, err := GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
@@ -405,3 +409,37 @@ func GetBucketName(ctx context.Context) (bucketName string, err error) {
|
||||
bucketName = fmt.Sprintf("tenantid-%d", user.TenantId)
|
||||
return
|
||||
}
|
||||
|
||||
// Lock 分布式锁
|
||||
func Lock(ctx context.Context, key string, expireSeconds int64, fn func(ctx context.Context) error) (success bool, err error) {
|
||||
limit := 3
|
||||
LOOP:
|
||||
if limit < 0 {
|
||||
return false, errors.New("锁重试次数耗尽")
|
||||
}
|
||||
limit--
|
||||
var val *gvar.Var
|
||||
if val, err = g.Redis().Set(ctx, key, true, gredis.SetOption{
|
||||
TTLOption: gredis.TTLOption{
|
||||
EX: &expireSeconds,
|
||||
},
|
||||
NX: true,
|
||||
}); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if val.Bool() {
|
||||
defer func(ctx context.Context, key string) {
|
||||
if _, err = g.Redis().Del(ctx, key); err != nil {
|
||||
glog.Errorf(ctx, "redis client Del error: %v", err)
|
||||
}
|
||||
}(ctx, key)
|
||||
if err = fn(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
goto LOOP
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user