序文
この記事では、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)を実行します。