正确的方法如何注册自定义IStateSerializer

问题描述 投票:1回答:1

确切地说,为了有效,应该在StatefulService的生命周期内注册自定义IStateSerializer吗?

internal sealed class Automat : StatefulService
{
    public Automat(StatefulServiceContext context)
        : base(context)
    { }

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        var ok = this.StateManager.TryAddStateSerializer(new DeviceStateSerializer());
        if (!ok)
        {
            Log.FailedToRegisterStateSerializer();
            throw new Exception("Failed to register state serializer.");
        }

        ...
    }
}

public sealed class DeviceStateSerializer : IStateSerializer<DeviceState>
{ ... }

部署后不久,健康事件分区处于仲裁丢失状态。报告(System.FM)并且更进一步说明有状态服务的辅助实例将发出警告:

{
  "Timestamp": "2019-04-10T13:08:10.2801059+02:00",
  "ProviderName": "Microsoft-ServiceFabric",
  "Id": 54429,
  "Message": "EventName: StatefulReplicaNewHealthReport Category: Health Partition=9396223e-01be-44fa-9b19-2438a5caec80 StatefulReplica=131993679124719148 InstanceId=131993679124719149 SourceId=System.RA Property=ReplicaOpenStatus HealthState=Warning TTL=922337203685477ms SequenceNumber=131993680683950343 Description='Replica had multiple failures during open on _Node_3. API call: IStatefulServiceReplica.Open(); Error = System.Runtime.Serialization.InvalidDataContractException (-2146233088)
    Type 'SmartGrid.Automat.Contracts.DeviceState' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.
       at Microsoft.ServiceFabric.Replicator.RecoveryManager.PerformRecoveryAsync(RecoveredOrCopiedCheckpointLsn recoveredOrCopiedCheckpointLsn, OperationProcessor recordsProcessor, CheckpointManager checkpointManager, TransactionManager transactionManager, LogRecordsDispatcher logRecordsDispatcher, ReplicatedLogManager replicatedLogManager)
       at Microsoft.ServiceFabric.Replicator.LoggingReplicator.PerformRecoveryAsync(RecoveryInformation recoveryInformation)
       at Microsoft.ServiceFabric.Replicator.DynamicStateManager.OpenAsync(ReplicaOpenMode openMode, TransactionalReplicatorSettings transactionalReplicatorSettings)
       at Microsoft.ServiceFabric.Replicator.TransactionalReplicator.OpenAsync(ReplicaOpenMode openMode, TransactionalReplicatorSettings transactionalReplicatorSettings)
       at Microsoft.ServiceFabric.Replicator.StatefulServiceReplica.System.Fabric.IStatefulServiceReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partitionObject, CancellationToken cancellationToken)
       at Microsoft.ServiceFabric.Data.ReliableStateManagerImpl.Microsoft.ServiceFabric.Data.IStateProviderReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partition, CancellationToken cancellationToken)
       at Microsoft.ServiceFabric.Services.Runtime.StatefulServiceReplicaAdapter.System.Fabric.IStatefulServiceReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partition, CancellationToken cancellationToken)
    For more information see: http://aka.ms/sfhealth' RemoveWhenExpired=False SourceUTCTimestamp=04/10/2019 13:07:48 ",
  "ProcessId": 19324,
  "Level": "Informational",
  "Keywords": "0x4000000000000001",
  "EventName": "HM",
  "ActivityID": null,
  "RelatedActivityID": null,
  "Payload": {
    "eventName": "StatefulReplicaNewHealthReport",
    "category": "Health",
    "eventInstanceId": "\"9bd354b7-0ab8-4a3d-99ce-48dbf3361432\"",
    "partitionId": "\"9396223e-01be-44fa-9b19-2438a5caec80\"",
    "replicaId": 131993679124719148,
    "replicaInstanceId": 131993679124719149,
    "sourceId": "System.RA",
    "property": "ReplicaOpenStatus",
    "healthState": 2,
    "TTLtimespan": 922337203685477,
    "sequenceNumber": 131993680683950343,
    "description": "Replica had multiple failures during open on _Node_3. API call: IStatefulServiceReplica.Open(); Error = System.Runtime.Serialization.InvalidDataContractException (-2146233088)
      Type 'SmartGrid.Automat.Contracts.DeviceState' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.
         at Microsoft.ServiceFabric.Replicator.RecoveryManager.PerformRecoveryAsync(RecoveredOrCopiedCheckpointLsn recoveredOrCopiedCheckpointLsn, OperationProcessor recordsProcessor, CheckpointManager checkpointManager, TransactionManager transactionManager, LogRecordsDispatcher logRecordsDispatcher, ReplicatedLogManager replicatedLogManager)
         at Microsoft.ServiceFabric.Replicator.LoggingReplicator.PerformRecoveryAsync(RecoveryInformation recoveryInformation)
         at Microsoft.ServiceFabric.Replicator.DynamicStateManager.OpenAsync(ReplicaOpenMode openMode, TransactionalReplicatorSettings transactionalReplicatorSettings)
         at Microsoft.ServiceFabric.Replicator.TransactionalReplicator.OpenAsync(ReplicaOpenMode openMode, TransactionalReplicatorSettings transactionalReplicatorSettings)
         at Microsoft.ServiceFabric.Replicator.StatefulServiceReplica.System.Fabric.IStatefulServiceReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partitionObject, CancellationToken cancellationToken)
         at Microsoft.ServiceFabric.Data.ReliableStateManagerImpl.Microsoft.ServiceFabric.Data.IStateProviderReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partition, CancellationToken cancellationToken)
         at Microsoft.ServiceFabric.Services.Runtime.StatefulServiceReplicaAdapter.System.Fabric.IStatefulServiceReplica.OpenAsync(ReplicaOpenMode openMode, IStatefulServicePartition partition, CancellationToken cancellationToken)
      For more information see: http://aka.ms/sfhealth",
    "removeWhenExpired": false,
    "sourceUtcTimestamp": "\"\/Date(1554894468395)\/\""
  }
}

我认为它试图通过使用回退到DataContractSerializer并且没有注册DeviceStateSerializer来反序列化DeviceState。

  • Microsoft.service fabric.services 3.3.644
  • Microsoft.ServiceFabric.Services.Remoting 3.3.644
  • Microsoft.service fabric.data 3.3.644
c# azure-service-fabric
1个回答
0
投票

状态序列化程序注册必须在ctor中,而不是它的工作原理。

public Automat(StatefulServiceContext context)
        : base(context)
{
    var ok = this.StateManager.TryAddStateSerializer(new DeviceStateSerializer());
    if (!ok)
    {
        Log.FailedToRegisterStateSerializer();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.