Orleans - это структура модели акторов, которая используется для простого создания распределенных систем в кластере машин. В этом посте мы рассмотрим функцию «Напоминания» Орлеана.
Во-первых, документы:
Напоминания можно использовать в Орлеане для выполнения задач более или менее «по расписанию». Мне сложно придумать простой пример, который действительно имеет смысл, поэтому мы собираемся использовать сигнализацию «все в порядке»:
Чтобы установить сигнализацию «все в порядке», нам нужно сделать несколько вещей:
- Включите службу напоминаний в
ISiloHostBuilder
- мы будем использовать службу в памяти только для простоты, и чтобы не приходилось полагаться на дополнительную инфраструктуру. - Новое зерно напоминания
- Что-то, что нужно сделать для зерна напоминания.
Я подумал, что мы могли бы использовать FakeEmailSender
, представленные в:
чтобы отправлять «поддельные электронные письма», все в порядке.
Включите службу напоминаний
Начиная с https://github.com/Kritner-Blogs/OrleansGettingStarted/releases/tag/v0.40, мы включим службу напоминаний в памяти, добавив следующую строку в наш ISiloHostBuilder
.
.UseInMemoryReminderService()
Полный метод:
private static async Task<ISiloHost> StartSilo() { // define the cluster configuration var builder = new SiloHostBuilder() .UseLocalhostClustering() .Configure<ClusterOptions>(options => { options.ClusterId = "dev"; options.ServiceId = "HelloWorldApp"; }) .Configure<EndpointOptions>(options => options.AdvertisedIPAddress = IPAddress.Loopback) .AddMemoryGrainStorage(Constants.OrleansMemoryProvider) .ConfigureApplicationParts(parts => { parts.AddApplicationPart(typeof(IGrainMarker).Assembly).WithReferences(); }) .ConfigureServices(DependencyInjectionHelper.IocContainerRegistration) .UseDashboard(options => { }) .UseInMemoryReminderService() .ConfigureLogging(logging => logging.AddConsole()); var host = builder.Build(); await host.StartAsync(); return host; }
Некоторые другие возможные службы напоминания, которые можно использовать, включают AzureTableReminderService
и AdoNetReminderService
.
Напоминание зерна
Давайте создадим тревожное зерно, в котором все в порядке! В письменной форме я обнаружил, что существует минимум 1 минута времени между «напоминаниями», поэтому, к сожалению, мы не соберем первоначально запланированные 3 секунды :(
В любом случае ... наш интерфейс зерна:
public interface IEverythingIsOkGrain : IGrainWithStringKey, IRemindable { Task Start(); Task Stop(); }
В приведенном выше примере мы делаем довольно стандартный интерфейс зерна с дополнительным (будет) реализованным IRemindable
. К интерфейсу прикреплены два метода: один для запуска напоминания, другой для его остановки. Обратите внимание, что интерфейс IRemindable
требует, чтобы реализующий класс реализовал:
Task ReceiveReminder(string reminderName, TickStatus status);
Зерновая реализация - также Grainception!
Как я уже упоминал ранее, мы будем использовать FakeEmailSender
, созданный из предыдущего поста, а также использовать другие зерна в нашем создаваемом зерне (grainception)!
Это могло выглядеть так:
[StorageProvider(ProviderName = Constants.OrleansMemoryProvider)] public class EverythingIsOkGrain : Grain, IEverythingIsOkGrain { IGrainReminder _reminder = null; public async Task ReceiveReminder(string reminderName, TickStatus status) { // Grain-ception! var emailSenderGrain = GrainFactory .GetGrain<IEmailSenderGrain>(Guid.Empty); await emailSenderGrain.SendEmail( "[email protected]", new[] { "[email protected]", "[email protected]", "[email protected]", "[email protected]" }, "Everything's ok!", "This alarm will sound every 1 minute, as long as everything is ok!" ); } public async Task Start() { if (_reminder != null) { return; } _reminder = await RegisterOrUpdateReminder( this.GetPrimaryKeyString(), TimeSpan.FromSeconds(3), TimeSpan.FromMinutes(1) // apparently the minimum ); } public async Task Stop() { if (_reminder == null) { return; } await UnregisterReminder(_reminder); _reminder = null; } }
Несколько замечаний из вышеизложенного:
[StorageProvider(ProviderName = Constants.OrleansMemoryProvider)]
- мы делаем зернистость с учетом состояния, поэтому (теоретически) напоминание будет сохраняться при завершении работы. Обратите внимание, что в нашем случае этого не произойдет из-за использования памяти, я * думаю * иначе было бы.IGrainReminder _reminder = null;
- содержит ссылку на наше начатое напоминание, используемое для остановки напоминания.Task ReceiveReminder(string reminderName, TickStatus status)
- это метод, с помощью которого мы фактически определяем, что происходит при появлении напоминания.var emailSenderGrain = GrainFactory.GetGrain<IEmailSenderGrain>(Guid.Empty);
- здесь мы используем несколько другие способы получения зерна, поскольку на самом деле мы делаем это изSiloHost
, а не изClient
. Обратите внимание, что это вытягиваемое зерно также использует внедрение зависимостей, но его зависимость вводится только в зерно, которое действительно в нем нуждается, а не в это зерно напоминания.
Новая опция меню зерна
как обычно, мы собираемся создать новую IOrleansFunction
конкрецию для использования в нашей системе меню; это новое зерно также будет добавлено для возврата из нашего IOrleansFunctionProvider
.
public class EverythingIsOkReminder : IOrleansFunction { public string Description => "Demonstrates a reminder service, notifying the user that everything is ok... every three seconds..."; public async Task PerformFunction(IClusterClient clusterClient) { var grain = clusterClient.GetGrain<IEverythingIsOkGrain>( $"{nameof(IEverythingIsOkGrain)}-{Guid.NewGuid()}" ); Console.WriteLine("Starting everything's ok alerm after key press."); Console.ReadKey(); Console.WriteLine("Starting everything's ok reminder..."); await grain.Start(); Console.WriteLine("Reminder started. Press any key to stop reminder."); Console.ReadKey(); await grain.Stop(); ConsoleHelpers.ReturnToMenu(); } }
Пробовать это
Согласно нормам, мы будем запускать SiloHost
, Client
и пробовать новое зерно.
В приведенном выше примере вы можете видеть, что наше «FakeEmail» попало в журнал Orleans, заявив, что все в порядке.
Еще одна интересная вещь, которую мы можем увидеть, добавив в предыдущий пост Дашборд Орлеана:
Аккуратный!
В этом посте мы узнали немного об еще одной особенности Орлеана - напоминаниях! Вы можете найти код этого сообщения по адресу:
Связанный:
- Начало работы с Microsoft Orleans
- Microsoft Orleans - Повторное использование зерна и состояния зерна
- Microsoft Orleans - Панель мониторинга отчетности
- Использование полиморфизма для обновления Орлеанского проекта, чтобы быть готовым к новым Орлеанским примерам!
- Microsoft Orleans - Внедрение зависимостей
- Код от поста - v0.45
- Microsoft Orleans Docs - Напоминания и таймеры