2022-04-20 16:15:41 +08:00
|
|
|
package proxy
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2023-02-26 11:31:49 +08:00
|
|
|
"github.com/cockroachdb/errors"
|
2023-04-06 19:14:32 +08:00
|
|
|
"go.uber.org/zap"
|
2023-03-31 14:36:22 +08:00
|
|
|
"golang.org/x/sync/errgroup"
|
2023-02-26 11:31:49 +08:00
|
|
|
|
2022-04-20 16:15:41 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/types"
|
2023-04-06 19:14:32 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/log"
|
|
|
|
"github.com/milvus-io/milvus/pkg/util/merr"
|
2022-04-20 16:15:41 +08:00
|
|
|
)
|
|
|
|
|
2023-06-13 10:20:37 +08:00
|
|
|
// type pickShardPolicy func(ctx context.Context, mgr shardClientMgr, query func(UniqueID, types.QueryNode) error, leaders []nodeInfo) error
|
2022-07-06 15:06:21 +08:00
|
|
|
|
2023-09-26 09:57:25 +08:00
|
|
|
type queryFunc func(context.Context, UniqueID, types.QueryNodeClient, ...string) error
|
2023-04-06 19:14:32 +08:00
|
|
|
|
2023-06-13 10:20:37 +08:00
|
|
|
type pickShardPolicy func(context.Context, shardClientMgr, queryFunc, map[string][]nodeInfo) error
|
2022-04-20 16:15:41 +08:00
|
|
|
|
2023-09-21 09:45:27 +08:00
|
|
|
var errInvalidShardLeaders = errors.New("Invalid shard leader")
|
2022-04-20 16:15:41 +08:00
|
|
|
|
2023-03-31 14:36:22 +08:00
|
|
|
// RoundRobinPolicy do the query with multiple dml channels
|
|
|
|
// if request failed, it finds shard leader for failed dml channels
|
|
|
|
func RoundRobinPolicy(
|
|
|
|
ctx context.Context,
|
2023-06-13 10:20:37 +08:00
|
|
|
mgr shardClientMgr,
|
2023-03-31 14:36:22 +08:00
|
|
|
query queryFunc,
|
2023-09-21 09:45:27 +08:00
|
|
|
dml2leaders map[string][]nodeInfo,
|
|
|
|
) error {
|
2023-03-31 14:36:22 +08:00
|
|
|
queryChannel := func(ctx context.Context, channel string) error {
|
|
|
|
var combineErr error
|
|
|
|
leaders := dml2leaders[channel]
|
2022-10-31 19:09:39 +08:00
|
|
|
|
2023-03-31 14:36:22 +08:00
|
|
|
for _, target := range leaders {
|
|
|
|
qn, err := mgr.GetClient(ctx, target.nodeID)
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("query channel failed, node not available", zap.String("channel", channel), zap.Int64("nodeID", target.nodeID), zap.Error(err))
|
|
|
|
combineErr = merr.Combine(combineErr, err)
|
|
|
|
continue
|
2022-07-06 15:06:21 +08:00
|
|
|
}
|
2023-03-31 14:36:22 +08:00
|
|
|
err = query(ctx, target.nodeID, qn, channel)
|
2022-07-06 15:06:21 +08:00
|
|
|
if err != nil {
|
2023-03-31 14:36:22 +08:00
|
|
|
log.Warn("query channel failed", zap.String("channel", channel), zap.Int64("nodeID", target.nodeID), zap.Error(err))
|
|
|
|
combineErr = merr.Combine(combineErr, err)
|
2022-07-06 15:06:21 +08:00
|
|
|
continue
|
|
|
|
}
|
2023-03-31 14:36:22 +08:00
|
|
|
return nil
|
2022-04-20 16:15:41 +08:00
|
|
|
}
|
|
|
|
|
2023-03-31 14:36:22 +08:00
|
|
|
log.Ctx(ctx).Error("failed to do query on all shard leader",
|
|
|
|
zap.String("channel", channel), zap.Error(combineErr))
|
|
|
|
return combineErr
|
2022-07-06 15:06:21 +08:00
|
|
|
}
|
2023-03-31 14:36:22 +08:00
|
|
|
|
|
|
|
wg, ctx := errgroup.WithContext(ctx)
|
|
|
|
for channel := range dml2leaders {
|
|
|
|
channel := channel
|
|
|
|
wg.Go(func() error {
|
|
|
|
err := queryChannel(ctx, channel)
|
2022-07-06 15:06:21 +08:00
|
|
|
return err
|
2023-03-31 14:36:22 +08:00
|
|
|
})
|
2022-04-20 16:15:41 +08:00
|
|
|
}
|
2023-03-31 14:36:22 +08:00
|
|
|
|
|
|
|
err := wg.Wait()
|
|
|
|
return err
|
2022-04-20 16:15:41 +08:00
|
|
|
}
|