хранить жетоны отмены в сервисах сервисной фабрики

Я пытаюсь реализовать функцию отмены задач в сервисах с отслеживанием состояния.

План использует токен отмены для распространения уведомлений на связанные потоки / задачи.

Проблема в том, что пока есть эти долго выполняющиеся задачи и потоки, ожидающие этого сигнала, я не уверен, как мне найти правильные токены отмены на основе других вызовов веб-API.

Я думал об использовании надежного словаря, но даже до того, как попробовать его, я предполагаю, что это приведет к потере, потому что cancellationToken не может быть сериализован / десериализован.

Пожалуйста, помогите мне найти хорошее решение этой проблемы.

Обновление (я не хотел создавать новую цепочку, теряющую некоторые важные контексты, упомянутые в этой ветке, поэтому обновляю в этом сообщении.)

Подтверждено, что в описании ссылки ниже показано, что методы надежной службы и субъекта могут поддерживать токен отмены. Однако типичный вариант использования - получение запроса на отмену напрямую через веб-API с запуском пользователя, например, обновление щелчка, переход на другую страницу и т. Д. В таком сценарии точно такая же конечная точка должна получить запрос, в то время как предыдущий HTTP-запрос задерживается с некоторыми долго выполняющаяся задача или зависла. Это не сценарий в этой теме.

По ссылке: https://blogs.msdn.microsoft.com/azureservicefabric/2016/02/23/service-fabric-sdk-v1-5-175-and-the-adoption-of-virtual-machine-scale-sets/

Поддержка CancellationToken для IService / IActor

Методы Reliable Service и Reliable Actor теперь поддерживают токен отмены, который может быть удален через ActorProxy и ServiceProxy, что позволяет реализовать совместную отмену. Клиенты, которые хотят отменить длительную службу или метод участника, могут сигнализировать токен отмены, и это намерение отмены будет передано методу субъекта / службы. Затем этот метод может определить, когда остановить выполнение, просмотрев состояние аргумента токена отмены.

Например, контракт актера, имеющий, возможно, долгосрочный метод, можно смоделировать, как показано ниже:

        public interface IPrimeNumberActorInterface : IActor
        {

            Task<ulong> FindNextPrimeNumberAsync
                (ulong previous, CancellationToken cancellationToken);

        }

Клиентский код, желающий отменить выполнение метода, может сообщить о своем намерении, отменив токен отмены.




Ответы (1)


CancellationToken & CancellationTokenSource не сериализуемы и не проходят через вызовы служб или репликацию данных в SF. Его можно использовать только для того, чтобы сообщить обработчику в том же процессе, что операция была отменена, и он должен останавливать любую обработку или игнорировать любое продолжение в случае получения ответа.

Если вы хотите иметь возможность запускать и отменять операцию в другой службе, вам следует разделить операцию на два вызова.

  • Первый сгенерирует идентификатор операции, который будет возвращен клиенту, и создаст CancellationTokenSource для этой операции, чтобы сгенерировать CancellationToken, который будет передан в Task \ Thread, работающий в фоновом режиме.
  • Второй получит OperationID и определит, существует ли CancellationTokenSource, и отменит его, чтобы токен, предоставленный любому Task \ Thread, мог остановить любую обработку, если она еще не завершена или не отменена.

Вы можете просто сохранить его как Dictionary<Guid, CancellationTokenSource> в разделе процесса \, на котором выполняется задача.

Если вы выполняете эти задачи в нескольких разделах в SF и планируете сохранить их в надежном словаре, это не очень хорошая идея, потому что, как было сказано ранее, вы не можете сериализовать отмену в другие разделы.

В этом случае вы можете сохранить OperationID и PartitionID, чтобы все разделы знали, где выполняется операция, когда вы получите запрос на отмену на любом из разделов, служба будет искать в этом надежном словаре, где выполняется операция, и вперед отмена на правый раздел.

person Diego Mendes    schedule 25.10.2018
comment
Я нашел статью с использованием ISerializationSurrogate. блоги .msdn.microsoft.com / schlepticons / 2008/08/24 / Пока не уверен, сработает ли это и обеспечит сериализацию настраиваемого сериализованного токена отмены ... если нет, то, вероятно, то, что вы предложили, будет вариантом .. - person swcraft; 26.10.2018
comment
К сожалению, десериализованный токен отмены, использующий указанную выше методологию ссылки, теряет все зарегистрированные обратные вызовы, вероятно, это даже не будет та же ссылка, что и переданная в другие потоки ... тем не менее, стоит проверить. - person swcraft; 26.10.2018
comment
В том, что вы написали В этом случае вы можете сохранить OperationID и PartitionID, вы имеете в виду надежный словарь? В моем случае токен отмены - это не тот, который сводится к встроенной предоставленной функции, такой как RunAsync (cancellationtoken), а тот, который я должен создать в порожденном потоке (новый токен отмены для убийства актера / задач). Интересно, как я могу достичь эти токены вызывать Cancel (). Также было бы большим подспорьем, если бы вы могли с небольшими подробностями объяснить, что вы имеете в виду, перенаправляя отмену в правый раздел. - person swcraft; 26.10.2018
comment
Только процесс (служебный раздел), выполняющий операцию, может отменить ее, в этом случае вы сохраните словарь с токеном отмены в том же процессе. Надежный словарь с идентификатором операции и идентификатором раздела может храниться где угодно, например, в API, потому что вам нужно будет отправить запрос отмены процессу (служебному разделу), выполняющему операцию. Клиент \ вызывающий отправит команду отмены в API, и API найдет, в каком разделе находится процесс, и отправит вызов службе, служба получит запрос отменить токен - person Diego Mendes; 26.10.2018
comment
Я искал информацию о том, как получить OperationID / PartitionID, было бы здорово, если бы вы могли подсказать мне такую ​​информацию .. Service Fabric особенно сложно изучить или понять из-за отсутствия информации / хорошего учебного материала. - person swcraft; 29.10.2018
comment
OperationId - это не то, что вы найдете, в предложенной выше идее OperationID - это идентификатор, сгенерированный вами для идентификации выполняющейся операции, int не создается Service Fabric, Service Fabric - это просто оркестратор вашей службы, и он очень мало влияет на упомянутый выше дизайн. Поскольку ваш исходный вопрос заключался в том, как исправить Решение, а не как решить проблему, трудно ответить чем-то, что полностью отличается от того, что вы спросили. Я бы порекомендовал вам задать еще один вопрос о том, как отменить удаленную операцию с помощью Service Fabric. - person Diego Mendes; 29.10.2018
comment
Спасибо, что продолжаете помогать в этой теме, вероятно, последним кусочком головоломки будет пересылка отмены в нужный раздел в вашем объяснении. Как переадресовать полученный запрос API в нужный раздел? Я предполагаю, что после того, как запрос был перенаправлен из веб-API в правый раздел, все это имеет смысл, потому что в этот момент вы должны просто иметь возможность вызвать cancellationtokensource.cancel (). - person swcraft; 29.10.2018
comment
Можете ли вы сделать это дополнительным вопросом, будет легче ответить, чем указать в этом поле - person Diego Mendes; 29.10.2018
comment
конечно, я создал новую ветку: stackoverflow.com/questions/53050219/ - person swcraft; 29.10.2018
comment
Хорошо, как только у меня появится свободное время, я попытаюсь ответить образцом кода. Я немного занят сегодня - person Diego Mendes; 30.10.2018