mirror of https://github.com/dapr/dotnet-sdk.git
Revert "Changes to have only one Actions Interactor per ActorProxyFactory"
This reverts commit 2ba7c2f055.
This commit is contained in:
parent
2ba7c2f055
commit
c9711869b5
|
|
@ -17,13 +17,14 @@ namespace Microsoft.Actions.Actors
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Actions.Actors.Communication;
|
using Microsoft.Actions.Actors.Communication;
|
||||||
|
using Microsoft.Actions.Actors.Runtime;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class to interact with actions runtime over http.
|
/// Class to interact with actions runtime over http.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ActionsHttpInteractor : IActionsInteractor
|
internal class ActionsHttpInteractor : IActionsInteractor
|
||||||
{
|
{
|
||||||
private const string ActionsEndpoint = Constants.ActionsDefaultEndpoint;
|
private const string ActionsEndpoint = Constants.ActionsDefaultEndpoint;
|
||||||
private readonly string actionsPort = Constants.ActionsDefaultPort;
|
private readonly string actionsPort = Constants.ActionsDefaultPort;
|
||||||
private readonly HttpClientHandler innerHandler;
|
private readonly HttpClientHandler innerHandler;
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,19 @@ namespace Microsoft.Actions.Actors.Client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ActorProxyFactory : IActorProxyFactory
|
internal class ActorProxyFactory : IActorProxyFactory
|
||||||
{
|
{
|
||||||
// Used only for Remoting based communication
|
private readonly object thisLock;
|
||||||
private static readonly ActorCommunicationClientFactory DefaultActorCommunicationClientFactory = new ActorCommunicationClientFactory();
|
|
||||||
|
|
||||||
|
private volatile IActorCommunicationClientFactory actorCommunicationClientFactory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ActorProxyFactory"/> class.
|
/// Initializes a new instance of the <see cref="ActorProxyFactory"/> class.
|
||||||
/// TODO: Accept Retry settings.
|
/// TODO: Accept Retry settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ActorProxyFactory()
|
public ActorProxyFactory()
|
||||||
{
|
{
|
||||||
|
this.thisLock = new object();
|
||||||
|
|
||||||
|
this.actorCommunicationClientFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
@ -35,7 +39,7 @@ namespace Microsoft.Actions.Actors.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a proxy, this method is also used by ActorReference also to create proxy.
|
/// Create a proxy, this method is also sued by ACtorReference also to create proxy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorId">Actor Id.</param>
|
/// <param name="actorId">Actor Id.</param>
|
||||||
/// <param name="actorInterfaceType">Actor Interface Type.</param>
|
/// <param name="actorInterfaceType">Actor Interface Type.</param>
|
||||||
|
|
@ -43,14 +47,49 @@ namespace Microsoft.Actions.Actors.Client
|
||||||
/// <returns>Returns Actor Proxy.</returns>
|
/// <returns>Returns Actor Proxy.</returns>
|
||||||
internal object CreateActorProxy(ActorId actorId, Type actorInterfaceType, string actorType)
|
internal object CreateActorProxy(ActorId actorId, Type actorInterfaceType, string actorType)
|
||||||
{
|
{
|
||||||
// TODO factory/client level settings
|
var factory = this.GetOrCreateActorCommunicationClientFactory();
|
||||||
var actorCommunicationClient = DefaultActorCommunicationClientFactory.GetClient(actorId, actorType);
|
|
||||||
|
// TODO factory level settings or method level parameter, default http
|
||||||
|
var actorCommunicationClient = new ActorCommunicationClient(
|
||||||
|
factory,
|
||||||
|
actorId,
|
||||||
|
actorType);
|
||||||
|
|
||||||
var proxyGenerator = ActorCodeBuilder.GetOrCreateProxyGenerator(actorInterfaceType);
|
var proxyGenerator = ActorCodeBuilder.GetOrCreateProxyGenerator(actorInterfaceType);
|
||||||
|
|
||||||
return proxyGenerator.CreateActorProxy(
|
return proxyGenerator.CreateActorProxy(
|
||||||
actorCommunicationClient,
|
actorCommunicationClient,
|
||||||
DefaultActorCommunicationClientFactory.GetRemotingMessageBodyFactory());
|
factory.GetRemotingMessageBodyFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IActorCommunicationClientFactory GetOrCreateActorCommunicationClientFactory()
|
||||||
|
{
|
||||||
|
if (this.actorCommunicationClientFactory != null)
|
||||||
|
{
|
||||||
|
return this.actorCommunicationClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (this.thisLock)
|
||||||
|
{
|
||||||
|
if (this.actorCommunicationClientFactory == null)
|
||||||
|
{
|
||||||
|
this.actorCommunicationClientFactory = this.CreateActorCommunicationClientFactory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.actorCommunicationClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IActorCommunicationClientFactory CreateActorCommunicationClientFactory()
|
||||||
|
{
|
||||||
|
// TODO factory settings
|
||||||
|
var factory = new ActorCommunicationClientFactory();
|
||||||
|
if (factory == null)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("ClientFactory can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,16 +11,21 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
|
|
||||||
internal class ActorCommunicationClient : IActorCommunicationClient
|
internal class ActorCommunicationClient : IActorCommunicationClient
|
||||||
{
|
{
|
||||||
private readonly IActionsInteractor actionsInteractor;
|
private readonly SemaphoreSlim communicationClientLock;
|
||||||
|
private readonly IActorCommunicationClientFactory communicationClientFactory;
|
||||||
|
private readonly IActorMessageBodyFactory messageBodyFactory;
|
||||||
|
private IActionsInteractor actionsInteractor;
|
||||||
|
|
||||||
public ActorCommunicationClient(
|
public ActorCommunicationClient(
|
||||||
IActionsInteractor actionsInteractor,
|
IActorCommunicationClientFactory remotingClientFactory,
|
||||||
ActorId actorId,
|
ActorId actorId,
|
||||||
string actorType)
|
string actorType)
|
||||||
{
|
{
|
||||||
this.ActorId = actorId;
|
this.ActorId = actorId;
|
||||||
this.ActorType = actorType;
|
this.ActorType = actorType;
|
||||||
this.actionsInteractor = actionsInteractor;
|
this.communicationClientFactory = remotingClientFactory;
|
||||||
|
this.communicationClientLock = new SemaphoreSlim(1);
|
||||||
|
this.messageBodyFactory = remotingClientFactory.GetRemotingMessageBodyFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -41,7 +46,33 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
string methodName,
|
string methodName,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return await this.actionsInteractor.InvokeActorMethodWithRemotingAsync(remotingRequestMessage);
|
var client = await this.GetCommunicationClientAsync(cancellationToken);
|
||||||
|
return await client.InvokeActorMethodWithRemotingAsync(remotingRequestMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IActionsInteractor> GetCommunicationClientAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
IActionsInteractor client;
|
||||||
|
await this.communicationClientLock.WaitAsync(cancellationToken);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (this.actionsInteractor == null)
|
||||||
|
{
|
||||||
|
this.actionsInteractor = await this.communicationClientFactory.GetClientAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
client = this.actionsInteractor;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Release the lock incase of exceptions from the GetClientAsync method, which can
|
||||||
|
// happen if there are non retriable exceptions in that method. Eg: There can be
|
||||||
|
// ServiceNotFoundException if the GetClientAsync client is called before the
|
||||||
|
// service creation completes.
|
||||||
|
this.communicationClientLock.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,19 +5,24 @@
|
||||||
|
|
||||||
namespace Microsoft.Actions.Actors.Communication.Client
|
namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Actions.Actors.Runtime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An <see cref="IActorCommunicationClientFactory"/> that uses
|
/// An <see cref="IActorCommunicationClientFactory"/> that uses
|
||||||
/// http protocol to create <see cref="IActorCommunicationClient"/> that communicate with actors.
|
/// http protocol to create <see cref="IActorCommunicationClient"/> that communicate with actors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class ActorCommunicationClientFactory : IActorCommunicationClientFactory
|
internal class ActorCommunicationClientFactory : IActorCommunicationClientFactory
|
||||||
{
|
{
|
||||||
private static readonly IActionsInteractor ActionsInteractor = new ActionsHttpInteractor();
|
|
||||||
private readonly ActorMessageSerializersManager serializersManager;
|
private readonly ActorMessageSerializersManager serializersManager;
|
||||||
private readonly IActorMessageBodyFactory actorMessageBodyFactory = null;
|
private readonly IActorMessageBodyFactory remotingMessageBodyFactory = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ActorCommunicationClientFactory"/> class.
|
/// Initializes a new instance of the <see cref="ActorCommunicationClientFactory"/> class.
|
||||||
/// Constructs actor remoting communication client factory.
|
/// Constructs a fabric transport based service remoting client factory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationProvider">IActorCommunicationMessageSerializationProvider provider.</param>
|
/// <param name="serializationProvider">IActorCommunicationMessageSerializationProvider provider.</param>
|
||||||
public ActorCommunicationClientFactory(
|
public ActorCommunicationClientFactory(
|
||||||
|
|
@ -25,7 +30,19 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
{
|
{
|
||||||
// TODO Add settings, exception handlers, serialization provider
|
// TODO Add settings, exception handlers, serialization provider
|
||||||
this.serializersManager = IntializeSerializationManager(serializationProvider);
|
this.serializersManager = IntializeSerializationManager(serializationProvider);
|
||||||
this.actorMessageBodyFactory = this.serializersManager.GetSerializationProvider().CreateMessageBodyFactory();
|
this.remotingMessageBodyFactory = this.serializersManager.GetSerializationProvider().CreateMessageBodyFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a client to communicate.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="System.Threading.Tasks.Task">Task</see> that represents outstanding operation. The result of the Task is
|
||||||
|
/// the CommunicationClient(<see cref="IActorCommunicationClient" />) object.
|
||||||
|
/// </returns>
|
||||||
|
public async Task<IActionsInteractor> GetClientAsync()
|
||||||
|
{
|
||||||
|
return await this.CreateClientAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -34,12 +51,7 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
/// <returns>A factory for creating the remoting message bodies.</returns>
|
/// <returns>A factory for creating the remoting message bodies.</returns>
|
||||||
public IActorMessageBodyFactory GetRemotingMessageBodyFactory()
|
public IActorMessageBodyFactory GetRemotingMessageBodyFactory()
|
||||||
{
|
{
|
||||||
return this.actorMessageBodyFactory;
|
return this.remotingMessageBodyFactory;
|
||||||
}
|
|
||||||
|
|
||||||
public ActorCommunicationClient GetClient(ActorId actorId, string actorType)
|
|
||||||
{
|
|
||||||
return new ActorCommunicationClient(ActionsInteractor, actorId, actorType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActorMessageSerializersManager IntializeSerializationManager(
|
private static ActorMessageSerializersManager IntializeSerializationManager(
|
||||||
|
|
@ -50,5 +62,28 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
serializationProvider,
|
serializationProvider,
|
||||||
new ActorMessageHeaderSerializer());
|
new ActorMessageHeaderSerializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a communication client for the given endpoint address.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The communication client that was created.</returns>
|
||||||
|
private Task<IActionsInteractor> CreateClientAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// TODO add retries and error handling - add CreateClientWithRetriesAsync version
|
||||||
|
var client = new ActionsHttpInteractor(
|
||||||
|
this.serializersManager);
|
||||||
|
return Task.FromResult((IActionsInteractor)client);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// TODO specific error handling
|
||||||
|
throw new Exception(
|
||||||
|
string.Format(
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
ex.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
namespace Microsoft.Actions.Actors.Communication.Client
|
namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
{
|
{
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Actions.Actors.Runtime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A factory for creating <see cref="IActorCommunicationClient">actions communication clients.</see>.
|
/// A factory for creating <see cref="IActorCommunicationClient">actions communication clients.</see>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -17,11 +21,12 @@ namespace Microsoft.Actions.Actors.Communication.Client
|
||||||
IActorMessageBodyFactory GetRemotingMessageBodyFactory();
|
IActorMessageBodyFactory GetRemotingMessageBodyFactory();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets actor communication client.
|
/// Get a communication client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorId"> Actor Id.</param>
|
/// <returns>
|
||||||
/// <param name="actorType"> Actor Type.</param>
|
/// A <see cref="System.Threading.Tasks.Task">Task</see> that represents outstanding operation. The result of the Task is
|
||||||
/// <returns>A factory for creating the remoting message bodies.</returns>
|
/// the CommunicationClient(<see cref="IActorCommunicationClient" />) object.
|
||||||
ActorCommunicationClient GetClient(ActorId actorId, string actorType);
|
/// </returns>
|
||||||
|
Task<IActionsInteractor> GetClientAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue