В настоящее время у нас есть система NServiceBus 5, которая содержит две повторяющиеся саги.Поскольку они действуют как диспетчер для периодического извлечения нескольких видов данных из внешней системы, мы используем Timeouts для запуска этого: мы создали универсальный и пустой класс с именем ExecuteTask, который используется Saga для обработки времени ожидания.
public class ScheduleSaga1 : Saga<SchedulerSagaData>,
IAmStartedByMessages<StartScheduleSaga1>,
IHandleMessages<StopSchedulingSaga>,
IHandleTimeouts<ExecuteTask>
И другая Сага почти идентично определена:
public class ScheduleSaga2: Saga<SchedulerSagaData>,
IAmStartedByMessages<StartScheduleSaga2>,
IHandleMessages<StopSchedulingSaga>,
IHandleTimeouts<ExecuteTask>
Тайм-аут обрабатывается одинаково в обеих Сагах:
public void Handle(StartScheduleSaga1 message)
{
if (_schedulingService.IsDisabled())
{
_logger.Info($"Task '{message.TaskName}' is disabled!");
}
else
{
Debugger.DoDebug($"Scheduling '{message.TaskName}' started!");
Data.TaskName = message.TaskName;
// Check to avoid that if the saga is already started, don't initiate any more tasks
// as those timeout messages will arrive when the specified time is up.
if (!Data.IsTaskAlreadyScheduled)
{
// Setup a timeout for the specified interval for the task to be executed.
Data.IsTaskAlreadyScheduled = true;
// Send the first Message Immediately!
SendMessage();
// Set the timeout
var timeout = _schedulingService.GetTimeout();
RequestTimeout<ExecuteTask>(timeout);
}
}
}
public void Timeout(ExecuteTask state)
{
if (_schedulingService.IsDisabled())
{
_logger.Info($"Task '{Data.TaskName}' is disabled!");
}
else
{
SendMessage();
// Action that gets executed when the specified time is up
var timeout = _schedulingService.GetTimeout();
Debugger.DoDebug($"Request timeout for Task '{Data.TaskName}' set to {timeout}!");
RequestTimeout<ExecuteTask>(timeout);
}
}
private void SendMessage()
{
// Send the Message to the bus so that the handler can handle it
Bus.Send(EndpointConfig.EndpointName, Activator.CreateInstance(typeof(PullData1Request)));
}
Теперь проблема: так как обе Сагизапрашивают тайм-ауты для ExecuteTask, он отправляется обеим Sagas!Еще хуже то, что кажется, что данные о состояниях в сагах испорчены, поскольку обе саги посылают оба сообщения.
Поэтому кажется, что тайм-ауты отправляются всем инстансам саги, которые запрашивают его.Но, глядя на пример https://docs.particular.net/samples/saga/simple/, нет особой логики в отношении нескольких экземпляров Saga и их состояния.
Верно ли мое предположение?Если это так, каковы наилучшие практики, когда несколько Sagas запрашивают и получают тайм-ауты?