В настоящее время у нас есть система NServiceBus 5, которая содержит две повторяющиеся саги. Поскольку они действуют как диспетчер для периодического извлечения различных типов данных из внешней системы, мы используем тайм-ауты, чтобы вызвать это: мы создали универсальный и пустой класс с именем 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, они отправляются обеим Сагам! Хуже того, кажется, что данные с отслеживанием состояния в сагах перепутались, поскольку обе саги отправляют оба сообщения.
Поэтому кажется, что тайм-ауты отправляются всем экземплярам Saga, которые их запрашивают. Но глядя на пример https://docs.particular.net/samples/saga/simple/ нет особой логики в отношении нескольких экземпляров Saga и их состояния.
Верно ли мое предположение? Если это так, каковы наилучшие методы, чтобы несколько Sagas запрашивали и получали тайм-ауты?