Правильный способ как зарегистрировать пользовательский IStateSerializer <T> - PullRequest
1 голос
/ 10 апреля 2019

Где именно должна происходить регистрация пользовательского IStateSerializer в течение срока службы StatefulService, чтобы быть эффективной?

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)\/\""
  }
}

Я думаю, что он пытается десериализовать DeviceState с помощью отката к DataContractSerializer и не зарегистрированDeviceStateSerializer.

  • Microsoft.ServiceFabric.Services 3.3.644
  • Microsoft.ServiceFabric.Services.Remoting 3.3.644
  • Microsoft.ServiceFabric.Data 3.3.644

1 Ответ

0 голосов
/ 10 апреля 2019

Государственный регистратор сериализатора должен быть в ctor, чем он работает.

public Automat(StatefulServiceContext context)
        : base(context)
{
    var ok = this.StateManager.TryAddStateSerializer(new DeviceStateSerializer());
    if (!ok)
    {
        Log.FailedToRegisterStateSerializer();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...