Chris Fischer
Chris Fischer

Reputation: 163

c#/Service Fabric - How to Set Actor Operation Timeout at Runtime?

I've been struggling with this for a few days now and need some help. We have a Report service that consumes messages from Rabbit MQ based on a users choices to run a report. Some reports take longer than others of course, and we are using reliable actors to do the work for those report requests.

Our actors are creating a V2.1 Listener: enter image description here

Within our interface, we have set the Remoting Listener version and client version to be both V2.1, and set the operation timeout seconds to several hours:

enter image description here

There is nothing wrong (from my perspective) with this, and everything works fine this way when we invoker our actor using an actor proxy.

var actorService = ActorProxy.Create<IReportsWorker>(new ActorId(key));
successful = await actorService.CreateReport(reportEvent.CustomerId, reportEvent.ReportQueueId);

However we cannot change the operation timeout seconds field at runtime to be configurable from our database.

I started reading the following URL: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting

and came up with the following:

ServiceUriBuilder builder = new ServiceUriBuilder("Reports", "ReportsWorkerActorService");
            string actorURI = builder.ToUri().ToString();
            ServiceProxyDistributorCached _ServiceProxyDistributorCached = new ServiceProxyDistributorCached(_logger, builder.ToUri().ToString());
            ServicePartitionKey partition = _ServiceProxyDistributorCached.GetKey(System.Fabric.ServicePartitionKind.Int64Range, builder.ToUri().ToString());
            long key = (long)partition.Value;

            int Minutes = _appConfig.GetPlatformSetting("ReportOperationTimeOutMinutes") == string.Empty ? 60 : int.Parse(_appConfig.GetPlatformSetting("ReportOperationTimeOutMinutes"));

            FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings
            {
                OperationTimeout = TimeSpan.FromMinutes(Minutes),
                UseWrappedMessage = true
            };

            IServiceRemotingClientFactory clientFactory = new FabricTransportServiceRemotingClientFactory(transportSettings);

            ////ActorProxyFactory actorProxyFactory = new ActorProxyFactory((c) => new FabricTransportServiceRemotingClientFactory(transportSettings));
            ActorProxyFactory actorProxyFactory = new ActorProxyFactory((c) => clientFactory);

            var actorService = actorProxyFactory.CreateActorProxy<IReportsWorker>(new ActorId(key));

I'm getting the following Exception:

System.Runtime.Serialization.SerializationException: Type 'Microsoft.ServiceFabric.Actors.Remoting.V2.ActorRemotingMessageHeaders' with data contract name 'ActorHeader:urn:actors' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.

I'm don't know what I'm doing wrong here, as I don't see anything in the SDK that allows me to specify a V2.1 ActoryProxyFactory. I don't want to change the listener version.

Thoughts and Ideas are welcome!

Upvotes: 1

Views: 116

Answers (0)

Related Questions