序文
この記事では、dubo-goのavailableClusterを取り上げます。
NewAvailableCluster
type availableCluster struct{}
const available = "available"
func init() {
	extension.SetCluster(available, NewAvailableCluster)
}
// NewAvailableCluster ...
func NewAvailableCluster() cluster.Cluster {
	return &availableCluster{}
}
- NewAvailableCluster メソッドは、availableCluster をインスタンス化します。
参加
func (cluser *availableCluster) Join(directory cluster.Directory) protocol.Invoker {
	return NewAvailableClusterInvoker(directory)
}
- JoinメソッドNewAvailableClusterInvoker
NewAvailableClusterInvoker
type availableClusterInvoker struct {
	baseClusterInvoker
}
// NewAvailableClusterInvoker ...
func NewAvailableClusterInvoker(directory cluster.Directory) protocol.Invoker {
	return &availableClusterInvoker{
		baseClusterInvoker: newBaseClusterInvoker(directory),
	}
}
- NewAvailableClusterInvoker メソッドは availableClusterInvoker をインスタンス化します。
呼び出し
func (invoker *availableClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
	invokers := invoker.directory.List(invocation)
	err := invoker.checkInvokers(invokers, invocation)
	if err != nil {
		return &protocol.RPCResult{Err: err}
	}
	err = invoker.checkWhetherDestroyed()
	if err != nil {
		return &protocol.RPCResult{Err: err}
	}
	for _, ivk := range invokers {
		if ivk.IsAvailable() {
			return ivk.Invoke(ctx, invocation)
		}
	}
	return &protocol.RPCResult{Err: errors.New(fmt.Sprintf("no provider available in %v", invokers))}
}
短い
availableClusterのJoinメソッドはNewAvailableClusterInvokerを実行し、availableClusterInvokerのInvokeメソッドは最初にinvoker.directory.List(invocation)を介して呼び出し元を取得します。List(invocation)で呼び出し元を取得した後、呼び出し元を繰り返し処理し、ivk.IsAvailable()がtrueの場合、ivk.Invoke(ctx, invocation)を実行します。





