信頼できるキュー (while ループ内) でデータを処理するステートフル サービスがあります。データの処理は、実際にはステートレス サービスを呼び出します。
ステートレス サービスはあるノードから別のノードに移動できるため、この依存関係 (ステートレス サービス) をステートフル サービスのコンストラクターに挿入しても安全ですか? コンストラクターで初期化/注入された依存関係が1つのノードに固定されていないことを確認したいだけです。
信頼できるキュー (while ループ内) でデータを処理するステートフル サービスがあります。データの処理は、実際にはステートレス サービスを呼び出します。
ステートレス サービスはあるノードから別のノードに移動できるため、この依存関係 (ステートレス サービス) をステートフル サービスのコンストラクターに挿入しても安全ですか? コンストラクターで初期化/注入された依存関係が1つのノードに固定されていないことを確認したいだけです。
リモート処理を使用してステートレス サービスと通信している場合は、コンストラクターにIServiceProxyFactoryを挿入できます。このようにして、テスト目的でモックを注入することもできます。
この回答の後に質問が変更されました。追加情報: サービス リモート処理は、サービス アドレスの解決、接続、再試行、およびエラー処理を処理します。
例:
public class MyStatefulService : StatefulService
{
private readonly Uri CalledServiceName = new Uri("fabric:/MyApp/MyStatefulService");
private readonly IServiceProxyFactory ServiceProxyFactory;
public MyStatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica, IServiceProxyFactory serviceProxyFactory = null)
: base(serviceContext, reliableStateManagerReplica)
{
ServiceProxyFactory = serviceProxyFactory ?? new ServiceProxyFactory();
}
public Task InsertAsync(object value)
{
var serviceProxy = ServiceProxyFactory.CreateServiceProxy<IMyStatefulService>(CalledServiceName);
return serviceProxy.InsertAsync(value);
}
}
TL;DR; はい、できます。ほとんどの場合、サービス リモート クライアントがそのシナリオを処理します。
説明: サービス リモーティングを使用してサービスと通信するプロキシを作成すると、実際のサービスとの通信を再試行できるクライアントが得られます。これについては、ドキュメント ( https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-connect-and-communicate-with-services )、特に説明するセクションにいくつかの説明があります。サービスの発見と解決:
サービスの解決と接続には、次の手順がループで実行されます。
- 解決: サービスがネーミング サービスから公開したエンドポイントを取得します。
- Connect : そのエンドポイントで使用するプロトコルを介してサービスに接続します。
- Retry : エンドポイント アドレスが最後に解決されてからサービスが移動した場合など、さまざまな理由で接続試行が失敗する可能性があります。その場合、前の解決と接続の手順を再試行する必要があり、接続が成功するまでこのサイクルが繰り返されます。
最後の部分はあなたの質問に非常に関連しています。サービスが前回から移動した場合、実際には解決してから接続を再試行します。したがって、これは、ファブリック トランスポートを使用してサービスにリモート接続している場合、実際にはこのシナリオを処理するためのメカニズムが組み込まれていることを意味します。
IServiceProxyFactory
( )のデフォルトの実装を呼び出すと、Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory
を使用して通信する ServiceProxy が取得されますIServiceRemotingClient
。その の再試行部分ではIServiceRemotingClient
、IExceptionHandler
関連する は、既知のファブリック エラーに関連している場合、一時的エラーと非一時的エラーの両方を再試行します。それらの 1 つは、サービスのアドレスが何らかの形で変更されたことです。
使いやすい静的 ServiceProxy クラス ( で使用ServiceProxy.Create<...>
) がありますが、これは実際には内部でのみ使用Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory
されます。@LoekD の回答で指摘されているようIServiceProxyFactory
に、コンストラクターにインスタンスを挿入するアプローチは、テストに役立ちます。ライブ コードでは のインスタンスを注入しMicrosoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory
、テストではそれの独自のモックを提供します。ServiceProxy
コードでは、 staticと同様に使用します_serviceProxyFactory.Create<IMyService>(...)
。
一方、独自IServiceRemotingClient
に実装する場合は、さまざまなファブリック例外を再試行することを検討する必要があることに注意してください (FabricNotReadableException
および など。 https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-FabricTransientException
を確認してください)。 FabricClient の一般的な例外の詳細については、errors-and-exceptionsを参照してください。