Сервис Wcf ждет ответа от NServiceBus, который никогда не придет - PullRequest
0 голосов
/ 14 сентября 2010

Представьте себе следующую настройку: клиент Silverlight туннелирует сериализованную команду по сети, используя службу WCF, которая, в свою очередь, десериализует команду и отправляет ее с помощью NServiceBus на общий хост, который отвечает за обработку команды. Служба WCF после отправки команды зарегистрировала обратный вызов для вызова. Общий хост проверяет команду и «возвращает» код ошибки (0 == успех или> 0 == сбой).

Примечание. Служба WCF моделируется после встроенной службы WCF. Разница в том, что эта служба WCF получает «универсальную команду» (не IMessage), десериализует ее в реальную команду (которая реализует IMessage) и, следовательно, отправляет десериализованную команду на шину.

При возникновении непредвиденных исключений команда попадает (после определенного количества повторных попыток) в очередь в очередь ошибок. На этом этапе инициирующий сервис WCF бездействует, не подозревая о том, что только что произошло. В более поздний момент клиент Silverlight будет использовать тайм-аут в соответствии с конфигурацией прокси-сервера клиента WCF.

Вещи, которые размыты в моей голове:

  1. NServiceBus обрабатывает этот сценарий каким-либо образом? Когда генерируется исключение тайм-аута (если вообще)? Или это что-то эксклюзивное для саг?
  2. Предполагая, что я использую [OperationContract (AsyncPattern = true)], есть ли какие-либо настройки тайм-аута, связанные с WCF, которые убьют операцию службы? Или метод EndXXX будет как-то вызываться? Или он будет сидеть вечно, протекая, ожидая чего-то, что никогда не придет?

Способы продолжить:

  1. повторно использовать существующие механизмы тайм-аута, при условии, что что-то не происходит.
  2. создать собственный механизм тайм-аута между службой wcf и nservicebus.
  3. уведомить службу wcf, как только команда попадет в очередь ошибок.
  4. создать свой собственный механизм асинхронных уведомлений, используя полнофункциональный обработчик сообщений обратного вызова на уровне службы WCF.

Вещи, которые я сделал:

  1. запустите пример, предоставленный NServiceBus.
  2. поднял счастливый случай.

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

Некоторые мотивы выбора моего текущего подхода

  • Я пытаюсь использовать некоторые из преимуществ масштабируемости (использование дистрибьютора на более позднем этапе) NServiceBus.
  • Я не хочу размещать gazillion сервисов WCF (по одному для каждой команды), поэтому я приготовил сервис WCF, похожий на шину.
  • Несмотря на то, что это стиль запроса / ответа, меня больше всего интересует изящная обработка ответа на команду, не поступающего.

1 Ответ

0 голосов
/ 15 сентября 2010

Вы можете разработать любой тип сообщения, какой пожелаете, IMessage - это просто маркерный интерфейс.Если вы проверяете файл WSDL, который предоставляет конечная точка mex службы, нет ссылки на IMessage, поэтому вы можете определить любую команду, которая вам нравится в вашей службе.В таком случае вы сможете использовать предоставленный хост WCF.

Я смог воспроизвести описанную вами проблему, используя встроенный вариант хостинга WCF.Когда генерируется исключение, вся транзакция откатывается, включая Bus.Return, и, следовательно, сервис никогда не получает ответ.

Я нашел способ взломать это, что я мог бы предоставить, но я рекомендую пересмотреть, как вы используете службу.Если вы действительно хотите выполнить некоторые дорогостоящие операции в отдельном процессе, я бы рекомендовал в вашей конечной точке WCF выполнить Bus.Send для другого процесса.Это обеспечит вашему клиенту, что команда была успешно получена и работа продолжается.Оттуда это будет до сервера, чтобы завершить команду (некоторая предварительная проверка поможет обеспечить ее успех).Если команда не была выполнена успешно, об этом следует сообщить на другом канале (некоторые фоновые опросы от клиента могут сделать это).

...