Детская площадка:
зерна A есть метод для отправки сообщения в OnNextAsync
потока ST в неявно подписанные зерна B .
В зерне B существует инициализация, которую необходимо выполнить в OnActivateAsync()
зерна B , а также подписка на поток ST и лямбда-функция для выполнения действия при получении сообщения.
настройка проекта в виде
<TargetFramework>netcoreapp2.2</TargetFramework>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" /> <PackageReference Include="Microsoft.Orleans.Clustering.AdoNet" Version="2.4.2" /> <PackageReference Include="Microsoft.Orleans.OrleansGoogleUtils" Version="2.4.2" /> <PackageReference Include="Microsoft.Orleans.Persistence.AdoNet" Version="2.4.2" /> <PackageReference Include="Microsoft.Orleans.Reminders.AdoNet" Version="2.4.2" /> <PackageReference Include="Microsoft.Orleans.Server" Version="2.4.2" /> <PackageReference Include="Microsoft.Orleans.Transactions" Version="2.4.2" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.5" /> <PackageReference Include="Orleans.Providers.MongoDB" Version="2.7.0" />
настройка компоновщика хоста
UseLocalhostClustering(siloPort, gatewayPort) .Configure<ClusterOptions>(options => { options.ClusterId = Guid.NewGuid().ToString(); options.ServiceId = Guid.NewGuid().ToString(); }) .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(PersonGrain).Assembly).WithReferences()) .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(ConnectionRegistrarGrain).Assembly).WithReferences()) .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(OpmGrain).Assembly).WithReferences()) .ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(DcGrain).Assembly).WithReferences()) .AddMemoryGrainStorageAsDefault() .AddMemoryGrainStorage("MainGrainStorage") .AddMemoryGrainStorage("PubSubStore") .AddSimpleMessageStreamProvider(AcoConstant.GlobalSmsStreamProvider, op=> { op.PubSubType = Orleans.Streams.StreamPubSubType.ExplicitGrainBasedAndImplicit; }) .AddMemoryStreams<DefaultMemoryMessageBodySerializer>(AcoConstant.RegisterDcStreamNameSpace) .AddMemoryStreams<DefaultMemoryMessageBodySerializer>(AcoConstant.RequestForDcRegistrationStreamNameSpace) .AddMemoryStreams<DefaultMemoryMessageBodySerializer>(AcoConstant.DiscardTheRequestForDcRegistrationStreamNameSpace) .ConfigureLogging(logging => { logging.AddConsole(); logging.SetMinimumLevel(LogLevel.Trace); }) .UseInMemoryReminderService();
Проблема:
Когда многократная активация зерна A отправляет сообщение в зерно B , это случай повторной активации в зерне B без ранее сохраненного состояния зерна B и, в конечном счете, в gran B существует только первое сохраненное состояние.первичный ключ и пространство имен потоков уже проверены в отправителе и получателе, AddSimpleMessageStreamProvider
и AddMemoryStreams
, используемые в сборщике хостов.после некоторого теста выяснилось, что изменение OnActivateAsync()
на отсутствие async task
случая несоответствия e-Tag в памяти.Хранимое исключение.есть ли пропущенная конфигурация или какая-то другая проблема, которую необходимо рассмотреть?
(на следующий день 22 сентября) какое-то новое обнаружение;после трассировки на исходном сервере Orleans.Storage.InconsistentStateException
появляются при WriteStateAsync()
методе StateStorageBridge<TState>
.
отладочный вывод при исключении, как показано ниже
Exception thrown: 'Orleans.Storage.Internal.MemoryStorageEtagMismatchException' in OrleansProviders.dll Exception thrown: 'Orleans.Storage.Internal.MemoryStorageEtagMismatchException' in System.Private.CoreLib.dll Exception thrown: 'Orleans.Storage.Internal.MemoryStorageEtagMismatchException' in System.Private.CoreLib.dll Exception thrown: 'Orleans.Storage.Internal.MemoryStorageEtagMismatchException' in System.Private.CoreLib.dll Exception thrown: 'Orleans.Storage.Internal.MemoryStorageEtagMismatchException' in System.Private.CoreLib.dll Exception thrown: 'Orleans.Storage.InconsistentStateException' in OrleansProviders.dll Exception thrown: 'Orleans.Storage.InconsistentStateException' in System.Private.CoreLib.dll
после того, как эта ошибка зерна деактивируется и повторно активируется для обработки далеесообщение из потока.другой процесс сохранения с вызовом к зерну работает нормально (также первое сообщение из потока).
зерна Метод
if (!State.DcCreationRequest.inProcess)
{
State.DcCreationRequest = (dc, DateTimeOffset.Now, memo, true);
var a = this.GetPrimaryKey();
await _dcRegistrationRequestStream.OnNextAsync(a) ;
await WriteStateAsync();
return await Task.FromResult(true);
}
return await Task.FromResult(false);
}
и действие в методе подписки на зерно B
{State.DcCreationRequests.Remove(value);
return Task.CompletedTask;
}
если это не мисс конфиг, то может быть регрессия как # 5086
спасибо